CVE-2026-62388: NLTK before 3.10.0 Insecure Default Configuration in pathsec.py
NLTK versions before 3.10.0 default to ENFORCE=False in pathsec.py, causing all security validation functions to emit warnings instead of raising exceptions. Attackers can bypass path traversal and pickle deserialization protections by exploiting the disabled security controls that are only active when manually enabled.
Other sources
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.validatenetworkurl('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('NLTKPATHSECENFORCE', '').lower() in ('1', 'true', 'yes')
def validatesomething(path): if isviolation(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 NLTKPATHSECENFORCE=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.catchwarnings(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 NLTKPATHSECENFORCE=0 to explicitly disable.
— GitHub
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/nltkto a version that resolves this vulnerability.Fixed in 3.10.0 - Configuration
Change pathsec.py default behavior to fail-secure: make ENFORCE default to True (i.e., security validation functions raise exceptions on violations by default). Current behavior is ENFORCE=False unless NLTK_PATHSEC_ENFORCE is set to '1'/'true'/'yes'.
NLTK pathsec.py (nltk.pathsec) NLTK_PATHSEC_ENFORCE / ENFORCE default = True - Configuration
If you must keep backwards compatibility, explicitly disable protections only by setting NLTK_PATHSEC_ENFORCE=0; otherwise do not rely on the insecure default.
NLTK pathsec.py (nltk.pathsec) NLTK_PATHSEC_ENFORCE = 0
Event History
Frequently Asked Questions
Which deployments are exposed by default?
NLTK versions before 3.10.0 are exposed when using the default pathsec.py configuration, because ENFORCE defaults to False. In that state, security validation functions warn instead of raising exceptions.
What does an attacker need to exploit this issue?
An attacker needs an opportunity to trigger code paths that rely on NLTK's path traversal or pickle deserialization protections. No authentication or user interaction is required according to the supplied severity vector.
Is there a mitigation if upgrading is not immediately possible?
Manually enable the pathsec security controls by setting ENFORCE to True. This changes validation failures from warnings to exceptions and activates the described protections.
How can I determine whether an installation is affected?
Check whether the installed NLTK version is earlier than 3.10.0 and inspect pathsec.py configuration. An installation is affected by this default-configuration issue if ENFORCE is set to False or left at its default value.