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 中的路径遍历漏洞
[](https://www.cve.org/CVERecord?id=CVE-2026-38360)
[](https://nvd.nist.gov/vuln/detail/CVE-2026-38360)
[](https://cwe.mitre.org/data/definitions/22.html)
[](#)
[](#mitigation)
[](#attack-vectors)
[](https://pypi.org/project/dash-uploader/)
[](https://pepy.tech/project/dash-uploader)
[](https://pepy.tech/project/dash-uploader)
[](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, 开源项目漏洞, 文件上传漏洞, 无后门, 无身份验证, 漏洞通报, 第三方组件漏洞, 编程工具, 蓝队分析, 路径遍历, 远程代码执行, 逆向工具