سطح الهجوم: الطلب والاستجابة بعين المهاجم
من أين يدخل المهاجم؟ من كل حقل في الطلب. فأين يكون التحقق؟ ⏱ نحو 35 دقيقة.
- تحلّل الطلب والاستجابة بعين المهاجم.
- تعدّد مصادر المدخلات وتعرف أنها كلها غير موثوقة.
- تميّز الحدود الموثوقة من غير الموثوقة.
- تختار رمز الحالة المناسب لكل موقف أمني.
١كل تطبيق ويب حوار من طلب واستجابة
درست في مقرر أطر الويب كيف يرد الخادم على الطلبات. الأمن يبدأ بإعادة النظر في الصورة نفسها بعين المهاجم: كل جزء من الطلب يكتبه المُرسِل، وقد لا يكون متصفحًا عاديًّا.
المهاجم لا يحتاج متصفحك ولا واجهتك. يرسل الطلب مباشرة بأداة سطر أوامر، فيضع في كل حقل ما يشاء. القاعدة الذهبية في أمن الويب كلها فرع عن هذه الجملة: لا تثق بأي شيء يأتي من العميل.
٢من أين تأتي المدخلات؟
جرّب هذا الخادم: يردّ لك بما استقبله من كل مصدر. انظر كيف أن قيمة الاستعلام والترويسة والجسم كلها قابلة لأن يضع فيها المرسل أي شيء:
const express = require('express');const app = express();app.use(express.json());app.use(express.urlencoded({ extended: false })); app.get('/echo', (req, res) => { res.json({ path: req.path, query: req.query, // ما بعد ؟ في الرابط userAgent: req.headers['user-agent'], language: req.headers['accept-language'], });}); app.post('/order', (req, res) => { res.json({ received: req.body }); // جسم الطلب كما أرسله العميل}); app.listen(3000);
لاحظ الطلب الثاني: أرسل العميل price=0. لو اعتمد الخادم هذا السعر لاشترى بلا مقابل. المدخل من العميل، فلا يُوثق به.
| مصدر المدخل | المثال | يتحكم به المهاجم؟ |
|---|---|---|
| معامل المسار | /user/42 | نعم: يجرّب 43 و 44… |
| سلسلة الاستعلام | ?sort=price | نعم |
| جسم الطلب | { "price": 0 } | نعم |
| الترويسات | User-Agent, Cookie | نعم؛ تُزوَّر بسهولة |
| رقم الحالة ورموز الخادم | — | لا؛ يصنعها خادمك |
٣رموز الحالة بعين الأمن
ردّ الخادم يحمل رمز حالة، وله معنى أمني: ماذا تخبر به المهاجم؟
| الرمز | المعنى | ملحوظة أمنية |
|---|---|---|
200 | نجح | — |
400 | طلب خاطئ | للمدخلات غير الصالحة |
401 | لم تُصادَق | سجّل الدخول أولًا |
403 | ممنوع | مصادَق لكن بلا صلاحية |
404 | غير موجود | يُستخدم أحيانًا بدل 403 لإخفاء وجود المورد |
429 | طلبات كثيرة | تحديد المعدل ضد التخمين (الدرس 13) |
الفرق بين 401 و 403 و 404 سيعود كثيرًا: أحيانًا نردّ 404 عمدًا على مورد موجود لا يملكه الطالب، حتى لا نؤكد له وجوده.
توقّع وتحقّق
المهاجم يرسل الطلب بأداة سطر أوامر. ماذا يستطيع التحكم به؟
التحقق من المدخلات في JavaScript بالمتصفح وحده:
أي رمز يناسب «مصادَق لكن بلا صلاحية»؟
اعتماد price من جسم الطلب يكسر:
الخلاصة
- كل حقول الطلب يتحكم بها المُرسِل: المسار، والاستعلام، والجسم، والترويسات.
- لا تثق بأي مدخل من العميل؛ التحقق مكانه الخادم لا الواجهة.
- المهاجم يرسل الطلب مباشرة بلا متصفح، فيتجاوز كل تحقق في الواجهة.
- رموز الحالة لها معنى أمني: 401 للمصادقة، و 403 للصلاحية، و 404 لإخفاء الوجود.
تحدٍّ تصميمي: خريطة سطح الهجوم
تمهيديأمامك مسار في متجر «رفيق» يعرض ملف العميل ويحدّثه: PATCH /api/customers/:id بجسم فيه الاسم والبريد. حلّل سطح الهجوم بملء الحقول.
- مصادر المدخلات في هذا الطلب (كل مصدر في سطر).
- ما الحقل الذي قد يعبث به المهاجم ولماذا.
- لماذا لا يكفي التحقق في الواجهة.
- أي رمز حالة يُعاد إذا طلب العميل تعديل ملف عميل آخر، ولماذا.
- ثلاثة مصادر مدخلات على الأقل
- ذكر معامل المسار id
- ذكر جسم الطلب
- الحقل الخطر هو المعرّف
- السبب: تجاوز الواجهة
- الرمز 403 أو 404
💡 تلميح 1
💡 تلميح 2
💡 تلميح 3
نموذج واحد من إجابات كثيرة صحيحة.
- مصادر المدخلات (سطر لكل مصدر)
- معامل المسار id: رقم العميل المراد تعديله.
جسم الطلب: الاسم والبريد الجديدان.
ترويسة الهوية (الرمز/الكوكي): لتحديد من المستخدم الحالي. - الحقل الخطر وسببه
- معامل id: قد يضع المهاجم رقم عميل آخر ليعدّل ملفه، فلا بد من التحقق أن الملف يخصّه.
- لماذا لا يكفي التحقق في الواجهة
- لأن المهاجم يرسل الطلب مباشرة بلا متصفح، فيتجاوز أي تحقق مكتوب في JavaScript بالواجهة؛ التحقق يجب أن يكون في الخادم.
- رمز الحالة لتعديل ملف غيره وسببه
- 404: حتى لا نؤكد للمهاجم وجود ملف ذلك العميل؛ أو 403 إن أردنا التصريح بأنه ممنوع.