
CVE-2026-8161の概念実証エクスプロイト。multiparty multipartパーサーにおけるサービス拒否(DoS)の脆弱性であり、プロトタイプ汚染が未捕捉の例外とクラッシュを引き起こすことを実証します。
CVE-2026-8161(Multiparty)の概念実証
[email protected] 以前のバージョンは、捕捉されない例外によるサービス拒否(DoS)に対して脆弱です。
パーサーはアップロードされたフィールドとファイルをプレーンな 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 が必要です