لوحة تحكم الغربان تتيح للزعيم تغيير بريده الاحتياطي الصفحة تقبل الطلب بناء على كوكي الجلسة فقط لا يوجد أي رمز إضافي الزعيم مسجل دخوله دائما والصقر يريد أن يضع بريده هو مكان بريد الزعيم ليستولي على الحساب
لوحة تحكم الغربان تطبيق على المضيف panel.ravens.lab يغير فيه الزعيم بريده الاحتياطي الصفحة تقبل الطلب بناء على كوكي الجلسة وحده بلا أي رمز إضافي أنت تختار طريقة توصيل الطلب المزور من صفحة المهاجم نموذج يرسل تلقائيا POST أو صورة تحمل رابطا GET أو رابط يفتحه الزعيم بنفسه GET والتطبيق يوضح هل أرفق المتصفح كوكي الجلسة ولماذا
لماذا نجح الحل
هذا CSRF طلب مزور عبر المواقع الصفحة وثقت بكوكي الجلسة وحده والمتصفح يرفق الكوكي تلقائيا مع أي طلب للوحة فأي موقع يقدر يرسل طلبا باسم الزعيم الحل: رمز CSRF فريد لكل جلسة يرسل مع كل طلب يغير حالة ويتحقق منه في الخادم والمهاجم لا يقدر قراءته لأنه على موقع آخر وأضف SameSite=Lax أو Strict على كوكي الجلسة
السبب الجذري
الخادم يثق بكوكي الجلسة وحده لإثبات نية المستخدم والكوكي يرفق تلقائيا مع الطلبات عبر المواقع فلا شيء يثبت أن الطلب بدأ من صفحة الموقع نفسه
كيف يصلح الكود
الكوكي يرفق تلقائيا وهذا ما يجعل CSRF ممكنا الرمز السري يكسر هذا لأنه ليس كوكي ولا يرفق تلقائيا ولا يقدر موقع آخر قراءته
الكود المصاب
app.post('/settings', (req, res) => {
// Trusts the session cookie alone: any site can trigger this.
if (!req.session.user) return res.status(401).end();
db.setRecoveryEmail(req.session.user, req.body.email);
res.end('updated');
});
الكود الآمن
app.post('/settings', (req, res) => {
if (!req.session.user) return res.status(401).end();
// A per-session token the attacker on another site cannot read.
if (req.body.csrf !== req.session.csrfToken) return res.status(403).end();
db.setRecoveryEmail(req.session.user, req.body.email);
res.end('updated');
});
// Cookie: Set-Cookie: session=...; SameSite=Lax; HttpOnly; Secure
الأثر في الواقع
CSRF يسمح بتنفيذ أفعال باسم الضحية تغيير بريد تحويل أموال تغيير إعدادات بمجرد أن تفتح الضحية صفحة المهاجم وقد أدى لاستيلاء كامل على حسابات
كيف يكتشفها المدافعون
المدافع يفحص رأس Origin و Referer على الطلبات التي تغير الحالة ويرصد طلبات تغيير بلا رمز CSRF صالح