هجمات الدخول و Password Reset
صفحة الـ login أكتر صفحة بتتهاجم في أي موقع، و"نسيت الباسورد" هي الباب الخلفي الرسمي للحساب. الدرس ده بيوريك الهجمات زي ما بتظهر في الـ logs، وبيبنيلك حماية من غير ما تأذي المستخدم الحقيقي.
- تفرّق بين Brute Force و Credential Stuffing و Password Spraying من البصمة
- تصمم Rate Limiting على أكتر من مفتاح، وتعرف ليه الـ Lockout ممكن يبقى سلاح
- تقفل User Enumeration في 4 أماكن، ومنها التوقيت
- تصمم Password Reset آمن، وتفهم تأكيد الإيميل والـ Signed URLs
1. هجمات التخمين
صفحة الـ login أكتر صفحة بتتهاجم في أي موقع. وفيه 3 هجمات شبه بعض، بس كل واحد ليه بصمة مختلفة في الـ logs، وعشان كده ليه حماية مختلفة. اتفرج على الشكل بتاع كل واحد، وبعدين شغّل الـ lockout وجرّب تاني:
| 123456 | Aa123456 | password | qwerty | iloveyou | P@ssw0rd | |
|---|---|---|---|---|---|---|
| ali@ | ||||||
| mona@ | ||||||
| omar@ | ||||||
| heba@ | ||||||
| karim@ | ||||||
| nour@ |
| الهجوم | الفكرة | شكله في الـ logs |
|---|---|---|
| Brute Force | حساب واحد، وآلاف الباسوردات | محاولات فاشلة كتير على إيميل واحد |
| Credential Stuffing | قايمة إيميل وباسورد متسربة من موقع تاني، وتجربها كلها عندك | كل إيميل بيتجرب مرة أو مرتين، من IPs كتير، وفيه نسبة نجاح ملحوظة |
| Password Spraying | باسورد واحد مشهور (زي Aa123456) على آلاف الحسابات |
إيميلات كتير، ومحاولة واحدة لكل إيميل، فمش بيوصل لحد الـ lockout |
Brute Force بيضرب حساب واحد، و Spraying بيضرب حسابات كتير بباسورد واحد، و Stuffing بيجرّب باسوردات صحيحة من تسريبات تانية.
2. Rate Limiting و Lockout
جرّب كل حماية قدام كل نوع هاكر، وخد بالك من عمر الحقيقي اللي على الشمال:
تحدد على أساس إيه؟
| المفتاح | بيوقف | مبيوقفش |
|---|---|---|
| الإيميل + IP | Brute Force من جهاز واحد | نفس الهجوم من 1000 IP |
| IP بس | جهاز واحد بيجرّب حسابات كتير | botnet، وكمان بيضر ناس كتير ورا نفس الـ IP (شركة، جامعة، شبكة موبايل) |
| الإيميل بس | Brute Force من IPs كتير | Spraying |
عشان كده الحل العملي إنك تحط أكتر من حد: واحد على الإيميل + IP، وواحد أوسع على الـ IP لوحده. وفي لارافيل ده بيتعمل بـ RateLimiter::for()، وبيرجّع 429 Too Many Requests ومعاها header اسمه Retry-After.
الـ Lockout سلاح ذو حدين
لو قفلت الحساب بعد 5 محاولات غلط، الهاكر يقدر يقفل حساب أي حد بإنه يكتب إيميله وباسورد غلط 5 مرات. كده إنت عملت بإيدك هجوم DoS على مستخدمينك.
البدائل الأحسن:
- تأخير متزايد: كل محاولة فاشلة تزوّد وقت الانتظار (ثانية، 2، 4، 8…).
- CAPTCHA بعد عدد محاولات معين، بدل القفل.
- تقفل المحاولة من الـ IP ده، مش الحساب كله.
- تبعت إيميل للمستخدم: “فيه محاولات دخول كتير على حسابك”.
حط أكتر من حد على أكتر من مفتاح، وبطّأ المهاجم بدل ما تقفل الحساب، عشان القفل نفسه ممكن يتستخدم سلاح.
3. User Enumeration
ليه دي مشكلة؟ لأن المهاجم بيبدأ بقايمة مليون إيميل، ويطلع منها الـ 20,000 اللي عندهم حساب عندك. وبعدين يركز عليهم بالـ Credential Stuffing، أو يبعتلهم إيميلات phishing مقنعة جداً: “عميل shop-lab العزيز…”.
شغّل السكريبت. وبعدين شغّل الحل الأول بس، وشغّله تاني. وبعدين التاني:
| الرسالة | وقت الرد | الهاكر استنتج |
|---|
| المكان | الرسالة اللي بتسرّب | الرسالة الصح |
|---|---|---|
| الدخول | “الإيميل ده مش مسجل” | “الإيميل أو الباسورد غلط” في الحالتين |
| نسيت الباسورد | “مفيش حساب بالإيميل ده” | “لو الإيميل مسجل عندنا، هيوصلك لينك” |
| التسجيل | “الإيميل ده مستخدم” | دي أصعب واحدة (تحت) |
| الـ Timing | الرد بيرجع أسرع لو الإيميل مش موجود، عشان مفيش bcrypt | اعمل hash وهمي في الحالتين، أو اعتمد على الـ rate limiting |
مشكلة صفحة التسجيل
لو قولت “الإيميل مستخدم”، كشفت الحساب. ولو مقولتش، المستخدم الحقيقي اللي نسي إنه مسجل هيتلخبط. الحل الأمثل إنك تقول “ابعتنالك إيميل تأكيد”، وفي الإيميل نفسه تقوله “إنت عندك حساب أصلاً، ودي لينك تغيير الباسورد”. كده الكشف بيحصل في إيميل صاحب الحساب بس.
ده تمنه تجربة مستخدم أتقل. ومواقع كتير بتقبل الكشف في التسجيل وبتعوّضه بـ rate limiting قوي. المهم إنك تبقى واخد القرار وفاهمه، مش ناسيه.
كل رسالة بتفرّق بين “الحساب موجود” و “مش موجود” هدية للمهاجم، حتى لو الفرق في السرعة بس.
4. نسيت الباسورد (Password Reset)
7 قواعد للـ Reset الآمن
- Token عشوائي وطويل: عشان ميتخمنش. ومش مبني على الوقت ولا الـ user id.
- يتخزن Hash: نفس منطق الباسورد و Sanctum: لو الداتابيز اتسربت، الـ tokens متتستخدمش. لارافيل بيخزنه hash في جدول
password_reset_tokens. - عمره قصير: الإيميلات بتفضل في الـ inbox سنين. الافتراضي في لارافيل 60 دقيقة.
- يتستخدم مرة واحدة: بعد ما الباسورد يتغيّر، الـ token يتمسح.
- اللينك مبني من APP_URL: شوف الهجوم تحت.
- صفحة الـ reset متحمّلش حاجات من برا: الـ token موجود في الـ URL. لو الصفحة فيها صورة أو script من موقع تاني، الـ URL ممكن يتبعتله في الـ
Refererheader. - بعد التغيير اقفل كل حاجة: المستخدم بيغيّر الباسورد غالباً عشان شاك إن حد دخل. فاطرد كل الـ sessions التانية، وامسح الـ tokens، وغيّر الـ remember token، وابعتله إيميل “الباسورد اتغيّر”.
Host Header Injection
لو اللينك مبني من الـ Host header اللي في الـ request، اتفرج إيه اللي يحصل:
دوس ▶ شغّل، أو امشي خطوة خطوة بالأسهم.
الحل إن اللينك يتبني من إعداد ثابت زي APP_URL، مش من أي حاجة جاية في الـ request.
ولارافيل بيطبق معظم ده لوحده من خلال الـ Password Broker، ومعاه throttle افتراضي بيمنع إنك تطلب reset أكتر من مرة كل 60 ثانية.
الـ Reset هو الباب الخلفي للحساب: token عشوائي، متخزن hash، عمره قصير، لمرة واحدة، وبعده تطرد الكل.
5. تأكيد الإيميل و Signed URLs
ليه مهم أمنياً، مش بس عشان الـ spam؟
دوس ▶ شغّل، أو امشي خطوة خطوة بالأسهم.
لو الموقع كان مستني تأكيد الإيميل قبل ما يعتبره صحيح، الهجوم ده كان مات.
Signed URLs
لينك التأكيد في لارافيل فيه signature، وده HMAC للـ URL كله بالـ APP_KEY، وده نفس فكرة توقيع الـ JWT اللي في المرحلة التانية. لو حد غيّر الـ 7 لـ 8 أو مدّ الـ expires، التوقيع يبوظ والطلب يترفض بـ 403. ومن غير ما تخزن أي حاجة في الداتابيز. جرّب:
………وتقدر تستخدم نفس الفكرة في حاجات تانية في المتجر: لينك “ألغي اشتراكي في النشرة”، أو لينك تحميل فاتورة صالح لساعة.
متثقش في إيميل قبل ما صاحبه يأكده، والـ Signed URL بيخليك تبعت لينك محدش يقدر يعدّله من غير ما تخزن حاجة.
أسئلة الإنترفيو
فكّر في إجابتك الأول، وبعدين افتح السؤال.
01الفرق بين Brute Force و Credential Stuffing و Password Spraying؟
Brute Force: باسوردات كتير على حساب واحد. Credential Stuffing: إيميلات وباسوردات متسربة من مواقع تانية بتتجرب عندك، وأخطرهم لأن الباسوردات صح. Spraying: باسورد واحد مشهور على حسابات كتير، فمبيوصلش لحد الـ lockout.
02إيه مشكلة الـ Account Lockout؟
المهاجم يقدر يقفل حساب أي حد بإنه يكتب باسورد غلط كام مرة، فبيبقى DoS على المستخدمين. البدائل: تأخير متزايد، و CAPTCHA بعد عدد محاولات، وإنك تقفل الـ IP مش الحساب، و rate limit على أكتر من مفتاح.
03يعني إيه User Enumeration، وفين بيحصل؟
إن الموقع يكشف هل إيميل معين عنده حساب. بيحصل في رسايل الدخول، و"نسيت الباسورد"، والتسجيل، وفرق السرعة في الرد. الحل رسالة واحدة في الحالتين، وhash وهمي أو rate limiting للـ timing، وفي التسجيل تبعت إيميل بدل ما تقول "الإيميل مستخدم".
04صمم Password Reset آمن.
Token عشوائي طويل، يتخزن hash، عمره ساعة تقريباً، يتستخدم مرة واحدة. اللينك مبني من APP_URL مش من الـ Host header. رسالة واحدة لو الإيميل موجود أو لأ، و rate limit. وبعد التغيير أطرد كل الـ sessions والـ tokens، وأبعت إيميل تنبيه.
05إيه هو Host Header Injection في الـ Password Reset؟
لو لينك الـ reset مبني من الـ Host header، الهاكر يطلب reset لإيميل الضحية بـ Host مزوّر، فالضحية يوصلها إيميل حقيقي فيه لينك لموقع الهاكر. لما تدوس، الـ token يروحله. الحل إن اللينك يتبني من إعداد ثابت زي APP_URL.
06إيه هو الـ Signed URL؟
لينك فيه توقيع HMAC للـ URL كله بسر السيرفر، وغالباً معاه تاريخ انتهاء. أي تعديل في الـ URL بيبوّظ التوقيع. بيتستخدم في تأكيد الإيميل ولينكات التحميل المؤقتة، من غير ما تخزن حاجة في الداتابيز.