ثغرات رفع الملفات (File Upload)
كيف تتحول ميزة الرفع إلى تنفيذ شيفرة عن بعد ولماذا تكسر قوائم منع الامتدادات وفحص توقيع الملف وكيف تخزن الملفات المرفوعة بأمان
- المسار
- أمن الويب
- الوقت المتوقع
- 25 د
- المستوى
- متوسط
قبل هذا الدرس
ميزة الرفع تأخذ ملفا من المستخدم وتحفظه الخطر بسيط: لو حفظ الملف في مكان ينفذه الخادم وكان فيه شيفرة خادم فرفعه هو تنفيذ شيفرة على الخادم web shell تحكم كامل معظم ثغرات الرفع فحص ضعيف يقف بين المهاجم وهذي النتيجة
ما هي الثغرة؟
fs.writeFileSync('/var/www/uploads/' + req.file.name, req.file.data);الملف يحفظ باسم المستخدم في مجلد يخدمه خادم الويب
ارفع shell.php فيه <?php system($_GET["c"]); ?> ثم اطلب /uploads/shell.php?c=... فينفذ الخادم أمرك
صار رفع الصورة صدفة
ليش تفشل الفحوص المعتادة
- بلا فحص أي شيء يمر وهذي الحالة السهلة
- قائمة سوداء للامتداد امنع .php فيبقى الخادم ينفذ phtml و php5 و phar و jsp قائمة الامتدادات التنفيذية دائما ناقصة
- توقيع الملف مع امتداد النهاية اطلب أن يبدأ المحتوى بتوقيع صورة وأن ينتهي الاسم بـ .jpg فملف ملف صالح كصيغتين في وقت واحد هنا ترويسة GIF حقيقية متبوعة بشيفرة خادم فيمر فحص الصورة ومع ذلك ينفذ كشيفرة يبدأ بـ GIF89a ويحمل شيفرة بعده والامتداد المزدوج shell.php.jpg يمر فحص النهاية بينما خادم مضبوط خطأ ينفذه كـ PHP
وتمشي على الثلاث حالات بلا فحص ومنع .php وحالة التوقيع مع الامتداد المزدوج في اللابات الثلاثة
كيف تنحمى منها
const ALLOW = new Set(['png', 'jpeg']);
if (!isRealImage(data)) return res.status(400).end(); // decode it, do not trust magic alone
const name = randomId() + '.' + typeFor(data); // our name and extension, not the user's
fs.writeFileSync('/srv/blobs/' + name, data); // outside the web root, never executedأعد تسمية كل ملف مرفوع باسم عشوائي بامتداد تختاره أنت ولا تبق اسم المستخدم ولا امتداده خزن المرفوعات خارج جذر الويب (أو في تخزين كائنات) وقدمها عبر معالج لا يقدر ينفذ شيفرة تحقق من النوع بقائمة بيضاء وبفك المحتوى فعلا لا بالثقة بتوقيع أو نهاية اسم واضبط مجلد الرفع ألا ينفذ شيئا وأزل الامتدادات المزدوجة
اللابات
رفع بلا فحص
محلولسهللاب في المتصفح
ارفع ملف شيفرة خادم (web shell) ينفذ على الخادم
ادخل اللابمقفليمنع امتدادا واحدا
محلولمتوسطلاب في المتصفح
ارفع web shell ينفذ رغم منع .php
ادخل اللابمقفليفحص المحتوى والامتداد
محلولصعبلاب في المتصفح
ارفع web shell يمر من فحص المحتوى والامتداد ومع ذلك ينفذ
ادخل اللابمقفل
