a1ohadance/CVE-2026-38360

GitHub: a1ohadance/CVE-2026-38360

记录了 dash-uploader(Plotly Dash 文件上传组件)中一个 CVSS 9.8 的未认证路径遍历漏洞,详述了攻击向量、多种 RCE 利用原语及无补丁环境下的缓解策略。

Stars: 1 | Forks: 0

# CVE-2026-38360:dash-uploader 中的路径遍历漏洞 [![CVE](https://img.shields.io/badge/CVE-2026--38360-red?style=for-the-badge)](https://www.cve.org/CVERecord?id=CVE-2026-38360) [![NVD](https://img.shields.io/badge/NVD-CVE--2026--38360-blue?style=for-the-badge)](https://nvd.nist.gov/vuln/detail/CVE-2026-38360) [![CWE](https://img.shields.io/badge/CWE-22-orange?style=for-the-badge)](https://cwe.mitre.org/data/definitions/22.html) [![Severity](https://img.shields.io/badge/Severity-Critical-red?style=for-the-badge)](#) [![Patch](https://img.shields.io/badge/Patch-None-black?style=for-the-badge)](#mitigation) [![Auth](https://img.shields.io/badge/Auth-None_required-red?style=for-the-badge)](#attack-vectors) [![Version](https://img.shields.io/badge/dash--uploader-0.6.1-blue?style=for-the-badge)](https://pypi.org/project/dash-uploader/) [![PyPI Downloads](https://img.shields.io/badge/PyPI%20downloads-28K%2Fmonth-blue?style=for-the-badge)](https://pepy.tech/project/dash-uploader) [![Total Downloads](https://img.shields.io/badge/Total%20downloads-733.08K-blue?style=for-the-badge)](https://pepy.tech/project/dash-uploader) [![License](https://img.shields.io/pypi/l/dash-uploader?style=for-the-badge)](https://pypi.org/project/dash-uploader/) [`fohrloop/dash-uploader`](https://github.com/fohrloop/dash-uploader)(Python,PyPI)中存在未经身份验证的路径遍历漏洞,允许任意文件写入,可导致(但不限于)**远程代码执行 (RCE)**、应用程序源代码覆盖、存储型 XSS 以及持久化后门植入。 ### ⚠️ 目前没有补丁,且未来也不会发布 该代码库已于 [2025-07-19 被归档](https://github.com/fohrloop/dash-uploader/issues/153),没有活跃的维护者。所有已发布的版本(从 `0.1.0` 到 `0.7.0a2`)均受影响,并将持续处于受影响状态。该包每月仍有大约 28,000 次下载。 任何在生产环境中运行 `dash-uploader` 的用户都必须自行采取缓解措施。推荐的修复方案是迁移到 Plotly Dash 内置的 `dcc.Upload` 组件。有关完整的选项,请参阅[缓解措施](#mitigation)。 | | | |---|---| | **CVE ID** | [CVE-2026-38360](https://www.cve.org/CVERecord?id=CVE-2026-38360) ([NVD](https://nvd.nist.gov/vuln/detail/CVE-2026-38360)) | | **漏洞类型** | 路径遍历 (CWE-22) | | **CVSS 3.1** | 9.8 / 严重 (`AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`) | | **产品** | dash-uploader | | **受影响版本** | `0.1.0` 至 `0.7.0a2`(所有 18 个发行版) | | **修复版本** | 无(项目已于 2025-07-19 归档) | | **攻击向量** | 远程,无需身份验证 | | **发现者** | Muhammad Fitri Bin Mohd Sultan | | **分配方** | MITRE,2026-05-07 | | **相关漏洞** | [CVE-2026-38361](https://github.com/a1ohadance/CVE-2026-38361)(同一库中的 DoS 漏洞) | ## 描述 `dash_uploader/httprequesthandler.py` 中来自 `request.form.get()` 的三个用户可控参数被直接传递给 `os.path.join()` 和 `os.makedirs()`,期间没有任何清理或验证: 1. **`upload_id`**(第 57 行 → 第 161 行,`BaseHttpRequestHandler.get_temp_root`):控制目标目录。攻击者可以发送 `upload_id=../../../../usr/local/lib/python3.10/site-packages`,文件就会被写入 Python 的包目录中。 2. **`resumableFilename`**(第 51 行 → 第 108 行,`BaseHttpRequestHandler._post`):控制最终的文件名。即使使用了合法的 `upload_id`,攻击者也可以通过文件名遍历出上传目录。 3. **`resumableIdentifier`**(第 54 行 → 第 64 行,`BaseHttpRequestHandler._post`):与 `os.makedirs()` 一起使用来创建临时目录。攻击者可以在文件系统上的任何位置创建任意目录。 上传端点(默认为 `/API/dash-uploader`)不需要身份验证。在 `v0.5.0` 中添加的 `http_request_handler` 钩子允许通过 `post_before()` 进行请求前的检查,但是存在漏洞的 `_post()` 方法是在钩子返回之后,直接从 `request.form` 读取所有参数的。该钩子无法在库处理参数之前对它们进行清理。通过此钩子添加身份验证的开发者,其应用仍然容易受到已认证用户的路径遍历攻击。 ## 漏洞代码 ``` # dash_uploader/httprequesthandler.py def _post(self): resumableFilename = request.form.get("resumableFilename", default="error", type=str) resumableIdentifier = request.form.get("resumableIdentifier", default="error", type=str) upload_id = request.form.get("upload_id", default="", type=str) ... temp_root = self.get_temp_root(upload_id) # upload_id flows in here temp_dir = os.path.join(temp_root, resumableIdentifier) # raw user input -> os.path.join if not os.path.isdir(temp_dir): os.makedirs(temp_dir) # raw user input -> os.makedirs def get_temp_root(self, upload_id): return os.path.join(self.upload_folder, upload_id) # no sanitization: ../../ escapes upload_folder ``` 三个独立的遍历入口点都具有相同的根本原因:表单值在未经任何验证的情况下直接进入了 `os.path.join` 和 `os.makedirs`。 ## 攻击向量 未经身份验证的远程攻击者向该上传端点发送 HTTP POST multipart 请求。通过向 `upload_id` 表单参数注入路径遍历序列(`../`),攻击者可以控制上传文件的目标目录。例如,`upload_id=../../../../usr/local/lib/python3.10/site-packages` 会将文件写入 Python 的包目录,从而在下次解释器启动时通过 `.pth` 自动执行实现 RCE。 此攻击不需要任何身份验证、会话令牌或 CSRF 令牌。另外两个参数(`resumableFilename` 和 `resumableIdentifier`)通过同一个端点提供了独立的遍历攻击向量。正如官方快速入门文档中所述的默认库配置,只需使用一条简单的 `curl` 命令即可对其进行攻击利用。 ## 影响 可以向服务器进程具有写入权限的任何目录写入任意文件。这会通过几种众所周知的原语转化为**远程代码执行 (RCE)**: **RCE 原语** - 将 Python `.pth` 文件放入 `site-packages` 目录。在下次解释器启动时执行攻击者提供的代码。 - `sitecustomize.py` 或 `usercustomize.py` 注入。在每次 Python 启动时执行。 - 覆盖应用程序包目录中可导入的 Python 模块。在下次导入或工作进程回收时执行。 - 覆盖 WSGI/ASGI 入口点(例如 `app.wsgi`、`wsgi.py`)。在下次工作进程重载时执行。 - 在进程具有必要权限时,投放 Cron 任务(`/etc/cron.d/`、`/etc/cron.hourly/`、用户 crontab spool)。计划执行。 - Systemd 单元或用户单元的投放(`/etc/systemd/system/`、`~/.config/systemd/user/`)。在下次服务启动或系统重启时执行。 - 当进程以 root 权限运行时,进行 `/etc/ld.so.preload` 注入。将攻击者代码预加载到随后执行的每个二进制文件中。 - Shell 启动文件覆盖(`~/.bashrc`、`~/.profile`、`~/.bash_profile`)。在应用用户下次交互式登录时执行。 - 追加 `~/.ssh/authorized_keys`。授予攻击者以应用用户身份对主机的持久 SSH 访问权限。 **Web 层影响** - 通过覆盖提供的 JavaScript(例如,位于 `site-packages` 中的 Dash 框架 JS),在宿主域上产生存储型跨站脚本攻击,影响每次页面加载时的每一个用户,直至应用程序重启 - 应用程序源代码覆盖(这是一种隐蔽的、持久的后门,当部署机制没有完全覆盖受影响的路径时,它能在常规部署中存活下来) **文件系统影响** - 通过带有未清理的 `resumableIdentifier` 参数的 `os.makedirs()`,在进程可触及的任何位置创建任意目录(可用于耗尽 inode 或为写入不存在的目录树做准备) - 在共享上传目录中发生跨用户文件替换,导致同一应用程序的不同租户之间的数据投毒 ## 受影响组件 - `dash_uploader/httprequesthandler.py` - `BaseHttpRequestHandler.get_temp_root()` - `BaseHttpRequestHandler._post()` ## 缓解措施 ### ⚠️ 没有可用的补丁,且项目已归档 当前已部署用户的可选方案,按优先顺序排列: 1. **迁移到 `dcc.Upload`**,这是 Plotly Dash 提供的官方上传组件。文件以 base64 字符串的形式到达回调函数;没有公开文件系统写入处理器,也没有客户端控制的目标路径,因此此类漏洞在这里不适用。最适用于中小型文件。对于非常大的文件上传,请参见方案 2。 2. **自建一个小型的 Flask 上传处理器**,使用 `werkzeug.utils.secure_filename()` 和硬编码的服务器端目标目录。绝不能接受客户端提供的 `upload_id`、文件名或标识符值作为路径组件。 3. **如果继续使用 dash-uploader**,请将上传端点置于身份验证之后,并且在库处理器看到请求之前,在重写或拒绝请求的层级上,对照严格的允许列表(例如,仅允许 UUID)验证 `upload_id`、`resumableFilename` 和 `resumableIdentifier`。该库的 `http_request_handler` 钩子并不能阻止这种遍历,因为参数是在钩子返回后从 `request.form` 中读取的;清理必须在库的上层进行。 4. **在反向代理或 WAF 层**,拒绝任何发送到上传端点、且其任何表单字段包含 `..`、编码变体(`%2e%2e`、`..%2f`、`%2e%2e%2f`)或绝对路径的请求。 ## 披露时间线 | 日期 | 事件 | |---|---| | 2026-03-17 | 在对生产部署进行安全研究期间发现了该漏洞。 | | 2026-03-19 | 向 MITRE 提交了 CVE 申请。 | | 2026-05-07 | CVE-2026-38360 由 MITRE 分配。 | | 2026-05-07 | 发布了公开的安全公告。 | | 2026-05-09 | CVE 记录在 [MITRE CVE 数据库](https://www.cve.org/CVERecord?id=CVE-2026-38360) 和 [NVD](https://nvd.nist.gov/vuln/detail/CVE-2026-38360) 上发布。 | ## 包上下文 - 在 PyPI 上每月约有 28,000 次下载(在 2026-05-07 之前的 30 天内为 27,756 次,尽管代码库已归档,但每日下载量仍保持稳定)。来源:[pypistats.org](https://pypistats.org/packages/dash-uploader)。 - 最新发布版本:`0.6.1`(稳定版线)。预发布版本扩展至 `0.7.0a2`。 - 必需依赖:`dash`。可选依赖:`pyyaml`。许可证:MIT。 - 11 个依赖包,6 个依赖代码库。 - 153 个 GitHub Stars。 - 代码库已于 2025-07-19 归档([Issue #153](https://github.com/fohrloop/dash-uploader/issues/153))。 - 无先前的 CVE 记录(已于 2026-03-19 对照 NVD、GitHub Advisory Database、Snyk、OSV 进行验证)。 ## 参考 - https://www.cve.org/CVERecord?id=CVE-2026-38360 - https://nvd.nist.gov/vuln/detail/CVE-2026-38360 - https://github.com/fohrloop/dash-uploader - https://pypi.org/project/dash-uploader/ - https://pypistats.org/packages/dash-uploader - https://github.com/fohrloop/dash-uploader/blob/stable/dash_uploader/httprequesthandler.py - https://github.com/fohrloop/dash-uploader/blob/dev/dash_uploader/httprequesthandler.py - https://github.com/fohrloop/dash-uploader/issues/153 - https://cwe.mitre.org/data/definitions/22.html ## 发现者 Muhammad Fitri Bin Mohd Sultan
标签:CISA项目, CVE-2026-38360, CWE-22, dash-uploader, NVD, PyPI, Python, RCE, Web安全, 严重漏洞, 任意文件写入, 后门, 存储型XSS, 开源项目漏洞, 文件上传漏洞, 无后门, 无身份验证, 漏洞通报, 第三方组件漏洞, 编程工具, 蓝队分析, 路径遍历, 远程代码执行, 逆向工具