CVE-2026-12243: NLTK: path traversal enables arbitrary file read

UNKNOWN PoC AVAILABLE CISA: TRACK*
Published June 30, 2026
CISO Take

NLTK 3.9.4 ships an incomplete fix for a known path traversal bug: its validation regex blocks literal "../" but not percent-encoded equivalents like "..%2f", which are only decoded after the check passes inside url2pathname(). Any application that lets a user or upstream service influence the resource name passed to nltk.data.load() or nltk.data.find() — NLP web backends, Jupyter notebooks, CLI tools — can be coerced into reading arbitrary files the Python process can access, including credentials, config files, and source code. There's no CVSS score or CISA KEV listing yet and EPSS sits low (0.51%, top 60th percentile), but a public PoC already exists on huntr, and the default pathsec.ENFORCE=False setting means most deployments have no secondary control blocking the file read at open(). Treat this as a low-noise but easy-to-weaponize bug: inventory where NLTK resource names are derived from user input, upgrade once a patched release is available, and in the interim set pathsec.ENFORCE=True and reject any resource identifier containing percent-encoded characters before it reaches nltk.data.load/find.

Sources: NVD EPSS huntr.com

What is the risk?

Low attack complexity and no authentication or user interaction required make this trivially exploitable wherever resource names reach NLTK's loader from untrusted input — a single crafted string is sufficient. The absence of a CVSS score and CISA KEV listing, plus a low EPSS score, suggest exploitation isn't yet widespread, but the combination of a public PoC and a broadly deployed, general-purpose NLP library (NLTK is embedded in many text-preprocessing steps of larger AI/NLP pipelines) means the realistic exposure is wider than the score implies. The core risk is arbitrary file disclosure, which is a stepping stone to credential theft, source code exposure, and further compromise rather than an end in itself — so actual severity in a given environment depends heavily on what secrets and files sit within reach of the Python process.

How does the attack unfold?

Entry Point
Attacker identifies an application or notebook that passes a user- or externally-controlled resource name into nltk.data.load() or nltk.data.find().
AML.T0049
Bypass Validation
Attacker crafts a resource identifier using percent-encoded traversal sequences (e.g. "..%2f") that slips past the _UNSAFE_NO_PROTOCOL_RE literal-"../" check.
Arbitrary File Read
url2pathname() decodes the payload after validation and, with pathsec.ENFORCE=False by default, the process opens and returns the contents of an out-of-scope file.
AML.T0037
Downstream Impact
Leaked secrets, credentials, or configuration data from the read file are used to escalate access or pivot further into the environment.
AML.T0106

What systems are affected?

Package Ecosystem Vulnerable Range Patched
nltk No patch

Do you use nltk? You're affected.

How severe is it?

CVSS 3.1
N/A
EPSS
0.6%
chance of exploitation in 30 days
Higher than 45% of all CVEs
Exploitation Status
Exploit Available
Exploitation: MEDIUM
Sophistication
Trivial
Exploitation Confidence
medium
CISA SSVC: Public PoC
Public PoC indexed (trickest/cve)
Composite signal derived from CISA KEV, VulnCheck KEV, CISA SSVC, EPSS, Metasploit, Exploit-DB, trickest/cve, Nuclei templates, and inthewild.io exploitation reports.

What should I do?

1 step
  1. Track the upstream fix for this incomplete patch (the referenced huntr report) and upgrade NLTK as soon as a corrected release ships — the current 3.9.4 fix for issue #3504 is insufficient. As an immediate compensating control, explicitly set pathsec.ENFORCE=True wherever NLTK is used, since the default False setting removes the last line of defense at the open() call. Never pass user- or externally-controlled strings directly into nltk.data.load() or nltk.data.find(); validate and allow-list expected resource identifiers before they reach these functions, and reject any input containing percent-encoding (%2f, %2e, etc.) prior to path resolution. For detection, monitor application logs and WAF rules for percent-encoded traversal sequences in parameters that map to NLTK resource names, and run the process with least-privilege filesystem access so a successful read has minimal value.

What does CISA's SSVC say?

Decision Track*
Exploitation poc
Automatable Yes
Technical Impact partial

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:

EU AI Act
Article 15 - Accuracy, robustness and cybersecurity
ISO 42001
A.6.2.6 - AI system security
NIST AI RMF
MEASURE 2.7 - AI system security and resilience are evaluated and documented
OWASP LLM Top 10
LLM03 - Supply Chain Vulnerabilities

