
Preuve de concept d'exploitation pour CVE-2026-8161, une vulnérabilité de déni de service dans l'analyseur multipart multiparty, démontrant une pollution de prototype conduisant à une exception non interceptée et à un crash.
Preuve de concept de la CVE-2026-8161 (Multiparty)
[email protected] et versions antérieures sont vulnérables à un déni de service via une exception non interceptée.
L'analyseur stocke les champs et fichiers téléversés dans des objets JavaScript simples et ne distingue pas de manière sûre les clés appartenant à l'analyseur des propriétés héritées de l'objet. Un nom de champ multipart malveillant peut amener l'analyseur à lire des valeurs inattendues de la chaîne de prototypes et à planter lors du traitement du téléversement.
Tout service qui accepte des téléversements multipart via des versions vulnérables de multiparty peut être affecté.
Le problème vient du fait que fields et files sont des objets JavaScript simples, mais qu'ils sont utilisés comme des mappages clé-valeur sûrs pour des noms contrôlés par l'utilisateur.
var fieldsArray = fields[name] || (fields[name] = [])
fieldsArray.push(value)
var filesArray = files[name] || (files[name] = [])
filesArray.push(file)
Le problème est que fields[name] et files[name] utilisent une recherche de propriété JavaScript normale. Pour les objets simples, cette recherche peut renvoyer des propriétés héritées de la chaîne de prototypes au lieu de uniquement les valeurs stockées sur l'objet lui-même.
Lorsque le nom est __proto__, JavaScript peut le résoudre via la chaîne de prototypes et renvoyer l'objet prototype hérité au lieu de undefined. Comme cette valeur est évaluée comme vraie, l'assignation de repli est ignorée et l'analyseur ne crée jamais un véritable tableau pour ce champ.
Le correctif résout ce problème en ne faisant confiance qu'aux clés qui appartiennent directement à l'objet :
var filesArray = Object.prototype.hasOwnProperty.call(files, name)
? files[name]
: undefined
Ensuite, l'analyseur n'ajoute que lorsque la valeur stockée est réellement un tableau, sinon il en initialise un nouveau :
if (Array.isArray(filesArray)) {
filesArray.push(file)
} else {
files[name] = [file]
}
Lorsque .push() est appelé sur une valeur qui n'est pas un tableau, il lève une TypeError. Comme cela se produit dans le flux d'analyse asynchrone de Multiparty, la gestion d'erreur normale côté appelant peut ne pas l'intercepter, permettant à l'exception de faire planter le processus.
Object.prototype.hasOwnProperty.call(...).Lancez l'environnement mocklab et envoyez la charge utile de test aux deux cibles :
docker compose up -d
python3 secdos.py -u http://localhost:8080/api/submit
python3 secdos.py -u http://localhost:8081/api/submit
La cible vulnérable plantera et renverra [PASS]. La cible corrigée gérera la requête en toute sécurité et renverra [FAIL].
Si vous relancez contre le serveur vulnérable, redémarrez-le d'abord
La construction d'une image corrigée à partir du dockerfile nécessite un argument de build PATCHED=1