
إثبات مفهوم لاستغلال CVE-2026-8161، وهي ثغرة رفض خدمة في محلل multipart متعدد الأطراف، توضح تلوث النموذج الأولي المؤدي إلى استثناء غير مُلتقط وتعطل النظام.
إثبات المفهوم لـ CVE-2026-8161 (Multiparty)
[email protected] والإصدارات الأقدم معرّضة لهجوم حجب الخدمة (Denial of Service) من خلال استثناء غير مُلتقَط (uncaught exception).
يخزّن المحلّل (parser) الحقول والملفات المرفوعة في كائنات JavaScript عادية ولا يميّز بأمان المفاتيح المملوكة للمحلّل عن الخصائص الموروثة للكائن. يمكن أن يتسبب اسم حقل متعدد الأجزاء (multipart field name) مُصمَّم بعناية في قراءة المحلّل لقيم غير متوقعة من سلسلة النماذج الأولية (prototype chain) وتعطّله أثناء معالجة الرفع.
قد تتأثر أي خدمة تقبل رفع ملفات متعددة الأجزاء عبر إصدارات multiparty المعرّضة للخطر.
تحدث المشكلة لأن fields و files كائنات JavaScript عادية، لكنها تُستخدم كخرائط آمنة من مفتاح-قيمة لأسماء يتحكم بها المستخدم.
var fieldsArray = fields[name] || (fields[name] = [])
fieldsArray.push(value)
var filesArray = files[name] || (files[name] = [])
filesArray.push(file)
المشكلة أن fields[name] و يستخدمان البحث العادي عن الخصائص في JavaScript. بالنسبة للكائنات العادية، يمكن أن يُرجع هذا البحث خصائص موروثة من سلسلة النماذج الأولية بدلاً من القيم المخزنة على الكائن نفسه فقط.
files[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. ولأن هذا يحدث داخل تدفق المعالجة غير المتزامن (async) في 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