Ser0n-ath/multiparty-CVE-2026-8161
GitHub: Ser0n-ath/multiparty-CVE-2026-8161
本项目是针对 Node.js `multiparty` 库拒绝服务漏洞(CVE-2026-8161)的 PoC,用于验证因原型链污染导致服务崩溃的问题。
Stars: 0 | Forks: 0
# CVE-2026-8161
CVE-2026-8161 (Multiparty) 的概念验证
# 描述
`multiparty@4.2.3` 及更早版本因未捕获的异常而存在拒绝服务漏洞。
解析器将上传的字段和文件存储在普通 JavaScript 对象中,并且没有安全地将解析器自身的键与继承的对象属性区分开来。精心构造的 multipart 字段名会导致解析器读取到意外的原型链值,并在处理上传时发生崩溃。
任何通过存在漏洞的 multiparty 版本接受 multipart 上传的服务都可能受到影响。
# 工作原理
出现此问题的原因是 `fields` 和 `files` 是普通的 JavaScript 对象,但它们却被当作用户可控名称的安全键值映射来使用。
```
var fieldsArray = fields[name] || (fields[name] = [])
fieldsArray.push(value)
var filesArray = files[name] || (files[name] = [])
filesArray.push(file)
```
问题在于 `fields[name]` 和 `files[name]` 使用了常规的 JavaScript 属性查找机制。对于普通对象,该查找会返回原型链中继承的属性,而不仅仅是对象本身存储的值。
当 name 为 `__proto__` 时,JavaScript 会通过原型链解析它,并返回继承的原型对象而不是 undefined。由于该值为真值,因此会跳过回退赋值操作,并且解析器永远不会为该字段创建真正的数组。
该补丁通过仅信任直接属于对象自身的键来修复此问题:
```
var filesArray = Object.prototype.hasOwnProperty.call(files, name)
? files[name]
: undefined
```
随后,解析器仅在存储的值实际上是数组时才进行追加操作,否则它会初始化一个新数组:
```
if (Array.isArray(filesArray)) {
filesArray.push(file)
} else {
files[name] = [file]
}
```
当对非数组值调用 .push() 时,会抛出 TypeError。由于这发生在 Multiparty 的异步解析流程中,常规的调用方错误处理可能无法捕获它,从而导致异常使进程崩溃。
# 时间线
- 2026-01-12:向 multiparty 维护者报告了漏洞。
- 2026-01-17:报告被接受,修复工作开始。
- 2026-02-14:与 @pillarjs/security-triage 开始了协同审查。
- 2026-02-16:补丁讨论 -> `Object.prototype.hasOwnProperty.call(...)`。
- 2026-03-29:更新了 Advisory 标题和元数据,以反映拒绝服务的影响。
- 2026-04:审查并批准了修复方案。
- 2026-05-08:Advisory 定稿并保留了 CVE-2026-8161。
- 2026-05-11:修复合并到 pillarjs:master 中。
# 演示用法 运行 mocklab 环境并向两个目标发送测试 payload: ``` docker compose up -d python3 secdos.py -u http://localhost:8080/api/submit python3 secdos.py -u http://localhost:8081/api/submit ``` 存在漏洞的目标将崩溃并返回 `[PASS]`。已打补丁的目标将安全地处理请求并返回 `[FAIL]`。 # 设置概述 ### 存在漏洞的服务器 - 访问地址为 localhost:8080 - Nginx 服务器作为反向代理,在失败时显示状态为 502 的错误页面 - Nginx 通过服务名称解析存在漏洞的服务器地址 - 使用 multiparty 4.2.3(存在漏洞) ### 已打补丁的服务器 - 运行并访问于 localhost:8081 - 不需要 Nginx - 使用 multiparty 4.3.0(已打补丁) 通过 dockerfile 构建打补丁的镜像时,需要构建参数 `PATCHED=1` ## 参考资料 https://github.com/pillarjs/multiparty/security/advisories/GHSA-qxch-whhj-8956 https://github.com/pillarjs/multiparty/commit/8ee6aca09aca29e923da48da8260c87aa964b282
# 演示用法 运行 mocklab 环境并向两个目标发送测试 payload: ``` docker compose up -d python3 secdos.py -u http://localhost:8080/api/submit python3 secdos.py -u http://localhost:8081/api/submit ``` 存在漏洞的目标将崩溃并返回 `[PASS]`。已打补丁的目标将安全地处理请求并返回 `[FAIL]`。 # 设置概述 ### 存在漏洞的服务器 - 访问地址为 localhost:8080 - Nginx 服务器作为反向代理,在失败时显示状态为 502 的错误页面 - Nginx 通过服务名称解析存在漏洞的服务器地址 - 使用 multiparty 4.2.3(存在漏洞) ### 已打补丁的服务器 - 运行并访问于 localhost:8081 - 不需要 Nginx - 使用 multiparty 4.3.0(已打补丁) 通过 dockerfile 构建打补丁的镜像时,需要构建参数 `PATCHED=1` ## 参考资料 https://github.com/pillarjs/multiparty/security/advisories/GHSA-qxch-whhj-8956 https://github.com/pillarjs/multiparty/commit/8ee6aca09aca29e923da48da8260c87aa964b282
标签:CMS安全, CVE-2026-8161, DoS, GNU通用公共许可证, JavaScript, MITM代理, Multiparty, Node.js, PoC, Web安全, 原型链污染, 开源组件漏洞, 异常崩溃, 拒绝服务, 数据可视化, 文件上传漏洞, 暴力破解, 网络安全, 蓝队分析, 请求拦截, 逆向工具, 配置错误, 隐私保护