
Proof-of-concept exploit for CVE-2026-8161, a denial-of-service vulnerability in multiparty multipart parser, demonstrating prototype pollution leading to uncaught exception and crash.
Proof of concept of CVE-2026-8161 (Multiparty)
[email protected] and earlier are vulnerable to denial of service through an uncaught exception.
The parser stores uploaded fields and files in plain JavaScript objects and does not safely distinguish parser owned keys from inherited object properties. A crafted multipart field name can cause the parser to read unexpected prototype-chain values and crash while handling the upload.
Any service that accepts multipart uploads through vulnerable versions of multiparty may be affected.
The issue happens because fields and files are plain JavaScript objects, but they are used like safe key-value maps for user-controlled names.
var fieldsArray = fields[name] || (fields[name] = [])
fieldsArray.push(value)
var filesArray = files[name] || (files[name] = [])
filesArray.push(file)
The issue is that fields[name] and use normal JavaScript property lookup. For plain objects, that lookup can return inherited properties from the prototype chain instead of only values stored on the object itself.
files[name]When name is __proto__, JavaScript can resolve it through the prototype chain and return the inherited prototype object instead of undefined. Since that value is truthy, the fallback assignment is skipped and the parser never creates a real array for that field.
The patch fixes this by only trusting keys that belong directly to the object:
var filesArray = Object.prototype.hasOwnProperty.call(files, name)
? files[name]
: undefined
Then the parser appends only when the stored value is actually an array, otherwise it initializes a fresh one:
if (Array.isArray(filesArray)) {
filesArray.push(file)
} else {
files[name] = [file]
}
When .push() is called on a value that is not an array, it throws a TypeError. Because this happens inside Multiparty’s async parsing flow, normal caller-side error handling may not catch it, allowing the exception to crash the process.
Object.prototype.hasOwnProperty.call(...).Run the mocklab environment and send the test payload to both targets:
docker compose up -d
python3 secdos.py -u http://localhost:8080/api/submit
python3 secdos.py -u http://localhost:8081/api/submit
The vulnerable target will crash and return [PASS]. The patched target will handle the request safely and return [FAIL].
If re-running against the vulnerable server, restart it first
Building a patched image from dockerfile requires a build arg PATCHED=1