NLTK, Regular Expression Denial of Service (ReDoS), CVE-2026-80206 (High) -DC-Sep2026-2252

Listen to this Post

NLTK versions prior to 3.10.3 contain a regular expression denial of service (ReDoS) vulnerability in the tgrep module. The `_tgrep_node_action` function compiles user-supplied regular expressions embedded in `/regex/` pattern nodes and executes them via `re.search` against tree node labels without any validation or timeout. An attacker who controls the tgrep pattern (e.g., via `tgrep_positions()` or `tgrep_compile()` exposed to external input) can supply a pattern that triggers catastrophic backtracking, causing indefinite CPU saturation that blocks the Python process.
The core technical issue resides in the `_tgrep_node_action` function in `nltk/tgrep.py` around line 320. When a tgrep pattern contains a `/regex/` node, this function compiles the embedded regex literal directly with no validation:

return (lambda r: lambda n, m=None, l=None: r.search(_tgrep_node_literal_value(n)))(re.compile(node_lit))

The compiled regex is applied against every matching tree node label via r.search(...). A caller reaching this path via `tgrep_positions()` or `tgrep_compile()` controls `node_lit` entirely.
The vulnerability stems from improper handling of user-supplied input during pattern matching operations. When the function receives a pattern string with specific structural characteristics known to cause catastrophic backtracking, it initiates an exponential time complexity execution path during the search operation. Because there are no input validation mechanisms or timeout controls in place, the Python interpreter becomes trapped in an infinite loop of state transitions within the regex engine, leading to complete CPU saturation and effectively blocking the application process indefinitely. This vulnerability is classified under CWE-1333 (Inefficient Regular Expression Complexity).
The attack mechanism relies on poorly constructed regular expressions that exploit ambiguities in backtracking algorithms used by standard regex engines like Python’s re module. An attacker who can inject or control the tgrep pattern can craft input strings designed to trigger worst-case scenarios for the matching algorithm, typically involving patterns with nested quantifiers or ambiguous alternations that force the engine to explore an exponential number of possible matches before determining failure. The lack of a timeout mechanism means there is no automated safeguard to abort the operation after a reasonable duration, allowing the attack to persist until manual intervention or system resource exhaustion occurs.
The operational impact is severe for any application relying on NLTK’s tgrep functionality with untrusted input. Since the Python process becomes blocked by CPU saturation, it cannot serve legitimate requests, leading to a denial of service condition. In web applications or API services that expose functions like `tgrep_positions()` or `tgrep_compile()` directly to external users without sanitization, this vulnerability can be exploited remotely. The attacker does not need elevated privileges; they only need the ability to submit malicious pattern strings.

DailyCVE Form:

Platform: NLTK (pip)
Version: <=3.10.2
Vulnerability: ReDoS
Severity: High (CVSS 8.2)
Date: 2026-08-26

Prediction: 2026-09-15

What Undercode Say:

Verify NLTK version
pip show nltk | grep Version
Check if vulnerable
python3 -c "import nltk; print(nltk.<strong>version</strong>)"
Test ReDoS vulnerability
python3 -c "
import nltk
from nltk.tgrep import tgrep_positions
import time
for n in [18, 20, 22, 24, 26, 28]:
tree = nltk.Tree.fromstring('(' + 'a' n + ' (NP (DT the)))')
start = time.perf_counter()
list(tgrep_positions(r'/((a+)+)b/', [bash]))
print(f'n={n}: {time.perf_counter() - start:.4f}s')
"
Monitor CPU saturation during attack
top -p $(pgrep -f "python.nltk") -b -n 1
Check for hanging processes
ps aux | grep python | grep -v grep

Exploit: (Educational Purposes!)

import nltk
from nltk.tgrep import tgrep_positions
Crafted payload triggering catastrophic backtracking
Pattern: nested quantifier ((a+)+)b with no matching 'b'
Tree root label: 'a' repeated n times (n ≥ 35 causes indefinite hang)
tree = nltk.Tree.fromstring("(" + "a" 35 + " (NP (DT the)))")
pattern = r"/((a+)+)b/"
This will never return for n ≥ 35
tgrep_positions(pattern, [bash]) Denial of Service

Protection:

import signal
import nltk
from nltk.tgrep import tgrep_positions
class TimeoutError(Exception):
pass
def timeout_handler(signum, frame):
raise TimeoutError("Regex execution timed out")
Apply timeout protection around tgrep operations
def safe_tgrep_positions(pattern, trees, timeout_seconds=5):
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(timeout_seconds)
try:
return list(tgrep_positions(pattern, trees))
except TimeoutError:
return []
finally:
signal.alarm(0)
Input validation: reject patterns with nested quantifiers
import re
DANGEROUS_PATTERNS = [r'(\w++)+', r'(\w+\)\', r'(\w++)\']
def validate_tgrep_pattern(pattern):
for dangerous in DANGEROUS_PATTERNS:
if re.search(dangerous, pattern):
raise ValueError("Potentially dangerous regex pattern rejected")
return pattern

Impact:

In environments like web APIs (Flask, FastAPI), Jupyter notebooks, or multi-tenant pipelines, an unauthenticated attacker can cause indefinite CPU saturation with a single crafted request, denying service to all other users of the process. The vulnerability affects all NLTK versions up to and including 3.10.2. Remediation requires upgrading to NLTK version 3.10.3 or higher, where this vulnerability has been addressed by implementing safeguards against catastrophic backtracking. For environments unable to update immediately, developers should implement strict input validation for any tgrep patterns received from external sources, including restricting allowed characters and structure of regex strings to exclude known problematic constructs such as nested quantifiers. Additionally, integrating a timeout mechanism around regex execution can prevent indefinite blocking by terminating operations that exceed a predefined time threshold.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top