CVE-2026-12876: Pip/nltk vulnerability

Published Sep 2, 2026
·
Updated

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.

Affected Software

1 affected componentFixes available
pip/nltk<=3.10.2
3.10.3

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/nltk to a version that resolves this vulnerability.

    Fixed in 3.10.3

Event History

Sep 2, 2026
Advisory Published
via GitHub·02:33 PM
Data Sourced
via GitHub·02:33 PM
DescriptionWeaknessAffected Software

Frequently Asked Questions

1

Which applications are realistically exposed to this denial of service?

Applications are exposed when they run RecursiveDescentParser or SteppingRecursiveDescentParser using a context-free grammar or input obtained from an untrusted source. The impact is limited to availability of the affected process; the provided data does not indicate confidentiality or integrity impact.

2

What does an attacker need to trigger the issue?

An attacker needs to cause parsing of a crafted grammar or input. A small grammar and a short input can trigger unbounded CPU consumption or Python recursion-stack exhaustion; the examples use 24 tokens.

3

Are all NLTK parsing configurations affected by default?

The issue is specifically described for RecursiveDescentParser and SteppingRecursiveDescentParser. The data does not establish that other NLTK parsers or default application configurations are affected.

4

What can be done if updating is not immediately possible?

Do not parse untrusted grammars or inputs with the affected parsers. Where parsing untrusted data cannot be avoided, isolate the parsing process and enforce execution time and resource limits to prevent a single parse from indefinitely pinning the application process.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203