
البحث في الثغرة CVE-2023-26136
البحث في الثغرة CVE-2023-26136
الإصدارات من الحزمة tough-cookie قبل 4.1.3 معرضة لتلوث النموذج الأولي (Prototype Pollution) بسبب المعالجة غير الصحيحة لملفات تعريف الارتباط (Cookies) عند استخدام CookieJar في وضع rejectPublicSuffixes=false. تنشأ هذه المشكلة من طريقة تهيئة الكائنات.
https://nvd.nist.gov/vuln/detail/CVE-2023-26136
تمتلك JavaScript مفهوم الكائنات (objects)، الذي يشبه إلى حد ما القواميس (dictionaries). يمكن للكائن أن يحمل مجموعة من المتغيرات من أنواع مختلفة (مثل string, Boolean, int إلخ)، واسم المتغير هو المفتاح (key)، وقيمته هي القيمة (value)، إذا تابعنا تشبيه القواميس والكائنات. بشكل أدق، الكائن هو مماثل لبنية بيانات القاموس نفسها، وكل متغير هو مماثل لزوج مفتاح-قيمة. تحتوي الكائنات أيضًا على الكلمة المفتاحية proto التي تتيح إضافة متغيرات إضافية إلى كائن عن طريق تعديل نموذجه الأولي (prototype). تلوث النموذج الأولي (Prototype Pollution) هو هجوم يقوم فيه المهاجم بتلويث كائنه، عن طريق إضافة متغيرات إضافية إليه، عبر الكلمة المفتاحية proto. التفاعل التالي مع وحدة تحكم المتصفح يوضح الهجوم.
كما نرى، لدينا مستخدمان: admin1 و user1. كائن admin1 يحتوي على متغير منطقي: "isAdmin"، مضبوط على true. user1 لا يمتلك هذا المتغير إطلاقًا. في السطر 7، نضيف متغير isAdmin إلى النموذج الأولي لـ user1، وعلى الرغم من أنه واضح من السطر 10 أن المتغير لم يُضف إلى كائن user1 نفسه، إلا أن وحدة التحكم تستجيب بشكل إيجابي، هذه المرة، عندما نتحقق من قيمة user1.isAdmin. ذلك لأن user1 يرث خصائص نموذجه الأولي.
من الجدير بالذكر أيضًا أن النموذج الأولي هو كائن بذاته، وهو بدوره يرث خصائص وطرقًا من نموذجه الأولي، مما ينشئ سلسلة النماذج الأولية. تنتهي السلسلة بنموذج أولي فارغ (null prototype)، لذلك فإن النهج المعقول لمنع تلوث النموذج الأولي هو جعل الكائن الذي نعمل معه يرث صراحةً من نموذج أولي فارغ.
ملفات تعريف الارتباط (المعروفة غالبًا بملفات تعريف الارتباط على الإنترنت) هي ملفات نصية تحتوي على أجزاء صغيرة من البيانات — مثل اسم المستخدم وكلمة المرور — تُستخدم لتحديد جهاز الكمبيوتر الخاص بك أثناء استخدامك للشبكة. تُستخدم ملفات تعريف ارتباط محددة لتحديد مستخدمين معينين وتحسين تجربة تصفحهم على الويب.
بإذن من Kaspersky: https://www.kaspersky.com/resource-center/definitions/cookies
CookieJar هو كائن لتخزين ملفات تعريف الارتباط.
وفقًا لوصف الثغرة، تنشأ من الطريقة التي يقوم بها Tough-Cookie بتهيئة ملفات تعريف الارتباط. نظرًا لأن ملفات تعريف الارتباط هي كائنات، فهي، نظريًا على الأقل، عرضة لتلوث النموذج الأولي.
من خلال القدرة على العبث بالكائنات وخصوصًا ملفات تعريف الارتباط، عبر النموذج الأولي للكائن، يمكن للمهاجم محتملاً الوصول إلى بيانات غير مصرح بها، تنفيذ كود عن بُعد، التسبب في رفض الخدمة، اختطاف الجلسة إذا كان الموقع يعتمد على ملفات تعريف الارتباط لإدارة الجلسة، واستخراج بيانات حساسة من ملفات تعريف الارتباط نفسها.
تم التصحيح في الملف: memstore.js. وفقًا لتتبع المشكلة وكذلك للتصحيح الذي تم تقديمه في الإصدار 4.1.3، من أجل تصحيح الثغرة، نحتاج إلى تخزين ملفات تعريف الارتباط في خريطة (map) أو إنشاء كائن this.idx. عن طريق إنشاء this.idx باستخدام: this.idx = Object.create(null); بدلاً من this.idx = {}، نطبق اقتراحي حول كيفية منع تلوث النموذج الأولي في المقدمة، عن طريق الوراثة من نموذج أولي فارغ، وقطع سلسلة النماذج الأولية.
نشرت Snyk إثبات المفهوم (PoC) للثغرة التي نوقشت. بنيت index.js بناءً عليه. غلفته بمنطق try-catch لالتقاط الاستثناءات في حالة ظهورها، وأضفت مخرجات إضافية لتتبع تقدم الاختبار، وانتهيت بالمخرجات المطلوبة (مثل "EXPLOITED SUCCESSFULLY" أو "EXPLOITED FAILED"). عند تشغيل الأمر: npm install [email protected] && node index.js نحصل على المخرجات التالية:
عند تشغيل الأمر: npm install ./tough-cookie-2.5.0-PATCHED.tgz && node index.js نحصل على المخرجات التالية:
في كلا السيناريوهين (التشغيل بالإصدار المنشور 2.5.0 والتشغيل بالإصدار المصحح خاصتي)، تمكنا من تعيين كل من ملف تعريف الارتباط العادي وملف تعريف الارتباط المستغل، ولكن في الإصدار المصحح، فشلنا في الوصول إلى ملف تعريف الارتباط المستغل.
في هذه المهمة تعلمت عن هجوم تلوث النموذج الأولي (Prototype Pollution)، وتعلمت عن كائن JavaScript، وتعرفت على حزمة Tough-Cookie.