Frequently Asked Questions

What is CVE-2026-12243?

NLTK 3.9.4 ships an incomplete fix for a known path traversal bug: its validation regex blocks literal "../" but not percent-encoded equivalents like "..%2f", which are only decoded after the check passes inside url2pathname(). Any application that lets a user or upstream service influence the resource name passed to nltk.data.load() or nltk.data.find() — NLP web backends, Jupyter notebooks, CLI tools — can be coerced into reading arbitrary files the Python process can access, including credentials, config files, and source code. There's no CVSS score or CISA KEV listing yet and EPSS sits low (0.51%, top 60th percentile), but a public PoC already exists on huntr, and the default pathsec.ENFORCE=False setting means most deployments have no secondary control blocking the file read at open(). Treat this as a low-noise but easy-to-weaponize bug: inventory where NLTK resource names are derived from user input, upgrade once a patched release is available, and in the interim set pathsec.ENFORCE=True and reject any resource identifier containing percent-encoded characters before it reaches nltk.data.load/find.

Is CVE-2026-12243 actively exploited?

Proof-of-concept exploit code is publicly available for CVE-2026-12243, increasing the risk of exploitation.

How to fix CVE-2026-12243?

Track the upstream fix for this incomplete patch (the referenced huntr report) and upgrade NLTK as soon as a corrected release ships — the current 3.9.4 fix for issue #3504 is insufficient. As an immediate compensating control, explicitly set pathsec.ENFORCE=True wherever NLTK is used, since the default False setting removes the last line of defense at the open() call. Never pass user- or externally-controlled strings directly into nltk.data.load() or nltk.data.find(); validate and allow-list expected resource identifiers before they reach these functions, and reject any input containing percent-encoding (%2f, %2e, etc.) prior to path resolution. For detection, monitor application logs and WAF rules for percent-encoded traversal sequences in parameters that map to NLTK resource names, and run the process with least-privilege filesystem access so a successful read has minimal value.

What systems are affected by CVE-2026-12243?

This vulnerability affects the following AI/ML architecture patterns: NLP pipelines, agent frameworks, model serving, RAG pipelines.

What is the CVSS score for CVE-2026-12243?

No CVSS score has been assigned yet.

What is the AI security impact?

Affected AI Architectures

NLP pipelinesagent frameworksmodel servingRAG pipelines

MITRE ATLAS Techniques

AML.T0037 Data from Local System
AML.T0049 Exploit Public-Facing Application
AML.T0106 Exploitation for Credential Access

Compliance Controls Affected

EU AI Act: Article 15
ISO 42001: A.6.2.6
NIST AI RMF: MEASURE 2.7
OWASP LLM Top 10: LLM03

What are the technical details?

Original Advisory

NLTK version 3.9.4 is vulnerable to a path traversal attack due to an incomplete fix for GitHub Issue #3504. The `_UNSAFE_NO_PROTOCOL_RE` regex in `nltk/data.py` checks for literal `../` sequences but fails to account for percent-encoded traversal sequences such as `..%2f`. The `url2pathname()` function decodes these sequences after the validation step, allowing an attacker to bypass the protection. This vulnerability enables an attacker to read arbitrary files accessible to the Python process by controlling the resource name parameter passed to `nltk.data.load()` or `nltk.data.find()`. The issue affects applications that rely on NLTK for resource loading, including NLP web applications, Jupyter notebooks, and CLI tools. The default `pathsec.ENFORCE=False` setting exacerbates the impact by not blocking the file read at the `open()` stage.

Exploitation Scenario

An NLP-powered web application exposes an endpoint that lets users select a corpus or tokenizer resource by name, passing that string through to nltk.data.load(). An attacker submits a resource identifier containing a percent-encoded traversal payload such as "..%2f..%2f..%2fapp%2f.env" instead of a legitimate resource name. The _UNSAFE_NO_PROTOCOL_RE regex inspects the raw string, sees no literal "../", and lets it through; url2pathname() then decodes the percent-encoding into a real traversal path, and — because pathsec.ENFORCE is False by default — the file is opened and its contents returned to the application, leaking environment variables, API keys, or other sensitive files to the attacker.

Weaknesses (CWE)

CWE-22 — Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'): The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.

  • [Implementation] Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does. When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue." Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylis
  • [Architecture and Design] For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.

Source: MITRE CWE corpus.

Timeline

Published
June 30, 2026
Last Modified
June 30, 2026
First Seen
June 30, 2026

Related Vulnerabilities