NLTK's package downloader fetches tokenizer models and corpora over HTTP but never verifies a SHA-256 checksum after the file lands on disk and before it's unzipped, so anything that can intercept the download or win a race on a shared filesystem can substitute its own payload. This matters because NLTK sits underneath 15,633 downstream packages, and tokenizer data such as punkt_tab is routinely pickled — meaning a swapped file isn't just corrupted data but a potential code-execution vector once it's loaded. There is no evidence of active exploitation (not in CISA KEV, no public PoC or Nuclei template) and the EPSS score of 0.001 reflects genuinely low real-world exploitation likelihood, since the attack requires either a MITM position, DNS poisoning, or local race-condition access (CVSS AC:H, UI:R). Upgrade to nltk 3.9.3, which the maintainers patched via GHSA-5wp5-5229-5g6q; until then, force HTTPS mirrors, avoid running `nltk.download()` on untrusted or shared multi-tenant hosts, and audit any environment where NLTK data was fetched over plain HTTP for unexpected pickle files in `nltk_data/`.
What is the risk?
Medium severity (CVSS 5.3, AC:H/UI:R) reflects a real but narrow exploitation window: the attacker needs network position (MITM/DNS poisoning) or local filesystem race-condition access, plus some form of user interaction (triggering a download). There's no known public exploit, no Nuclei template, and it isn't in CISA KEV, and EPSS (0.001) confirms it's not being opportunistically targeted in the wild today. The risk is elevated by scale (15,633 dependents) and by the specific nature of what's downloaded — pickled tokenizer/model artifacts that are trusted and loaded without further validation downstream. This is a supply-chain integrity gap rather than an actively weaponized vulnerability; prioritize patching over emergency response.
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| Tokenizers | pip | <= 3.9.2 | 3.9.3 |
Do you use Tokenizers? You're affected.
How severe is it?
What is the attack surface?
What should I do?
1 step-
1) Upgrade to nltk >= 3.9.3, which is expected to add post-download checksum verification per the linked advisory and PR #3449. 2) Until patched, force NLTK to use HTTPS-only mirrors and avoid networks where MITM is plausible (public Wi-Fi, untrusted proxies). 3) In CI/CD and shared environments, pre-bake
nltk_datainto a trusted base image or artifact rather than downloading at build/runtime, eliminating the download-time attack window entirely. 4) On shared filesystems, restrict write permissions on the NLTK data directory to prevent the race-condition variant. 5) Detection: auditnltk_data/directories for files with hashes that don't match the official NLTK package index, and monitor for unexpected outbound HTTP (not HTTPS) requests to nltk.org/nltk_data mirrors from build and inference hosts.
What does CISA's SSVC say?
Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is CVE-2026-12259?
NLTK's package downloader fetches tokenizer models and corpora over HTTP but never verifies a SHA-256 checksum after the file lands on disk and before it's unzipped, so anything that can intercept the download or win a race on a shared filesystem can substitute its own payload. This matters because NLTK sits underneath 15,633 downstream packages, and tokenizer data such as punkt_tab is routinely pickled — meaning a swapped file isn't just corrupted data but a potential code-execution vector once it's loaded. There is no evidence of active exploitation (not in CISA KEV, no public PoC or Nuclei template) and the EPSS score of 0.001 reflects genuinely low real-world exploitation likelihood, since the attack requires either a MITM position, DNS poisoning, or local race-condition access (CVSS AC:H, UI:R). Upgrade to nltk 3.9.3, which the maintainers patched via GHSA-5wp5-5229-5g6q; until then, force HTTPS mirrors, avoid running `nltk.download()` on untrusted or shared multi-tenant hosts, and audit any environment where NLTK data was fetched over plain HTTP for unexpected pickle files in `nltk_data/`.
Is CVE-2026-12259 actively exploited?
No confirmed active exploitation of CVE-2026-12259 has been reported, but organizations should still patch proactively.
How to fix CVE-2026-12259?
1) Upgrade to nltk >= 3.9.3, which is expected to add post-download checksum verification per the linked advisory and PR #3449. 2) Until patched, force NLTK to use HTTPS-only mirrors and avoid networks where MITM is plausible (public Wi-Fi, untrusted proxies). 3) In CI/CD and shared environments, pre-bake `nltk_data` into a trusted base image or artifact rather than downloading at build/runtime, eliminating the download-time attack window entirely. 4) On shared filesystems, restrict write permissions on the NLTK data directory to prevent the race-condition variant. 5) Detection: audit `nltk_data/` directories for files with hashes that don't match the official NLTK package index, and monitor for unexpected outbound HTTP (not HTTPS) requests to nltk.org/nltk_data mirrors from build and inference hosts.
What systems are affected by CVE-2026-12259?
This vulnerability affects the following AI/ML architecture patterns: RAG pipelines, training pipelines, NLP preprocessing pipelines, CI/CD build pipelines.
What is the CVSS score for CVE-2026-12259?
CVE-2026-12259 has a CVSS v3.1 base score of 5.3 (MEDIUM). The EPSS exploitation probability is 0.10%.
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0010 AI Supply Chain Compromise AML.T0010.001 AI Software AML.T0011.001 Malicious Package AML.T0018.002 Embed Malware Compliance Controls Affected
What are the technical details?
Original Advisory
NLTK's package downloader in nltk/downloader.py does not verify file integrity after download and before extraction. The download flow at lines 789-825: 1. File is downloaded to a temp path via HTTP 2. os.replace(tmp_filepath, filepath) moves it to the final location (line 799) 3. Extraction begins via _unzip_iter() (line 825) Between steps 2 and 3, there is no SHA-256 verification. The checksum logic exists in _pkg_status() (lines 982-1015) but it is only used BEFORE download as a status check ("is this package already installed and up-to-date?"). It is never called after download to verify the file that was actually received. Attack vectors: 1. MITM during HTTP download (NLTK downloads from http:// by default on some mirrors) 2. Race condition on shared filesystems (attacker replaces file between os.replace and _unzip_iter) 3. DNS poisoning redirecting to attacker-controlled server PoC: ```python import nltk import unittest.mock import zipfile import io import os # Create a malicious zip that will be "downloaded" malicious_zip = io.BytesIO() with zipfile.ZipFile(malicious_zip, 'w') as zf: zf.writestr('punkt_tab/tokenizers/punkt_tab/english.pickle', b'MALICIOUS PAYLOAD - attacker controlled content') # Patch urllib to return our malicious zip with unittest.mock.patch('urllib.request.urlopen') as mock_urlopen: mock_response = unittest.mock.MagicMock() mock_response.read.return_value = malicious_zip.getvalue() mock_response.headers = {'Content-Length': str(len(malicious_zip.getvalue()))} mock_urlopen.return_value = mock_response # Download proceeds, no integrity check catches the swap # nltk.download('punkt_tab') # Would install attacker payload ``` This is distinct from CVE-2024-39705 (pickle deserialization via download) and CVE-2025-14009 (zip-slip path traversal). Those address what happens AFTER extraction. This finding addresses the gap BEFORE extraction where integrity is never verified. Suggested fix: After os.replace() and before _unzip_iter(), compute SHA-256 of the final file and compare against the expected checksum from the package index. Reject and delete the file if the hash does not match.
Exploitation Scenario
An adversary positioned on a shared network (coffee shop Wi-Fi, compromised router, or a rogue AP near a corporate office) waits for a data scientist or CI job to run `nltk.download('punkt_tab')`. Because some NLTK mirrors serve over plain HTTP, the attacker intercepts the request via ARP spoofing or DNS poisoning and returns a crafted zip containing a malicious `english.pickle` in place of the legitimate tokenizer model. NLTK moves the file into place and extracts it without ever checking its hash against the expected value, so the swap is invisible to the victim. The next time the RAG or NLP pipeline loads that tokenizer, the pickle deserializes and the attacker's embedded payload executes with the privileges of the pipeline process — turning a routine dependency fetch into remote code execution deep inside the victim's data pipeline.
Weaknesses (CWE)
CWE-494 — Download of Code Without Integrity Check: The product downloads source code or an executable from a remote location and executes the code without sufficiently verifying the origin and integrity of the code.
- [Implementation] Perform proper forward and reverse DNS lookups to detect DNS spoofing.
- [Architecture and Design, Operation] Encrypt the code with a reliable encryption scheme before transmitting. This will only be a partial solution, since it will not detect DNS spoofing and it will not prevent your code from being modified on the hosting site.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N References
- github.com/advisories/GHSA-5wp5-5229-5g6q
- github.com/nltk/nltk/commit/0e26734a61094b628d93e26dc18dd7302567ac46
- github.com/nltk/nltk/pull/3449
- github.com/nltk/nltk/releases/tag/3.9.3
- github.com/nltk/nltk/security/advisories/GHSA-5wp5-5229-5g6q
- github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-3729.yaml
- huntr.com/bounties/659ccf6d-12d4-4d4a-84c0-078633c35a5d
- nvd.nist.gov/vuln/detail/CVE-2026-12259
- vulncheck.com/advisories/nltk-before-missing-post-download-integrity-verification
Timeline
Related Vulnerabilities
CVE-2026-41680 7.5 marked: infinite recursion DoS crashes Node.js via OOM
Same package: tokenizers CVE-2026-85670 6.5 tokenizers: malformed vocab crashes process (DoS)
Same package: tokenizers GHSA-j95f-988m-3j2f tiptap: ReDoS in Markdown attribute parsers
Same package: tokenizers CVE-2024-2912 10.0 BentoML: RCE via insecure deserialization (CVSS 10)
Same attack type: Supply Chain CVE-2025-5120 10.0 smolagents: sandbox escape enables unauthenticated RCE
Same attack type: Supply Chain