GHSA-568f-pv23-39p4: Path Traversal
Summary
Published nltk==3.9.4 still contains several XML-reader entrypoints that build parser paths from caller-controlled selectors or trusted-looking index state without preserving the corpus-root boundary.
Details
- Vulnerability type: Path traversal and trusted-root bypass - Affected component: FramenetCorpusReader.framebyname, FramenetCorpusReader.doc, FramenetCorpusReader.lu, NKJPCorpusReader.header - Affected versions: Published 3.9.4 reproduced. Current source v3.10.0-rc2 acted as a negative control and blocked the same payloads. - Patched versions: Patched in version 3.10.0, which includes the path-safety rejections seen in the release candidate. - Root cause: Stable reader paths still construct raw XML filenames from unsafe selectors, poisoned index state, or unsafe file identifiers.
I confirmed four public stable entrypoints return parsed outside-root content: a parent-segment traversal frame name, a poisoned fulltext index filename, a poisoned LU id, and an unsafe NKJP header file identifier. Current source rejects the same payloads with explicit path-safety errors, which shows the bug is real but version-scoped to the published stable package.
PoC
Preconditions - The application exposes FrameNet or NKJP reader APIs while trusting NLTK to keep XML parsing inside a corpus root.
Steps 1. Create a minimal FrameNet or NKJP corpus root and place attacker-chosen XML files outside that root. 2. Feed unsafe selectors or poisoned index state into the relevant public stable 3.9.4 APIs. 3. Observe framebyname, doc, lu(...).exemplars, or header return parsed outside-root values. 4. Run the same payloads against current source and observe explicit path-safety rejections.
Minimal reproducible excerpt
text framenetframedefinition FRAMELEAK framenetdoctext DOCLEAK framenetlutext LULEAK nkjpheadertitle HEADERLEAK
Impact
Applications that process attacker-influenced FrameNet or NKJP corpus selectors or state can be made to parse XML outside the trusted corpus root through normal public reader responses.
Remediation
Keep these reader paths on the same root-confinement model as CorpusReader.open() and nltk.pathsec. Reject unsafe path components before constructing filenames from frame names, document filenames, LU ids, or NKJP file identifiers.
Resources
- https://github.com/nltk/nltk/blob/3.9.4/nltk/corpus/reader/framenet.py#L1366-L1369 - https://github.com/nltk/nltk/blob/3.9.4/nltk/corpus/reader/framenet.py#L1456-L1460 - https://github.com/nltk/nltk/blob/3.9.4/nltk/corpus/reader/framenet.py#L1803-L1810 - https://github.com/nltk/nltk/blob/3.9.4/nltk/corpus/reader/nkjp.py#L96-L103 - https://github.com/nltk/nltk/blob/3.9.4/nltk/corpus/reader/nkjp.py#L251-L256 - https://github.com/nltk/nltk/blob/v3.10.0-rc2/nltk/corpus/reader/framenet.py#L1388-L1399 - https://github.com/nltk/nltk/blob/v3.10.0-rc2/nltk/corpus/reader/nkjp.py#L96-L128
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 - Upgrade
Upgrade
nltkto a version that resolves this vulnerability.Fixed in 3.10.0 - Configuration
Update/modify NLTK corpus reader code so that public reader APIs (FramenetCorpusReader.frame_by_name/doc/lu(...).exemplars and NKJPCorpusReader.header) reject unsafe selectors or poisoned index state with explicit path-safety errors, preserving the corpus-root boundary used by CorpusReader.open() and nltk.pathsec.
NLTK corpus reader path construction (FramenetCorpusReader, NKJPCorpusReader) path-safety validation for selectors/index-derived filenames = reject unsafe path components before constructing XML filenames from frame names, document filenames, LU ids, or NKJP file identifiers
Event History
Frequently Asked Questions
Which installations are affected?
Published nltk version 3.9.4 is affected. Version 3.10.0 is patched; current source v3.10.0-rc2 rejected the tested unsafe paths.
What input must an attacker influence to exploit this?
An attacker needs influence over a selector, file identifier, or trusted-looking index state consumed by the affected corpus readers. Confirmed cases include a parent-segment frame name, a poisoned fulltext-index filename, a poisoned LU ID, and an unsafe NKJP header file identifier.
What should teams do if they cannot immediately upgrade?
Do not pass untrusted selectors or file identifiers to FramenetCorpusReader.frame_by_name, FramenetCorpusReader.doc, FramenetCorpusReader.lu, or NKJPCorpusReader.header. Protect corpus index state from modification and validate values so they cannot escape the intended corpus root.
How can I determine whether my application is exposed?
Check whether it uses nltk 3.9.4 and invokes any of the four affected entrypoints with values derived from external input or mutable corpus/index data. The issue is demonstrated by those entrypoints returning parsed XML content from outside the corpus root.