CVE-2026-8161(Multiparty)的概念验证
[email protected] 及更早版本容易受到未捕获异常导致的拒绝服务攻击。
解析器将上传的字段和文件存储在普通 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。由于该值是 truthy,因此会跳过回退赋值,解析器永远不会为该字段创建真正的数组。
该补丁通过只信任直接属于对象的键来修复此问题:
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 的异步解析流程内部,调用方的常规错误处理可能无法捕获它,从而允许异常导致进程崩溃。
Object.prototype.hasOwnProperty.call(...)。运行 mocklab 环境并将测试载荷发送到两个目标:
docker compose up -d
python3 secdos.py -u http://localhost:8080/api/submit
python3 secdos.py -u http://localhost:8081/api/submit
易受攻击的目标将崩溃并返回 [PASS]。已修补的目标将安全地处理请求并返回 [FAIL]。
如果针对易受攻击的服务器重新运行,请先重启它
从 dockerfile 构建已修补镜像需要构建参数 PATCHED=1