CVE-2026-126303: CVE-2026-126303: Uncontrolled Resource Consumption in NLTK SteppingRecursiveDescentParser
CVE-2026-126303: Uncontrolled Resource Consumption in NLTK SteppingRecursiveDescentParser Vulnerability ID: CVE-2026-126303 CVSS Score: 8.7 Published: 2026-11-13 CVE-2026-126303 (GHSA-8fx7-8jr8-84rv) is an uncontrol
CVE-2026-126303: Uncontrolled Resource Consumption in NLTK SteppingRecursiveDescentParser
Vulnerability ID: CVE-2026-126303
CVSS Score: 8.7
Published: 2026-11-13
CVE-2026-126303 (GHSA-8fx7-8jr8-84rv) is an uncontrolled resource consumption vulnerability in the Natural Language Toolkit (NLTK) prior to version 3.10.4. The flaw is located in the SteppingRecursiveDescentParser.parse() method within the nltk.parse.recursivedescent module. Because the parser executes a top-down recursive descent stepping loop without enforcing an execution time deadline or step limit, processing tokens against a left-recursive, self-embedding, or ambiguous Context-Free Grammar (CFG) causes the parser to enter an infinite loop. This results in complete CPU core exhaustion and worker thread starvation, leading to an application-level denial of service.
TL;DR
Versions of NLTK prior to 3.10.4 contain an algorithmic denial-of-service flaw in SteppingRecursiveDescentParser.parse(). The class fails to inherit or check the base parser's max_time deadline during stepwise tree expansion. Evaluating inputs against left-recursive or cyclic grammars causes an unbounded execution loop that pins CPU cores at 100% utilization.
β οΈ Exploit Status: POC
Technical Details
- CVE / GHSA ID: CVE-2026-126303 / GHSA-8fx7-8jr8-84rv
- Vulnerability Class: CWE-400 (Uncontrolled Resource Consumption) / CWE-407 / CWE-674
- CVSS v4.0 Score: 8.7 High (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)
- EPSS Score: 0.49% (42.56th Percentile)
- Affected Component: nltk.parse.recursivedescent.SteppingRecursiveDescentParser.parse()
- Impact: Application Denial of Service via 100% CPU core starvation and worker lockup
- Patched Version: nltk 3.10.4
- CISA KEV Status: Not Listed
Affected Systems
- Natural Language Toolkit (nltk) Python package < 3.10.4
-
nltk: < 3.10.4 (Fixed in:
3.10.4)
Code Analysis
Commit: e20c40e
Bound algorithmic-DoS and uncontrolled-recursion vectors (CWE-400/407/674/1333)
diff --git a/nltk/parse/recursivedescent.py b/nltk/parse/recursivedescent.py
index 19eaaf6e19..08e9239bee 100644
--- a/nltk/parse/recursivedescent.py
+++ b/nltk/parse/recursivedescent.py
@@ -407,8 +407,8 @@ class SteppingRecursiveDescentParser(RecursiveDescentParser):
:see: ``nltk.grammar``
"""
- def __init__(self, grammar, trace=0):
- super().__init__(grammar, trace)
+ def __init__(self, grammar, trace=0, max_time=DEFAULT_MAX_TIME):
+ super().__init__(grammar, trace, max_time)
self._rtext = None
self._tree = None
self._frontier = [()]
@@ -428,8 +428,19 @@ def _freeze(self, tree):
def parse(self, tokens):
tokens = list(tokens)
self.initialize(tokens)
+ # step() bypasses the base _parse deadline, so bound the stepping loop
+ # directly: a left-recursive or ambiguous grammar loops unbounded
+ # otherwise (CWE-407/674). max_time=None disables the bound.
+ deadline = None
+ if self._max_time is not None:
+ deadline = time.perf_counter() + self._max_time
while self.step() is not None:
- pass
+ if deadline is not None and time.perf_counter() > deadline:
+ raise TimeoutError(
+ f"SteppingRecursiveDescentParser exceeded its {self._max_time}s "
+ "time limit; the grammar may be ambiguous or left-recursive. "
+ "Pass max_time=None to disable the limit."
+ )
return self.parses()
def initialize(self, tokens):
Commit: 5c41fc0
Follow-up release and test harness hardening commit for NLTK 3.10.4
Exploit Details
- GitHub Advisory: Official GitHub Security Advisory detailing the unbounded stepping loop in SteppingRecursiveDescentParser.parse().
- GitHub Pull Request: Pull Request #3895 containing regression tests and proof-of-concept inputs demonstrating algorithmic DoS in SteppingRecursiveDescentParser.
Mitigation Strategies
- Upgrade the NLTK library to version 3.10.4 or later to enforce default wall-clock deadlines on SteppingRecursiveDescentParser.parse().
- Replace SteppingRecursiveDescentParser and RecursiveDescentParser in production services with polynomial-time chart parsers such as nltk.parse.EarleyChartParser or nltk.parse.ChartParser.
- Restrict or validate user-supplied Context-Free Grammar (CFG) definitions to reject direct and indirect left-recursive production rules prior to parsing.
- Isolate CPU-intensive NLP parsing tasks inside dedicated worker processes configured with strict OS-level execution timeouts.
Remediation Steps:
- Update dependency manifests (requirements.txt, pyproject.toml, Pipfile) to require nltk>=3.10.4.
- Run 'pip install --upgrade "nltk>=3.10.4"' across all affected virtual environments and container images.
- Audit application code for calls to SteppingRecursiveDescentParser.parse() and ensure explicit max_time values are appropriate for the service's latency budget (do not pass max_time=None on untrusted inputs).
- Wrap parser.parse() invocations in try/except blocks that catch TimeoutError and RecursionError to prevent unhandled exceptions from terminating application workers.
References
- CVE-2026-126303 Official CVE Record
- NVD - CVE-2026-126303 Detail
- GitHub Security Advisory GHSA-8fx7-8jr8-84rv
- VulnCheck Advisory: NLTK before 3.10.4 Denial of Service via SteppingRecursiveDescentParser.parse
- NLTK Pull Request #3895: Bound algorithmic-DoS and uncontrolled-recursion vectors
- NLTK Patch Commit e20c40e26ec9306de885703f6e53250695f1f49b
- NLTK Release Validation Commit 5c41fc04a45e95577a83f3914acda211a994be00
- CVEProject cvelistV5 Record for CVE-2026-126303
Read the full report for CVE-2026-126303 on our website for more details including interactive diagrams and full exploit analysis.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.