الهوية · فصل ٦

Weak Login و Open Redirect — الباب الأمامي واللينك المزيّف

credential stuffing · brute force · rate limiting · lockout · MFA · Open Redirect · ?next=
🎯 الهدف: تحمي الـ login من التخمين وقوايم الباسوردات المسربة، وتمنع إن لينك على الدومين بتاعك يودّي لموقع مزيّف.

Weak Login: خمّن لحد ما تزبط

المهاجم مش لازم يخمّن عشوائي. الناس بتكرر نفس الباسورد في مواقع كتير، وقوايم الباسوردات المسربة متاحة. فبيجرب الإيميل + الباسورد المسرب على موقعك (اسمها credential stuffing)، أو يجرب أشهر الباسوردات على حسابات كتير.

الحل: طبقات

⏱️ Rate limit

حد للمحاولات لكل IP ولكل حساب. الاتنين مهمين: IP واحد بيجرب على حسابات كتير، أو IPs كتير على حساب واحد.

📱 MFA

TOTP (تطبيق authenticator) أو passkeys. الباسورد المسرب لوحده مبقاش كفاية.

login.js
import rateLimit from "express-rate-limit";const loginLimiter = rateLimit({  windowMs: 15 * 60 * 1000,  limit: 10,                 // 10 محاولات لكل IP كل ربع ساعة  standardHeaders: true,});app.post("/login", loginLimiter, async (req, res) => {  const user = await findUserByEmail(req.body.email);  const ok = user && (await argon2.verify(user.passwordHash, req.body.password));  if (!ok) {    await recordFailedAttempt(req.body.email);   // عدّاد لكل حساب + تأخير متزايد    return res.status(401).json({ error: "الإيميل أو الباسورد غلط" });  }
...
});

Open Redirect: لينك بدومينك يودّي لموقع مزيّف

بعد الـ login بنرجّع المستخدم للصفحة اللي كان فيها: /login?next=/dashboard. لو السيرفر بيعمل redirect لأي قيمة، المهاجم يبعت لينك زي yoursite.com/login?next=https://evil.example. الإيميل فيه دومين حقيقي، المستخدم يعمل login، ويتحوّل لصفحة شبه موقعك تطلب منه الباسورد تاني.

login.js
// ❌ أي قيمةres.redirect(req.query.next);

الحل: relative paths بس، أو allow-list

safeRedirect.js
export function safeNext(next) {  // لازم يبدأ بـ / ومينفعش // أو /\ (دول بيتفهموا كدومين تاني)  if (typeof next !== "string" || !next.startsWith("/") || next.startsWith("//") || next.startsWith("/\\")) {    return "/";  }  return next;}res.redirect(safeNext(req.query.next));

خلّصت الفصل لما

🧠 اختبر نفسك
١) عملت rate limit لكل IP بس. إيه اللي فاتك؟
هجوم من IPs كتير (botnet) على نفس الحساب. لازم حد لكل حساب كمان.
٢) ليه open redirect خطر مع إنه مش بيسرق حاجة لوحده؟
عشان اللينك بدومينك الحقيقي، فالمستخدم بيثق فيه ويروح لصفحة phishing.
٣) القيمة //evil.example بتبدأ بـ / . آمنة؟
لأ. المتصفح بيفهم // كـ URL لدومين تاني. ارفضها.