GitHub Advisoryadvisory · PyPI

GHSA-p4gq-832x-fm9v Natural Language Toolkit (NLTK): URL-Encoded Path Traversal in nltk.data.load() Allows Arbitrary Local File Read

HIGH Published 2026-06-16 Modified 2026-07-21 Official page ↗
Aliases
CVE-2026-54293
Ecosystem
PyPI
Packages
nltk
Severity
High
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Weaknesses
CWE-22
Reviewed
2026-06-16

Affected packages

• PyPI nltk: < 3.10.0 → fixed in 3.10.0

Description

Summary nltk.data.load() in NLTK is vulnerable to path traversal via URL-encoded path separators and traversal segments when using the nltk: URL scheme. The unsafe-path regex check is performed before url2pathname() decodes the %xx sequences (a classic decode-after-check / TOCTOU-style flaw), allowing an attacker to bypass the protection documented in NLTK's SECURITY.md and read arbitrary files from the filesystem. While literal traversal strings such as ../../../etc/passwd are correctly blocked, encoded variants such as %2fetc%2fpasswd, %2e%2e%2f..., and ..%2f..%2f slip past the regex and are subsequently decoded into a real filesystem path. Affected Component nltk/data.py — find(), normalize_resource_url(), and the _UNSAFE_NO_PROTOCOL_RE regex check. Relevant occurrences: data.py L650–L653 — final path constructed from url2pathname(resource_name) after checks data.py L54–L69 — _UNSAFE_NO_PROTOCOL_RE operates only on the undecoded string data.py L219–L245 — normalize_resource_url() for nltk: scheme contributes to decode-after-check data.py L615–L618 — defense-in-depth traversal check also operates on undecoded input Root Cause The regex _UNSAFE_NO_PROTOCOL_RE is matched against the raw resource string. Path normalization via url2pathname() happens later, so any percent-encoded / (%2f) or . (%2e) is invisible to the regex but becomes active in the final path. Proof of Concept ``` """ NLTK Arbitrary File Read via URL-Encoded Path Traversal ======================================================= Bypasses _UNSAFE_NO_PROTOCOL_RE security regex in nltk/data.py by URL-encoding path separators and traversal components. Affected: NLTK 0: print(" Status: VULNERABLE (url2pathname decodes after regex check)") else: print(" Status: Not vulnerable") print("=" * 51) if __name__ == "__main__": main() ``` Impact Arbitrary local file read whenever attacker-controlled input reaches nltk.data.load(). Realistic targets include: /etc/passwd, /etc/shadow (if readable) /proc/self/environ — leaks environment variables, often containing API keys, DB credentials, cloud secrets Application source code and configuration files Cloud metadata, deployment secrets, SSH keys This is directly relevant to web applications, hosted notebook services, multi-tenant ML pipelines, and CI/CD systems that pass untrusted resource identifiers into NLTK. NLTK's SECURITY.md explicitly places path traversal within the scope of its protection model, so this is a documented security boundary being broken. fix https://github.com/nltk/nltk/pull/3575

Related

Alias · CVE (1)

  • CVE-2026-54293 NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in… vulnerability

Weakness · CWE (1)

  • CWE-22 Improper Limitation of a Pathname to a Restricted Directory weakness

References