CVE-2026-12243 Overview
CVE-2026-12243 is a path traversal vulnerability in the Natural Language Toolkit (NLTK) version 3.9.4. The flaw exists in nltk/data.py, where the _UNSAFE_NO_PROTOCOL_RE regex screens resource names for literal ../ sequences. Attackers bypass this check using percent-encoded traversal payloads such as ..%2f, because url2pathname() decodes these sequences after validation. Applications passing untrusted input to nltk.data.load() or nltk.data.find() allow attackers to read arbitrary files accessible to the Python process. The default pathsec.ENFORCE=False configuration leaves the open() call unguarded, extending the impact to NLP web services, Jupyter notebooks, and command-line tools that ingest user-controlled resource identifiers.
Critical Impact
Remote attackers can read arbitrary files readable by the NLTK-hosting Python process without authentication or user interaction, exposing credentials, source code, and sensitive configuration data.
Affected Products
- NLTK (Natural Language Toolkit) version 3.9.4
- Applications embedding NLTK for corpus, model, or resource loading
- Downstream NLP web services, Jupyter notebooks, and CLI tools using nltk.data.load() or nltk.data.find()
Discovery Timeline
- 2026-06-30 - CVE-2026-12243 published to NVD
- 2026-06-30 - Last updated in NVD database
Technical Details for CVE-2026-12243
Vulnerability Analysis
The vulnerability originates from an incomplete fix for GitHub Issue #3504. NLTK's resource loader uses the _UNSAFE_NO_PROTOCOL_RE regex in nltk/data.py to reject strings containing literal ../ sequences. The regex operates on the raw, still-encoded input string. After passing the check, NLTK forwards the resource name to url2pathname(), which URL-decodes percent-encoded characters. A payload such as ..%2fetc%2fpasswd survives the regex because it contains no literal ../, then decodes into ../etc/passwd during path resolution. This ordering mismatch between validation and decoding produces the path traversal primitive classified as [CWE-22].
Root Cause
Input validation runs before canonicalization. The regex inspects the pre-decoded string, while url2pathname() performs percent-decoding downstream. Any encoding that resolves to ../ after decoding evades detection. The default configuration pathsec.ENFORCE=False disables a secondary safety check at the open() stage, allowing the traversal to reach the filesystem.
Attack Vector
Exploitation requires an application that passes attacker-controlled data to nltk.data.load() or nltk.data.find(). An attacker submits a resource identifier containing percent-encoded traversal sequences. NLTK validates the raw string, decodes it, and opens the resolved path. The process returns file contents to the caller or leaks them through error messages. Typical targets include SSH keys, environment files, application source, and cloud credential stores readable by the Python process.
The vulnerability manifests through interaction between the validation regex and the decoding function inside NLTK's data loader. Refer to the Huntr Bounty Report for the disclosed technical writeup.
Detection Methods for CVE-2026-12243
Indicators of Compromise
- Requests to NLP endpoints containing percent-encoded traversal patterns such as ..%2f, ..%2F, %2e%2e%2f, or %2e%2e/.
- Python process file access to paths outside the expected NLTK data directory (for example /etc/passwd, ~/.ssh/, /proc/self/environ).
- Application logs showing nltk.data.load() or nltk.data.find() calls with unusual resource names.
Detection Strategies
- Inspect HTTP request parameters and JSON bodies passed to NLP services for percent-encoded . and / sequences.
- Instrument NLTK call sites with logging that records the fully decoded resource path before file access.
- Deploy runtime file integrity monitoring on the Python process to flag reads outside the NLTK corpus directory.
Monitoring Recommendations
- Enable audit logging (auditd on Linux) for open() syscalls originating from Python interpreters hosting NLTK.
- Alert on repeated 4xx or 5xx responses from NLP endpoints correlated with encoded traversal payloads in access logs.
- Track outbound data volume from NLP services to detect bulk file exfiltration following successful traversal.
How to Mitigate CVE-2026-12243
Immediate Actions Required
- Upgrade NLTK to a fixed release once the maintainers publish a patched version beyond 3.9.4.
- Set pathsec.ENFORCE=True to enable the secondary check at the open() stage and block file reads outside the permitted data directory.
- Sanitize and canonicalize all user-supplied resource names before passing them to nltk.data.load() or nltk.data.find().
- Restrict the Python process file permissions using OS-level controls, dedicated service accounts, and filesystem sandboxing.
Patch Information
Monitor the Huntr Bounty Report and the NLTK project repository for a release that corrects the ordering between validation and decoding. Apply the fixed version across development, staging, and production environments and rebuild container images that bundle NLTK 3.9.4.
Workarounds
- Wrap NLTK calls with an allowlist that accepts only known resource identifiers matching a strict character set.
- Reject any input containing % before forwarding to NLTK if percent-encoding is not required by the application.
- Run NLTK-hosting services in a container or chroot with read access limited to the NLTK data directory only.
- Enable pathsec.ENFORCE=True and confirm that resource resolution honors the configured base directory.
# Configuration example: restrict NLTK to a dedicated data directory
export NLTK_DATA=/opt/nltk_data
python -c "import nltk.data; nltk.data.pathsec.ENFORCE = True"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

