Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐍 PyPI
Not in CISA KEV

CVE-2026-66393 — nltk

Fix: nltk/nltk@00cdcd3

CVE-2026-66393 is a CWE-674 vulnerability in nltk. A fix is available for nltk — see the affected versions and patch details below.

NLTK before 3.9.4 Denial of Service via JSONTaggedDecoder

Also known asGHSA-rf74-v2fm-23pwPYSEC-2026-3724
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 5, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-66393.

EPSS Exploitation Probability

via FIRST.org ↗
0.5%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs42th percentile — riskier than 42% of all scored CVEsHighest risk
0.00%0.34%0.68%1.02%0.4%0.5%0.5%Sep 26Oct 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

Real-World Exposure

1 pkg affected
🐍nltk

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

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 Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPInltkall versions3.9.4pip install --upgrade 'nltk==3.9.4'

Affected Products

1 product · 1 configurations
Application
nltknltk
< 3.9.4
range

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for nltk, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update nltk to 3.9.4 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-66393 is resolved across your whole dependency graph.

  3. Workarounds

    Cap what an attacker can consume: apply request size, rate and timeout limits in front of the affected component, and run it with memory and CPU limits so exhaustion degrades one worker rather than the whole service.

Fixing This On Your OS

If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.

Red HatImportant

A denial of service flaw exists in NLTK's JSONTaggedDecoder, allowing remote attackers to crash Python processes by submitting crafted, deeply nested JSON data. This vulnerability poses a significant risk to Red Hat products that process untrusted JSON input using affected NLTK versions, as it can lead to service…

Workaround published by Red Hat
To mitigate this vulnerability, implement input validation to restrict the maximum nesting depth of JSON structures processed by NLTK. Ensure that any services or applications utilizing NLTK's JSONTaggedDecoder do not process untrusted or excessively nested JSON input without prior sanitization. If NLTK is not required to process external JSON, restrict its exposure to such data.
Source: Red Hat security advisory for CVE-2026-66393 (CC BY 4.0)

Frequently Asked Questions

### 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 ```python @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 ```pyt
O3 Security · Impact-Aware SCA

Is CVE-2026-66393 in your dependencies?

Find it across PyPI, including transitive dependencies.

CVE-2026-66393: nltk DoS — Fixed in 3.9.4 | O3 Security