GHSA-568f-pv23-39p4
NLTK: Stable FrameNet and NKJP readers parse outside-root XML
Packages
Details
As written in the advisory (Markdown source, shown as plain text).
### 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.frame_by_name`, `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 `frame_by_name`, `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
framenet_frame_definition FRAME_LEAK
framenet_doc_text DOC_LEAK
framenet_lu_text LU_LEAK
nkjp_header_title HEADER_LEAK
```
### 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
References
External links from the advisory. They lead to third-party sites.
- https://github.com/nltk/nltk/security/advisories/GHSA-568f-pv23-39p4
- https://nvd.nist.gov/vuln/detail/CVE-2026-62385
- https://github.com/nltk/nltk/pull/3579
- https://github.com/nltk/nltk/pull/3581
- https://github.com/nltk/nltk/commit/7d1389d0789c1eca56bd0ed444089e0a3972e3ed
- https://github.com/nltk/nltk/commit/bf3bf32786791394a1008258b4917a7f2d4dbcda
- https://github.com/nltk/nltk
- https://github.com/nltk/nltk/releases/tag/v3.10.0
- https://github.com/pypa/advisory-database/tree/main/vulns/nltk/PYSEC-2026-3728.yaml
- https://www.vulncheck.com/advisories/nltk-path-traversal-via-framenet-and-nkjp-readers