AI and data stack advisories

Severe, 6 weeks1496Projects326

1496 severe, 6 weeks · 326 projects

NLTKGHSA-3gq4-3j92-5w49

NLTK: Corpus Reader Sandbox Bypass

NLTK

CVE-2026-79674 · Published Sep 8, 2026

High
Fix: upgrade to 3.10.3 or later
GitHub advisory

Summary

NLTK corpus-reader constructors can still reach outside-root file and database reads before the nltk.pathsec sandbox boundary is enforced.

The PoC shows the safe path blocked by pathsec.open, then LinThesaurusCorpusReader and PanLexLiteCorpusReader succeeding in the same process.

Affected Product

  • Product: NLTK
  • Asset / component: nltk.corpus.reader constructors
  • Version tested: 3.10.2
  • Deployment / package / tag: commit 474af1f5a94b1b8d53fc2b6defec3a2ce7633b74 / PyPI nltk
  • Environment used for verification: Python 3.13.14

Vulnerability Details

  • Vulnerability class: path sandbox bypass / external control of file path
  • Required privileges: none beyond the ability to supply a corpus root path to a consumer call site
  • Entry point: LinThesaurusCorpusReader(root) and PanLexLiteCorpusReader(root)
  • Trust boundary crossed: NLTK data-root sandbox enforced by nltk.pathsec
  • Root affected functions:
  • [CorpusReader.__init__](https://github.com/nltk/nltk/blob/474af1f5a94b1b8d53fc2b6defec3a2ce7633b74/nltk/corpus/reader/api.py#L73-L80)
  • [LinThesaurusCorpusReader.__init__](https://github.com/nltk/nltk/blob/474af1f5a94b1b8d53fc2b6defec3a2ce7633b74/nltk/corpus/reader/lin.py#L37-L43)
  • [PanLexLiteCorpusReader.__init__](https://github.com/nltk/nltk/blob/474af1f5a94b1b8d53fc2b6defec3a2ce7633b74/nltk/corpus/reader/panlex_lite.py#L45-L46)...

Affected versions

PackageAffectedFixed in
nltk
PyPI
< 3.10.33.10.3
Details and references

## Summary NLTK corpus-reader constructors can still reach outside-root file and database reads before the `nltk.pathsec` sandbox boundary is enforced. The PoC shows the safe path blocked by `pathsec.open`, then `LinThesaurusCorpusReader` and `PanLexLiteCorpusReader` succeeding in the same process. ## Affected Product - Product: NLTK - Asset / component: `nltk.corpus.reader` constructors - Version tested: `3.10.2` - Deployment / package / tag: commit `474af1f5a94b1b8d53fc2b6defec3a2ce7633b74` / PyPI `nltk` - Environment used for verification: Python 3.13.14 ## Vulnerability Details - Vulnerability class: path sandbox bypass / external control of file path - Required privileges: none beyond the ability to supply a corpus root path to a consumer call site - Entry point: `LinThesaurusCorpusReader(root)` and `PanLexLiteCorpusReader(root)` - Trust boundary crossed: NLTK data-root sandbox enforced by `nltk.pathsec` - Root affected functions: - [CorpusReader.__init__](https://github.com/nltk/nltk/blob/474af1f5a94b1b8d53fc2b6defec3a2ce7633b74/nltk/corpus/reader/api.py#L73-L80) - [LinThesaurusCorpusReader.__init__](https://github.com/nltk/nltk/blob/474af1f5a94b1b8d53fc2b6defec3a2ce7633b74/nltk/corpus/reader/lin.py#L37-L43) - [PanLexLiteCorpusReader.__init__](https://github.com/nltk/nltk/blob/474af1f5a94b1b8d53fc2b6defec3a2ce7633b74/nltk/corpus/reader/panlex_lite.py#L45-L46) - Measured unsafe effect: outside-root file/database reads still happen with `ENFORCE=True` ## Root Cause `CorpusReader.__init__()` turns a string root into a `FileSystemPathPointer` without any `pathsec` validation, and these readers then use builtin `open()` or `sqlite3.connect()` directly on derived paths. The constructor path therefore never hits the sandbox guard that `pathsec.open()` enforces. ```python if zipfile: root = ZipFilePathPointer(zipfile, zipentry) else: root = FileSystemPathPointer(root) with open(path) as lin_file: ... self._c = sqlite3.connect(os.path.join(root, "db.sqlite")).cursor() ``` ## Proof of Concept Save the script as `hy01_raw_path_poc.py` in the checkout root and run `python hy01_raw_path_poc.py`. ```python #!/usr/bin/env python3 """PoC for HY-01: corpus-reader sandbox bypass. This script proves three facts: - pathsec blocks a direct read through the sandboxed file API - LinThesaurusCorpusReader still reaches builtin open() on an outside path - PanLexLiteCorpusReader still opens an outside sqlite database and loads data """ from __future__ import annotations import builtins import pathlib import sqlite3 import sys import tempfile from unittest.mock import patch try: import nltk.pathsec as pathsec from nltk.corpus.reader.lin import LinThesaurusCorpusReader from nltk.corpus.reader.panlex_lite import PanLexLiteCorpusReader except ModuleNotFoundError: here = pathlib.Path(__file__).resolve() for base in (here.parent, *here.parents): if (base / "nltk").is_dir() and (base / "setup.py").exists(): sys.path.insert(0, str(base)) break else: raise RuntimeError( "Could not import nltk. Run this script from an NLTK checkout root " "or from an environment where the current checkout is installed." ) import nltk.pathsec as pathsec from nltk.corpus.reader.lin import LinThesaurusCorpusReader from nltk.corpus.reader.panlex_lite import PanLexLiteCorpusReader def main() -> int: pathsec.ENFORCE = True with patch.object(pathsec, "_get_allowed_roots", lambda: set()): with patch.object(pathsec.os, "getcwd", lambda: "sandbox-disabled"): with tempfile.TemporaryDirectory() as tmp: tmpdir = pathlib.Path(tmp) outside = tmpdir / "outside" outside.mkdir() blocked_file = outside / "blocked.txt" blocked_file.write_text("blocked", encoding="utf-8") control_target = str(blocked_file) try

CVSS 4.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N
Severity from
GitHub (reviewed advisory)
Weakness
CWE-73
Also known as
CVE-2026-79674, PYSEC-2026-3736

More NLTK advisories

All NLTK