Action not permitted
Modal body text goes here.
Modal Title
Modal Body
PYSEC-2026-3722
Vulnerability from pysec - Published: 2026-08-22 15:16 - Updated: 2026-08-27 23:45NLTK 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.
| Name | purl | nltk | pkg:pypi/nltk |
|---|
{
"affected": [
{
"ecosystem_specific": {},
"package": {
"ecosystem": "PyPI",
"name": "nltk",
"purl": "pkg:pypi/nltk"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.10.0"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.8",
"0.9",
"0.9.3",
"0.9.4",
"0.9.5",
"0.9.6",
"0.9.7",
"0.9.8",
"0.9.9",
"2.0.1",
"2.0.1rc1",
"2.0.1rc2-git",
"2.0.1rc3",
"2.0.1rc4",
"2.0.2",
"2.0.3",
"2.0.4",
"2.0.5",
"2.0b4",
"2.0b5",
"2.0b6",
"2.0b7",
"2.0b8",
"2.0b9",
"3.0.0",
"3.0.0b1",
"3.0.0b2",
"3.0.1",
"3.0.2",
"3.0.3",
"3.0.4",
"3.0.5",
"3.1",
"3.2",
"3.2.1",
"3.2.2",
"3.2.3",
"3.2.4",
"3.2.5",
"3.3",
"3.4",
"3.4.1",
"3.4.2",
"3.4.3",
"3.4.4",
"3.4.5",
"3.5",
"3.5b1",
"3.6",
"3.6.1",
"3.6.2",
"3.6.3",
"3.6.4",
"3.6.5",
"3.6.6",
"3.6.7",
"3.7",
"3.8",
"3.8.1",
"3.9",
"3.9.1",
"3.9.2",
"3.9.3",
"3.9.4",
"3.9b1"
]
}
],
"aliases": [
"CVE-2026-62388",
"GHSA-p3m8-78j2-g5p3"
],
"details": "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.",
"id": "PYSEC-2026-3722",
"modified": "2026-08-27T23:45:34.112638Z",
"published": "2026-08-22T15:16:18.967Z",
"references": [
{
"type": "ADVISORY",
"url": "https://www.vulncheck.com/advisories/nltk-before-insecure-default-configuration-pathsec"
},
{
"type": "EVIDENCE",
"url": "https://github.com/nltk/nltk/security/advisories/GHSA-p3m8-78j2-g5p3"
}
],
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
BREW-ACRONYM-CVE-2026-62388 (PYSEC-2026-3722)
Vulnerability from osv_homebrew – Published: 2026-08-28 12:17 – Updated: 2026-09-17 18:47 – Source websiteNLTK'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:
- pathsec.open('/etc/passwd') succeeds (reads the file, emits warning)
- pathsec.validate_network_url('http://169.254.169.254/...') succeeds (warning only)
- pickle.loads() via nltk.data.load() proceeds despite unsafe source (warning only)
Every security gate follows the same pattern:
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:
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.
{
"affected": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "nltk",
"resource_purl": "pkg:pypi/nltk@3.10.3",
"upstream_fixed_in": "3.10.0"
},
"package": {
"ecosystem": "Homebrew",
"name": "acronym",
"purl": "pkg:brew/acronym"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0"
},
{
"fixed": "2.0.0_4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/nltk@3.10.3",
"name": "nltk",
"resource": "nltk",
"strategy": "registry",
"subject_version": "3.10.3"
}
]
},
"details": "NLTK\u0027s 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.\n\nThe 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:\n\n1. pathsec.open(\u0027/etc/passwd\u0027) succeeds (reads the file, emits warning)\n2. pathsec.validate_network_url(\u0027http://169.254.169.254/...\u0027) succeeds (warning only)\n3. pickle.loads() via nltk.data.load() proceeds despite unsafe source (warning only)\n\nEvery security gate follows the same pattern:\n```python\nENFORCE = os.environ.get(\u0027NLTK_PATHSEC_ENFORCE\u0027, \u0027\u0027).lower() in (\u00271\u0027, \u0027true\u0027, \u0027yes\u0027)\n\ndef validate_something(path):\n if is_violation(path):\n if ENFORCE:\n raise SecurityError(\u0027...\u0027) # Only raised when env var is set\n else:\n warnings.warn(\u0027...\u0027, RuntimeWarning) # Default: warning only\n # Execution continues regardless\n```\n\nThis 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.\n\nPoC:\n```python\nimport nltk.pathsec\nimport warnings\n\n# Show that ENFORCE is False by default\nprint(f\u0027ENFORCE = {nltk.pathsec.ENFORCE}\u0027) # False\n\n# Attempt to read /etc/passwd through pathsec -- should be blocked\nwith warnings.catch_warnings(record=True) as w:\n warnings.simplefilter(\u0027always\u0027)\n result = nltk.pathsec.open(\u0027/etc/passwd\u0027, \u0027r\u0027)\n print(f\u0027File opened: {result.name}\u0027) # /etc/passwd\n print(f\u0027Warning emitted: {w[0].message}\u0027) # RuntimeWarning (not an exception)\n # Attack succeeds -- file is readable\n```\n\nThe 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.\n\nSuggested fix: Change default to ENFORCE=True. Users who need backwards compatibility can set NLTK_PATHSEC_ENFORCE=0 to explicitly disable.",
"id": "BREW-acronym-CVE-2026-62388",
"modified": "2026-09-17T18:47:55Z",
"published": "2026-08-28T12:17:01Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/security/advisories/GHSA-p3m8-78j2-g5p3"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-62388"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/pull/3593"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/commit/155e40343cff0bf50d233e274a12e04d1428b1d9"
},
{
"type": "PACKAGE",
"url": "https://github.com/nltk/nltk"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/releases/tag/v3.10.0"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-3722.yaml"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/nltk-before-insecure-default-configuration-pathsec"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "NLTK: Default ENFORCE=False Disables All pathsec Security Controls",
"upstream": [
"PYSEC-2026-3722",
"CVE-2026-62388",
"GHSA-p3m8-78j2-g5p3"
]
}
BREW-GPTLINE-CVE-2026-62388 (PYSEC-2026-3722)
Vulnerability from osv_homebrew – Published: 2026-08-28 12:34 – Updated: 2026-09-17 19:32 – Source websiteNLTK'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:
- pathsec.open('/etc/passwd') succeeds (reads the file, emits warning)
- pathsec.validate_network_url('http://169.254.169.254/...') succeeds (warning only)
- pickle.loads() via nltk.data.load() proceeds despite unsafe source (warning only)
Every security gate follows the same pattern:
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:
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.
| URL | Type | |||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||||||||||||||||||||||||
{
"affected": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "nltk",
"resource_purl": "pkg:pypi/nltk@3.10.3",
"upstream_fixed_in": "3.10.0"
},
"package": {
"ecosystem": "Homebrew",
"name": "gptline",
"purl": "pkg:brew/gptline"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.8"
},
{
"fixed": "1.0.8_22"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/nltk@3.10.3",
"name": "nltk",
"resource": "nltk",
"strategy": "registry",
"subject_version": "3.10.3"
}
]
},
"details": "NLTK\u0027s 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.\n\nThe 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:\n\n1. pathsec.open(\u0027/etc/passwd\u0027) succeeds (reads the file, emits warning)\n2. pathsec.validate_network_url(\u0027http://169.254.169.254/...\u0027) succeeds (warning only)\n3. pickle.loads() via nltk.data.load() proceeds despite unsafe source (warning only)\n\nEvery security gate follows the same pattern:\n```python\nENFORCE = os.environ.get(\u0027NLTK_PATHSEC_ENFORCE\u0027, \u0027\u0027).lower() in (\u00271\u0027, \u0027true\u0027, \u0027yes\u0027)\n\ndef validate_something(path):\n if is_violation(path):\n if ENFORCE:\n raise SecurityError(\u0027...\u0027) # Only raised when env var is set\n else:\n warnings.warn(\u0027...\u0027, RuntimeWarning) # Default: warning only\n # Execution continues regardless\n```\n\nThis 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.\n\nPoC:\n```python\nimport nltk.pathsec\nimport warnings\n\n# Show that ENFORCE is False by default\nprint(f\u0027ENFORCE = {nltk.pathsec.ENFORCE}\u0027) # False\n\n# Attempt to read /etc/passwd through pathsec -- should be blocked\nwith warnings.catch_warnings(record=True) as w:\n warnings.simplefilter(\u0027always\u0027)\n result = nltk.pathsec.open(\u0027/etc/passwd\u0027, \u0027r\u0027)\n print(f\u0027File opened: {result.name}\u0027) # /etc/passwd\n print(f\u0027Warning emitted: {w[0].message}\u0027) # RuntimeWarning (not an exception)\n # Attack succeeds -- file is readable\n```\n\nThe 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.\n\nSuggested fix: Change default to ENFORCE=True. Users who need backwards compatibility can set NLTK_PATHSEC_ENFORCE=0 to explicitly disable.",
"id": "BREW-gptline-CVE-2026-62388",
"modified": "2026-09-17T19:32:01Z",
"published": "2026-08-28T12:34:21Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/security/advisories/GHSA-p3m8-78j2-g5p3"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-62388"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/pull/3593"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/commit/155e40343cff0bf50d233e274a12e04d1428b1d9"
},
{
"type": "PACKAGE",
"url": "https://github.com/nltk/nltk"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/releases/tag/v3.10.0"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-3722.yaml"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/nltk-before-insecure-default-configuration-pathsec"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "NLTK: Default ENFORCE=False Disables All pathsec Security Controls",
"upstream": [
"PYSEC-2026-3722",
"CVE-2026-62388",
"GHSA-p3m8-78j2-g5p3"
]
}
BREW-SAFETY-CVE-2026-62388 (PYSEC-2026-3722)
Vulnerability from osv_homebrew – Published: 2026-08-28 13:16 – Updated: 2026-09-17 17:35 – Source websiteNLTK'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:
- pathsec.open('/etc/passwd') succeeds (reads the file, emits warning)
- pathsec.validate_network_url('http://169.254.169.254/...') succeeds (warning only)
- pickle.loads() via nltk.data.load() proceeds despite unsafe source (warning only)
Every security gate follows the same pattern:
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:
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.
| URL | Type | |||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||||||||||||||||||||||||
{
"affected": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "nltk",
"resource_purl": "pkg:pypi/nltk@3.10.3",
"upstream_fixed_in": "3.10.0"
},
"package": {
"ecosystem": "Homebrew",
"name": "safety",
"purl": "pkg:brew/safety"
},
"ranges": [
{
"events": [
{
"introduced": "3.3.1"
},
{
"fixed": "3.8.1_1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/nltk@3.10.3",
"name": "nltk",
"resource": "nltk",
"strategy": "registry",
"subject_version": "3.10.3"
}
]
},
"details": "NLTK\u0027s 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.\n\nThe 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:\n\n1. pathsec.open(\u0027/etc/passwd\u0027) succeeds (reads the file, emits warning)\n2. pathsec.validate_network_url(\u0027http://169.254.169.254/...\u0027) succeeds (warning only)\n3. pickle.loads() via nltk.data.load() proceeds despite unsafe source (warning only)\n\nEvery security gate follows the same pattern:\n```python\nENFORCE = os.environ.get(\u0027NLTK_PATHSEC_ENFORCE\u0027, \u0027\u0027).lower() in (\u00271\u0027, \u0027true\u0027, \u0027yes\u0027)\n\ndef validate_something(path):\n if is_violation(path):\n if ENFORCE:\n raise SecurityError(\u0027...\u0027) # Only raised when env var is set\n else:\n warnings.warn(\u0027...\u0027, RuntimeWarning) # Default: warning only\n # Execution continues regardless\n```\n\nThis 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.\n\nPoC:\n```python\nimport nltk.pathsec\nimport warnings\n\n# Show that ENFORCE is False by default\nprint(f\u0027ENFORCE = {nltk.pathsec.ENFORCE}\u0027) # False\n\n# Attempt to read /etc/passwd through pathsec -- should be blocked\nwith warnings.catch_warnings(record=True) as w:\n warnings.simplefilter(\u0027always\u0027)\n result = nltk.pathsec.open(\u0027/etc/passwd\u0027, \u0027r\u0027)\n print(f\u0027File opened: {result.name}\u0027) # /etc/passwd\n print(f\u0027Warning emitted: {w[0].message}\u0027) # RuntimeWarning (not an exception)\n # Attack succeeds -- file is readable\n```\n\nThe 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.\n\nSuggested fix: Change default to ENFORCE=True. Users who need backwards compatibility can set NLTK_PATHSEC_ENFORCE=0 to explicitly disable.",
"id": "BREW-safety-CVE-2026-62388",
"modified": "2026-09-17T17:35:56Z",
"published": "2026-08-28T13:16:06Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/security/advisories/GHSA-p3m8-78j2-g5p3"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-62388"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/pull/3593"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/commit/155e40343cff0bf50d233e274a12e04d1428b1d9"
},
{
"type": "PACKAGE",
"url": "https://github.com/nltk/nltk"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/releases/tag/v3.10.0"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-3722.yaml"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/nltk-before-insecure-default-configuration-pathsec"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "NLTK: Default ENFORCE=False Disables All pathsec Security Controls",
"upstream": [
"PYSEC-2026-3722",
"CVE-2026-62388",
"GHSA-p3m8-78j2-g5p3"
]
}
CVE-2026-62388 (GCVE-0-2026-62388)
Vulnerability from cvelistv5 – Published: 2026-08-22 14:12 – Updated: 2026-08-29 11:47- CWE-1188 - Initialization of a Resource with an Insecure Default
| URL | Tags |
|---|---|
| https://github.com/nltk/nltk/security/advisories/… | vendor-advisory |
| https://www.vulncheck.com/advisories/nltk-before-… | third-party-advisory |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-62388",
"options": [
{
"Exploitation": "poc"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-08-26T17:53:47.950536Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-08-26T17:54:14.495Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"references": [
{
"tags": [
"exploit"
],
"url": "https://github.com/nltk/nltk/security/advisories/GHSA-p3m8-78j2-g5p3"
}
],
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"defaultStatus": "unaffected",
"packageURL": "pkg:pypi/nltk",
"product": "nltk",
"vendor": "nltk",
"versions": [
{
"lessThan": "3.10.0",
"status": "affected",
"version": "0",
"versionType": "semver"
},
{
"status": "unaffected",
"version": "3.10.0",
"versionType": "semver"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:nltk:nltk:*:*:*:*:*:*:*:*",
"versionEndExcluding": "3.10.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
]
}
],
"datePublic": "2026-08-07T00:00:00.000Z",
"descriptions": [
{
"lang": "en",
"value": "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."
}
],
"metrics": [
{
"cvssV4_0": {
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"baseScore": 8.7,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "NONE"
},
"format": "CVSS"
},
{
"cvssV3_1": {
"attackComplexity": "LOW",
"attackVector": "NETWORK",
"availabilityImpact": "NONE",
"baseScore": 7.5,
"baseSeverity": "HIGH",
"confidentialityImpact": "HIGH",
"integrityImpact": "NONE",
"privilegesRequired": "NONE",
"scope": "UNCHANGED",
"userInteraction": "NONE",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"version": "3.1"
},
"format": "CVSS"
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-1188",
"description": "Initialization of a Resource with an Insecure Default",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-08-29T11:47:32.048Z",
"orgId": "83251b91-4cc7-4094-a5c7-464a1b83ea10",
"shortName": "VulnCheck"
},
"references": [
{
"name": "GitHub Security Advisory (GHSA-p3m8-78j2-g5p3)",
"tags": [
"vendor-advisory"
],
"url": "https://github.com/nltk/nltk/security/advisories/GHSA-p3m8-78j2-g5p3"
},
{
"name": "VulnCheck Advisory: NLTK before 3.10.0 Insecure Default Configuration pathsec",
"tags": [
"third-party-advisory"
],
"url": "https://www.vulncheck.com/advisories/nltk-before-insecure-default-configuration-pathsec"
}
],
"title": "NLTK before 3.10.0 Insecure Default Configuration in pathsec.py",
"x_generator": {
"engine": "vulncheck-endgame"
}
}
},
"cveMetadata": {
"assignerOrgId": "83251b91-4cc7-4094-a5c7-464a1b83ea10",
"assignerShortName": "VulnCheck",
"cveId": "CVE-2026-62388",
"datePublished": "2026-08-22T14:12:38.647Z",
"dateReserved": "2026-07-13T22:40:54.412Z",
"dateUpdated": "2026-08-29T11:47:32.048Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
GHSA-P3M8-78J2-G5P3
Vulnerability from github – Published: 2026-09-02 15:40 – Updated: 2026-09-02 15:40NLTK'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:
- pathsec.open('/etc/passwd') succeeds (reads the file, emits warning)
- pathsec.validate_network_url('http://169.254.169.254/...') succeeds (warning only)
- pickle.loads() via nltk.data.load() proceeds despite unsafe source (warning only)
Every security gate follows the same pattern:
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:
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.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.9.4"
},
"package": {
"ecosystem": "PyPI",
"name": "nltk"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.10.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-62388"
],
"database_specific": {
"cwe_ids": [
"CWE-1188"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-02T15:40:33Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "NLTK\u0027s 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.\n\nThe 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:\n\n1. pathsec.open(\u0027/etc/passwd\u0027) succeeds (reads the file, emits warning)\n2. pathsec.validate_network_url(\u0027http://169.254.169.254/...\u0027) succeeds (warning only)\n3. pickle.loads() via nltk.data.load() proceeds despite unsafe source (warning only)\n\nEvery security gate follows the same pattern:\n```python\nENFORCE = os.environ.get(\u0027NLTK_PATHSEC_ENFORCE\u0027, \u0027\u0027).lower() in (\u00271\u0027, \u0027true\u0027, \u0027yes\u0027)\n\ndef validate_something(path):\n if is_violation(path):\n if ENFORCE:\n raise SecurityError(\u0027...\u0027) # Only raised when env var is set\n else:\n warnings.warn(\u0027...\u0027, RuntimeWarning) # Default: warning only\n # Execution continues regardless\n```\n\nThis 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.\n\nPoC:\n```python\nimport nltk.pathsec\nimport warnings\n\n# Show that ENFORCE is False by default\nprint(f\u0027ENFORCE = {nltk.pathsec.ENFORCE}\u0027) # False\n\n# Attempt to read /etc/passwd through pathsec -- should be blocked\nwith warnings.catch_warnings(record=True) as w:\n warnings.simplefilter(\u0027always\u0027)\n result = nltk.pathsec.open(\u0027/etc/passwd\u0027, \u0027r\u0027)\n print(f\u0027File opened: {result.name}\u0027) # /etc/passwd\n print(f\u0027Warning emitted: {w[0].message}\u0027) # RuntimeWarning (not an exception)\n # Attack succeeds -- file is readable\n```\n\nThe 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.\n\nSuggested fix: Change default to ENFORCE=True. Users who need backwards compatibility can set NLTK_PATHSEC_ENFORCE=0 to explicitly disable.",
"id": "GHSA-p3m8-78j2-g5p3",
"modified": "2026-09-02T15:40:33Z",
"published": "2026-09-02T15:40:33Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/security/advisories/GHSA-p3m8-78j2-g5p3"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-62388"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/pull/3593"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/commit/155e40343cff0bf50d233e274a12e04d1428b1d9"
},
{
"type": "PACKAGE",
"url": "https://github.com/nltk/nltk"
},
{
"type": "WEB",
"url": "https://github.com/nltk/nltk/releases/tag/v3.10.0"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-3722.yaml"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/nltk-before-insecure-default-configuration-pathsec"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "NLTK: Default ENFORCE=False Disables All pathsec Security Controls"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.