CVE-2026-126304: CVE-2026-126304: Symlink Path Traversal in NLTK YCOECorpusReader
CVE-2026-126304: Symlink Path Traversal in NLTK YCOECorpusReader Vulnerability ID: CVE-2026-126304 CVSS Score: 8.7 Published: 2026-11-13 CVE-2026-126304 is a symlink path traversal vulnerability (CWE-59) in the Natu
CVE-2026-126304: Symlink Path Traversal in NLTK YCOECorpusReader
Vulnerability ID: CVE-2026-126304
CVSS Score: 8.7
Published: 2026-11-13
CVE-2026-126304 is a symlink path traversal vulnerability (CWE-59) in the Natural Language Toolkit (NLTK) versions 3.10.0 prior to 3.10.4. The YCOECorpusReader class constructs internal sub-readers for the 'psd' and 'pos' subdirectories using FileSystemPathPointer.join(), which relies exclusively on lexical string-prefix validation rather than canonical path resolution. An attacker who supplies a crafted YCOE corpus containing symbolic links in place of the 'psd' or 'pos' subdirectories can bypass directory confinement and read arbitrary files from sibling corpora or sensitive directories within the NLTK data sandbox.
TL;DR
NLTK versions 3.10.0 through 3.10.3 fail to resolve symbolic links when initializing the YCOECorpusReader 'psd' and 'pos' subdirectories. Processing an untrusted corpus archive with symlinks allows unauthorized read access to files outside the designated corpus root. Upgrade to NLTK 3.10.4 to enforce realpath containment checks.
⚠️ Exploit Status: POC
Technical Details
- CVE ID: CVE-2026-126304 (GHSA-qg35-44qx-7vrr)
- Vulnerability Class: CWE-59: Improper Link Resolution Before File Access ('Link Following')
- Affected Component: YCOECorpusReader (nltk/corpus/reader/ycoe.py)
- CVSS v4.0 Score: 8.7 HIGH (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)
- EPSS Score: 0.52% (44.89th percentile)
- Impact: Unauthorized arbitrary file read outside corpus root via symlink traversal
- Exploit Status: Proof-of-Concept available in NLTK unit test suite
- Fixed Version: NLTK 3.10.4
Affected Systems
- Natural Language Toolkit (NLTK)
-
Natural Language Toolkit (NLTK): >= 3.10.0, < 3.10.4 (Fixed in:
3.10.4)
Code Analysis
Commit: 68434c0
Added realpath containment validation via validate_path(required_root=self.root) in YCOECorpusReader.
Commit: 2c563b1
Scoped the YCOE guard and imported validate_path at module level.
--- a/nltk/corpus/reader/ycoe.py
+++ b/nltk/corpus/reader/ycoe.py
@@ -24,6 +24,7 @@
from nltk.corpus.reader.bracket_parse import BracketParseCorpusReader
from nltk.corpus.reader.tagged import TaggedCorpusReader
from nltk.corpus.reader.util import *
+from nltk.pathsec import validate_path
from nltk.tokenize import RegexpTokenizer
@@ -37,6 +38,15 @@ class YCOECorpusReader(CorpusReader):
def __init__(self, root, encoding="utf8"):
CorpusReader.__init__(self, root, [], encoding)
+ # A psd/pos directory symlink escapes the corpus root: join() does a
+ # string-prefix check only, not symlink resolution, so files outside the
+ # YCOE corpus would be enumerated and read (CWE-59).
+ for sub in ("psd", "pos"):
+ validate_path(
+ self.root.join(sub),
+ context="YCOECorpusReader",
+ required_root=self.root,
+ )
+
self._psd_reader = YCOEParseCorpusReader(
self.root.join("psd"), ".*", ".psd", encoding=encoding
)
self._pos_reader = TaggedCorpusReader(
self.root.join("pos"), ".*", ".pos", encoding=encoding
)
Exploit Details
- GitHub (NLTK Official Regression Test Suite): Unit test in nltk/test/unit/test_ycoe_streamview_pathsec.py demonstrating sibling corpus data exfiltration via pos/psd directory symlinks.
Mitigation Strategies
- Upgrade NLTK to version 3.10.4 or later to enforce canonical path validation via nltk.pathsec.validate_path.
- Enforce strict archive extraction policies (such as Python's tarfile data_filter) to prevent symbolic links from being written during corpus unpacking.
- Restrict filesystem read and write permissions on NLTK data directories and sibling corpus storage locations.
Remediation Steps:
- Identify all Python environments, containers, and virtual environments running nltk versions >= 3.10.0 and < 3.10.4.
- Upgrade NLTK by executing: pip install --upgrade 'nltk>=3.10.4'.
- Audit existing corpus directories for unexpected symbolic links using: find /path/to/nltk_data -type l -ls.
- Update corpus ingestion pipelines to reject tar or zip archives containing symbolic or hard links.
References
- Official CVE Record: CVE-2026-126304
- GitHub Security Advisory: GHSA-qg35-44qx-7vrr
- VulnCheck Advisory: NLTK 3.10.0 before 3.10.4 Symlink Escape in YCOECorpusReader
- NLTK Pull Request #3888
- Fix Commit: YCOE Containment Enforced
- Refinement Commit: Test Scoping & View Refusal
- NLTK Release v3.10.4
Read the full report for CVE-2026-126304 on our website for more details including interactive diagrams and full exploit analysis.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.