Skip to content
Fencer Intel
medium —

CVE-2026-12876 json

NLTK: Uncontrolled resource consumption in RecursiveDescentParser via ambiguous or left-recursive grammars

published 2mo ago modified last mo. also GHSA-ff5c-cp5c-9wjf , PYSEC-2026-3869

cvss
—
not scored
cisa kev
Not listed
not in CISA's catalog
epss
—
no EPSS score yet
public exploits
0
none known

Summary

`nltk.parse.RecursiveDescentParser` (and `SteppingRecursiveDescentParser`) enumerate parses top-down with no bound on the number of recursive steps. A small, crafted context-free grammar makes a short input consume unbounded CPU (and/or exhaust the Python recursion stack), pinning a process indefinitely — a denial of service.

## Proof of concept

Both of the following hang on a 24-token input (killed after 8s; growth is super-linear in input length), on NLTK develop:

```python from nltk import CFG from nltk.parse import RecursiveDescentParser

# (a) left recursion -> unbounded recursion g = CFG.fromstring("S -> S S | 'a'") list(RecursiveDescentParser(g).parse(["a"] * 24)) # hangs

# (b) ambiguous grammar -> exponential number of parses g = CFG.fromstring("S -> 'a' S | 'a' S S | 'a'") list(RecursiveDescentParser(g).parse(["a"] * 24)) # hangs ```

## Impact

An application that runs `RecursiveDescentParser` on a grammar (or an input) drawn from an untrusted source can be driven into an unbounded CPU / stack-exhaustion loop by a tiny payload. No confidentiality or integrity impact; single-process availability only.

## Sibling

The RegexpTokenizer ReDoS reported alongside this (CVE-2026-12875) is a different class (caller-supplied regex) and is addressed under GHSA-w3v8-gmh9-3wv7.

Patch / fix

Is CVE-2026-12876 in your dependencies? Fencer shows which of your repositories are affected as soon as an advisory lands, and opens the fix as a pull request.

Check with Fencer

Affected packages

ecosystem package affected fixed in
pypi nltk
<3.10.3
3.10.3

Classification

Weakness
  • CWE-407 Inefficient Algorithmic Complexity
  • CWE-674 Uncontrolled Recursion

References

Sources

Fencer Intel keeps one entry per vulnerability: the CVE id wins, then GHSA, and records that alias each other are merged, except that two CVEs always keep separate entries. The same data is available as JSON.