تسلق المسارات (Path Traversal)
كيف يتسلق الرمز ../ في اسم ملف خارج المجلد المقصود ليقرأ أي ملف يصله الخادم ولماذا يفشل حذفه وكيف تحلل المسار ثم تتحقق
- المسار
- أمن الويب
- الوقت المتوقع
- 20 د
- المستوى
- متوسط
قبل هذا الدرس
تسلق المسارات يحدث لما يبني الخادم مسار ملف من اسم تعطيه إياه الرمز ../ يعني اصعد مجلدا للأعلى فبتكراره تخرج من المجلد الذي قصدته الميزة وتصل إلى أي شيء يقدر الخادم قراءته من إعدادات وكود المصدر وملف /etc/passwd الشهير
ما هي الثغرة؟
res.send(fs.readFileSync('/var/www/docs/' + req.query.name, 'utf8'));اطلب welcome.txt فيقرأ /var/www/docs/welcome.txt
واطلب ../../../etc/passwd فيصير المسار:
/var/www/docs/../../../etc/passwd -> /etc/passwdاسمك دمج مع المجلد ورموز ../ مشت للخلف خارجه فيقرأ الخادم ما يقع عليه
ليش تصير؟
الاسم يعامل كجزء من مسار لكنه يأتي من المستخدم والمسارات فيها عامل اصعد مدمج دمج نص المستخدم مع مجلد أساسي يسلم المستخدم ذلك العامل
ليش يفشل الحذف
حذف ../ يبدو بديهيا لكنه قائمة سوداء:
- الحذف مرة واحدة ….// فيها ../ في وسطها فبحذفها يتبقى ../ سليما
- الحذف المتكرر ثم فك الترميز لو حذفت قبل فك ترميز URL فإن %2e%2e%2f المرمزة تنجو من الحذف ثم الترتيب الذي تعمل به العمليات التنظيف قبل فك الترميز يترك حمولة مرمزة تنجو وتصير خطيرة بعد فك الترميز
وتستغل الاثنتين الحذف لمرة واحدة والحذف قبل فك الترميز في اللاب المتوسط والصعب
كيف تنحمى منها
import path from 'node:path';
const base = '/var/www/docs';
const decoded = decodeURIComponent(req.query.name); // decode fully FIRST
const full = path.resolve(base, path.basename(decoded)); // only the file name
if (!full.startsWith(base + path.sep)) return res.status(400).end(); // check AFTER resolving
res.send(fs.readFileSync(full, 'utf8'));لا تنظف المدخل حلل المسار النهائي ثم تحقق أنه داخل المجلد المسموح (الفحص يجب أن يأتي بعد فك الترميز والتحليل) خذ آخر جزء من الاسم (basename) أو الأفضل لا تكشف مسارات الملفات أصلا اربط معرفا بملف معروف في جهة الخادم فلا يوجد مسار يتسلق
اللابات
اسم ملف يتسلق للخارج
محلولسهللاب في المتصفح
اخرج من مجلد المستندات واقرأ ملف /etc/passwd
ادخل اللابمقفلحذف مرة واحدة
محلولمتوسطلاب في المتصفح
اقرأ /etc/passwd مرة أخرى متجاوزا حذف ../
ادخل اللابمقفليحذف ثم يفك الترميز
محلولصعبلاب في المتصفح
اقرأ /etc/passwd رغم الحذف المتكرر مستغلا أن فك الترميز يأتي بعده
ادخل اللابمقفل
