Track vulnerabilities like this one.
Sign up free to get alerted when software you use is affected.
8.7
CVE-2026-62388: NLTK 3.9 disables security checks by default
CVE-2026-62388 · published 2 months ago
Summary
The NLTK library’s security module is set to only warn, not block, when risky actions like reading system files, accessing internal network URLs, or loading untrusted data are attempted. Because the protection is off by default, the fixes for known risks are not actually enforced unless you manually turn on the ENFORCE setting. Set the environment variable NLTK_PATHSEC_ENFORCE to 1 or upgrade to a version where enforcement is enabled to restore the intended safeguards.
What to do
- Update debian nltk to version 3.10.0-1.
- Update nltk team nltk to version 3.10.0.
- Update nltk to version 3.10.0.
- Update nltk nltk to version 3.10.0 or later.
Affected software
| Ecosystem | Vendor | Product | Affected versions |
|---|---|---|---|
| Debian:14 | debian | nltk |
< 3.10.0-1 Fix: upgrade to 3.10.0-1
|
| – | nltk | nltk | < 3.10.0 |
| Debian:11 | debian | nltk | All versions |
| Debian:12 | debian | nltk | All versions |
| Debian:13 | debian | nltk | All versions |
| Ubuntu:Pro:14.04:LTS | canonical | nltk | All versions |
| Ubuntu:Pro:16.04:LTS | canonical | nltk | All versions |
| Ubuntu:Pro:18.04:LTS | canonical | nltk | All versions |
| Ubuntu:Pro:20.04:LTS | canonical | nltk | All versions |
| Ubuntu:Pro:22.04:LTS | canonical | nltk | All versions |
| Ubuntu:Pro:24.04:LTS | canonical | nltk | All versions |
| Ubuntu:Pro:26.04:LTS | canonical | nltk | All versions |
| PyPI | nltk team | nltk |
< 3.10.0 Fix: upgrade to 3.10.0
|
| pip | nltk team | nltk |
<= 3.9.4 Fix: upgrade to 3.10.0
|
| pip | – | nltk |
<= 3.9.4 Fix: upgrade to 3.10.0
|
Original advisory text
NLTK: Default ENFORCE=False Disables All pathsec Security Controls
NLTK's pathsec.py security module defaults to ENFORCE=False (line 24), which means all 8 security validation functions only emit RuntimeWarning instead of raising exceptions when violations are detected.
The pathsec module was introduced as the fix for CVE-2024-39705 (arbitrary code execution via pickle) and CVE-2026-0846 (path traversal). However, with ENFORCE=False as the default:
1. pathsec.open('/etc/passwd') succeeds (reads the file, emits warning)
2. pathsec.validate_network_url('http://169.254.169.254/...') succeeds (warning only)
3. pickle.loads() via nltk.data.load() proceeds despite unsafe source (warning only)
Every security gate follows the same pattern:
```python
ENFORCE = os.environ.get('NLTK_PATHSEC_ENFORCE', '').lower() in ('1', 'true', 'yes')
def validate_something(path):
if is_violation(path):
if ENFORCE:
raise SecurityError('...') # Only raised when env var is set
else:
warnings.warn('...', RuntimeWarning) # Default: warning only
# Execution continues regardless
```
This means the security remediations for CVE-2024-39705 and CVE-2026-0846 are effectively disabled by default. Any user who installed NLTK 3.9.x expecting the security fixes to be active is still vulnerable unless they manually set NLTK_PATHSEC_ENFORCE=1.
PoC:
```python
import nltk.pathsec
import warnings
# Show that ENFORCE is False by default
print(f'ENFORCE = {nltk.pathsec.ENFORCE}') # False
# Attempt to read /etc/passwd through pathsec -- should be blocked
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
result = nltk.pathsec.open('/etc/passwd', 'r')
print(f'File opened: {result.name}') # /etc/passwd
print(f'Warning emitted: {w[0].message}') # RuntimeWarning (not an exception)
# Attack succeeds -- file is readable
```
The correct default is fail-secure: ENFORCE should be True unless explicitly disabled. The current default makes the security module opt-in rather than opt-out, defeating its purpose.
Suggested fix: Change default to ENFORCE=True. Users who need backwards compatibility can set NLTK_PATHSEC_ENFORCE=0 to explicitly disable.
The pathsec module was introduced as the fix for CVE-2024-39705 (arbitrary code execution via pickle) and CVE-2026-0846 (path traversal). However, with ENFORCE=False as the default:
1. pathsec.open('/etc/passwd') succeeds (reads the file, emits warning)
2. pathsec.validate_network_url('http://169.254.169.254/...') succeeds (warning only)
3. pickle.loads() via nltk.data.load() proceeds despite unsafe source (warning only)
Every security gate follows the same pattern:
```python
ENFORCE = os.environ.get('NLTK_PATHSEC_ENFORCE', '').lower() in ('1', 'true', 'yes')
def validate_something(path):
if is_violation(path):
if ENFORCE:
raise SecurityError('...') # Only raised when env var is set
else:
warnings.warn('...', RuntimeWarning) # Default: warning only
# Execution continues regardless
```
This means the security remediations for CVE-2024-39705 and CVE-2026-0846 are effectively disabled by default. Any user who installed NLTK 3.9.x expecting the security fixes to be active is still vulnerable unless they manually set NLTK_PATHSEC_ENFORCE=1.
PoC:
```python
import nltk.pathsec
import warnings
# Show that ENFORCE is False by default
print(f'ENFORCE = {nltk.pathsec.ENFORCE}') # False
# Attempt to read /etc/passwd through pathsec -- should be blocked
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
result = nltk.pathsec.open('/etc/passwd', 'r')
print(f'File opened: {result.name}') # /etc/passwd
print(f'Warning emitted: {w[0].message}') # RuntimeWarning (not an exception)
# Attack succeeds -- file is readable
```
The correct default is fail-secure: ENFORCE should be True unless explicitly disabled. The current default makes the security module opt-in rather than opt-out, defeating its purpose.
Suggested fix: Change default to ENFORCE=True. Users who need backwards compatibility can set NLTK_PATHSEC_ENFORCE=0 to explicitly disable.
References
- https://www.vulncheck.com/advisories/nltk-before-insecure-default-configuration-...
- https://security-tracker.debian.org/tracker/CVE-2026-62388 Vendor Advisory
- https://github.com/nltk/nltk/security/advisories/ghsa-p3m8-78j2-g5p3 Third Party Advisory
- https://ubuntu.com/security/CVE-2026-62388 Third Party Advisory
- https://www.cve.org/CVERecord?id=CVE-2026-62388 Third Party Advisory
- https://security-tracker.debian.org/tracker/cve-2026-62388 Third Party Advisory
- https://github.com/cveproject/cvelistv5/tree/main/cves/2026/62xxx/cve-2026-62388... Third Party Advisory
- https://nvd.nist.gov/vuln/detail/cve-2026-62388 Third Party Advisory
- https://nvd.nist.gov/vuln/detail/CVE-2026-62388
- https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/62xxx/CVE-2026-62388... Vendor Advisory
- https://github.com/nltk/nltk/pull/3593
- https://github.com/nltk/nltk/commit/155e40343cff0bf50d233e274a12e04d1428b1d9
- https://github.com/nltk/nltk Product
- https://github.com/nltk/nltk/releases/tag/v3.10.0
- https://github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-3722.y...
- https://github.com/advisories/GHSA-p3m8-78j2-g5p3
- https://github.com/nltk/nltk/security/advisories/GHSA-p3m8-78j2-g5p3
Internet-facing
14 days
Internal
60 days
- Not known to be exploited
- Can be exploited automatically
- Gives an attacker partial control
Severity
8.7
High
Type
CWE-1188Initialization of a Resource with an Insecure Default
Timeline
Published2 Sep 2026
Updated4 Nov 2026
First seen22 Aug 2026
Sources
DEBIAN-CVE-2026-62388 · OSV
CVE-2026-62388 · OSV
GHSA-p3m8-78j2-g5p3 · GHSA
UBUNTU-CVE-2026-62388 · OSV
CVE-2026-62388 · NVD
CVE-2026-62388 · MITRE
PYSEC-2026-3722 · OSV
GHSA-p3m8-78j2-g5p3 · OSV
Track software like this
Free during beta