brew-acronym-cve-2026-66393
Vulnerability from osv_homebrew
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": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "nltk",
"resource_purl": "pkg:pypi/nltk@3.10.3",
"upstream_fixed_in": "3.9.4"
},
"package": {
"ecosystem": "Homebrew",
"name": "acronym",
"purl": "pkg:brew/acronym"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.0.0_3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/nltk@3.10.3",
"name": "nltk",
"resource": "nltk",
"strategy": "registry",
"subject_version": "3.10.3"
}
]
},
"details": "### Summary\n`JSONTaggedDecoder.decode_obj()` in `nltk/jsontags.py` calls itself \nrecursively without any depth limit. A deeply nested JSON structure \nexceeding `sys.getrecursionlimit()` (default: 1000) will raise an \nunhandled `RecursionError`, crashing the Python process.\n\n### Affected code\nFile: `nltk/jsontags.py`, lines 47\u201352\n```python\n@classmethod\ndef decode_obj(cls, obj):\n if isinstance(obj, dict):\n obj = {key: cls.decode_obj(val) for (key, val) in obj.items()}\n elif isinstance(obj, list):\n obj = list(cls.decode_obj(val) for val in obj)\n```\n\n### Proof of Concept\n```python\nimport sys, json\nfrom nltk.jsontags import JSONTaggedDecoder\n\ndepth = sys.getrecursionlimit() + 50 # e.g. 1050\npayload = \u0027{\"x\":\u0027 * depth + \"null\" + \"}\" * depth\n\n# Raises RecursionError, crashing the process\njson.loads(payload, cls=JSONTaggedDecoder)\n```\n\n### Impact\nAny code path that passes externally-supplied JSON to \n`JSONTaggedDecoder` is vulnerable to denial of service.\nThe severity depends on whether such a path exists in the \ncalling code (e.g. `nltk/data.py`).\n\n### Suggested Fix\nAdd a depth parameter with a hard limit:\n```python\n@classmethod\ndef decode_obj(cls, obj, _depth=0):\n if _depth \u003e 100:\n raise ValueError(\"JSON nesting too deep\")\n if isinstance(obj, dict):\n obj = {key: cls.decode_obj(val, _depth + 1) \n for (key, val) in obj.items()}\n elif isinstance(obj, list):\n obj = list(cls.decode_obj(val, _depth + 1) for val in obj)\n```",
"id": "BREW-acronym-CVE-2026-66393",
"modified": "2026-09-09T23:40:40Z",
"published": "2026-08-23T20:29:34Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/security/advisories/GHSA-rf74-v2fm-23pw"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-66393"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/commit/00cdcd392142e6c745e7120c8d50a24127df5fad"
},
{
"type": "PACKAGE",
"url": "https://github.com/nltk/nltk"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-3724.yaml"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/nltk-before-denial-of-service-via-jsontaggeddecoder"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "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",
"type": "CVSS_V4"
}
],
"summary": "Natural Language Toolkit (NLTK) has unbounded recursion in JSONTaggedDecoder.decode_obj() may cause DoS",
"upstream": [
"GHSA-rf74-v2fm-23pw",
"CVE-2026-66393",
"PYSEC-2026-3724"
]
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.