CVE-2026-71514 Overview
CVE-2026-71514 is a path traversal vulnerability [CWE-22] in the Natural Language Toolkit (NLTK) affecting versions 3.9.4 through 3.10.2. The flaw resides in the CrubadanCorpusReader class, where the _load_lang_ngrams method joins the corpus root with crubadan_code values read from a corpus table.txt mapping file. Because the code uses the builtin open() instead of the nltk.pathsec validated opener, absolute path values in the mapping file cause os.path.join to discard the root, escaping the corpus directory. An attacker who controls a corpus package can disclose files outside the corpus root through lang_freq.
Critical Impact
File disclosure is limited to paths ending in -3grams.txt whose contents parse as token count lines, and requires local access with user interaction to load a malicious corpus.
Affected Products
- NLTK 3.9.4
- NLTK versions between 3.9.4 and 3.10.2
- NLTK 3.10.2
Discovery Timeline
- 2026-08-22 - CVE-2026-71514 published to NVD
- 2026-08-24 - Last updated in NVD database
Technical Details for CVE-2026-71514
Vulnerability Analysis
The vulnerability exists in nltk/corpus/reader/crubadan.py within the CrubadanCorpusReader class. The _load_lang_ngrams method reads a mapping file called table.txt and uses the column-0 value, crubadan_code, to construct a file path. This value is combined with the corpus root using os.path.join and then passed to Python's builtin open(). NLTK ships a hardened opener in nltk.pathsec that enforces containment inside the corpus root when the ENFORCE flag is set, but this code path bypasses it entirely. The lang_freq accessor exposes contents of the resulting file to callers, enabling arbitrary file read within the constraints of the parser.
Root Cause
Two issues combine to produce the flaw. First, os.path.join in Python discards preceding components when a later component is an absolute path, so an absolute crubadan_code value overrides the corpus root. Second, _load_lang_ngrams uses the standard library open() rather than the pathsec_open wrapper that validates paths remain inside the corpus directory. The parser accepts only files ending in -3grams.txt whose lines match a token count grammar, which bounds what can be exfiltrated.
Attack Vector
Exploitation requires an attacker to control the contents of a corpus package that the victim loads with NLTK. The attacker crafts a table.txt mapping entry whose column-0 value is an absolute path pointing to a target -3grams.txt file outside the corpus root. When the victim invokes lang_freq, _load_lang_ngrams opens the attacker-specified path and returns its parsed token frequencies.
# Patch excerpt from nltk/corpus/reader/crubadan.py
from nltk.corpus.reader import CorpusReader
from nltk.data import ZipFilePathPointer
from nltk.pathsec import open as pathsec_open
from nltk.probability import FreqDist
Source: GitHub NLTK Commit 10d34b3
The patch introduces pathsec_open so all corpus reads pass through the sandboxed opener that enforces containment within the corpus root.
Detection Methods for CVE-2026-71514
Indicators of Compromise
- Presence of table.txt files inside Crubadan corpus packages containing absolute paths in the column-0 crubadan_code field.
- Unexpected access by Python processes to -3grams.txt files located outside standard NLTK corpus directories.
- Installation of third-party or untrusted Crubadan corpus packages from non-official sources.
Detection Strategies
- Audit installed NLTK versions across development and production hosts and flag any instance in the range 3.9.4 through 3.10.2.
- Inspect corpus packages for table.txt entries whose first column begins with /, \, or a drive letter, which indicates absolute path values.
- Enable filesystem auditing on Python processes to log open() calls made by CrubadanCorpusReader and correlate against the expected corpus root.
Monitoring Recommendations
- Monitor package installation events for NLTK corpora that originate outside nltk_data official mirrors.
- Log and review access patterns to sensitive files with the -3grams.txt suffix, since the parser restricts reads to that extension.
- Track upstream advisories from the NLTK project and the VulnCheck Advisory on NLTK for related follow-up findings.
How to Mitigate CVE-2026-71514
Immediate Actions Required
- Upgrade NLTK to a version that includes commit 10d34b3f4fe3fec74b76527a409eb0acbac2e8ab, which routes corpus reads through the pathsec sandbox.
- Remove or quarantine any Crubadan corpus packages loaded from untrusted sources until they can be validated.
- Review application code that calls CrubadanCorpusReader.lang_freq and restrict which corpora it can load.
Patch Information
The NLTK maintainers addressed the issue in commit 10d34b3 by importing pathsec_open in nltk/corpus/reader/crubadan.py and nltk/chunk/named_entity.py and routing corpus-reader reads through the hardened pathsec sandbox. Users should upgrade to the fixed release referenced in the GitHub NLTK Repository and confirm the patch is present in nltk/corpus/reader/crubadan.py.
Workarounds
- Load only Crubadan corpus packages from trusted, integrity-verified sources such as the official nltk_data distribution.
- Run NLTK processes under a dedicated OS account with least-privilege filesystem permissions to limit the scope of readable files.
- Validate table.txt mapping files before use and reject entries whose crubadan_code column contains path separators or absolute path indicators.
# Upgrade NLTK to a patched version
pip install --upgrade nltk
# Verify the fix is present in the installed package
python -c "import inspect, nltk.corpus.reader.crubadan as c; print('pathsec_open' in inspect.getsource(c))"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

