تخط إلى المحتوى
English

تلويث النموذج الأولي Prototype Pollution

كيف يكتب مفتاح __proto__ في JSON المدموج على النموذج الأولي المشترك فترث كل الكائنات قيم المهاجم ولماذا تفشل قوائم حظر المفاتيح

المسار
أمن الويب
الوقت المتوقع
25 د
المستوى
متوسط
تقدمك في المسار0%

في جافاسكربت كل كائن عادي يرث من نموذج أولي مشترك وتلويث النموذج الأولي أن تكتب بيانات المهاجم خاصية على ذلك النموذج المشترك بدل كائن واحد فبعدها يبدو أن كل كائن في التطبيق يملك تلك الخاصية وخاصية isAdmin ملوثة واحدة تقلب فحوص الصلاحية في التطبيق كله

في هذه اللابات التلويث محاكى على كائن نموذج أولي بديل فلا يمس النموذج الأولي الحقيقي ولا محرك اللابات والسلوك الذي تراه كائن جديد يرث القيمة المزروعة هو بالضبط ما يفعله التلويث الحقيقي

ما هي الثغرة؟

دمج متكرر ينسخ JSON المستخدم في كائن

merge.js
for (const key in source) {
  if (typeof source[key] === 'object') merge(target[key] ||= {}, source[key]);
  else target[key] = source[key];   // __proto__ يمر مباشرة
}

أرسل proto فيه isAdmin بقيمة true فيكتب الدمج isAdmin على النموذج الأولي وبعدها تصبح الخاصية موجودة في كل كائن جديد

لماذا تحدث؟

الدمج يثق بكل مفتاح والنموذج الأولي يوصل إليه عدة أسماء proto و constructor.prototype فمنع proto وحده يترك constructor مفتوحا وفحص المفاتيح العليا فقط يترك proto متداخلا يلوث عند نزول الدمج

كيف تتوقف؟

تخط المفاتيح الخطرة proto و constructor و prototype في كل عمق لا المستوى العلوي فقط والأفضل تجنب الدمج في كائنات عادية أصلا استخدم Map أو كائنات بلا نموذج أولي عبر Object.create(null) وتحقق من المدخل بمخطط حتى لا تصل المفاتيح غير المتوقعة الدمج

اللابات الثلاثة أدناه تمشي السلم لوث عبر proto وتجاوز حذف proto بـ constructor.prototype وتجاوز الفحص العلوي بمفتاح متداخل

اللابات

  • تلويث عبر الدمج

    سهللاب في المتصفح

    لوث النموذج الأولي لتصبح اللوحة الجديدة لوحة مدير

  • تجاوز منع __proto__

    متوسطلاب في المتصفح

    لوث النموذج الأولي رغم حذف __proto__

  • تلويث عبر مسار متداخل

    صعبلاب في المتصفح

    لوث النموذج الأولي بمفتاح متداخل يتجاوز الفحص العلوي