CSRF (Cross-Site Request Forgery)
كيف يجعل موقع خبيث متصفحك يرسل طلبا موثوقا يغير حالة إلى موقع آخر أنت مسجل دخوله وكيف يوقفه الرمز و SameSite
- المسار
- أمن الويب
- الوقت المتوقع
- 25 د
- المستوى
- متوسط
قبل هذا الدرس
CSRF هجوم يستغل شيئا يفعله المتصفح من أجلك: يرفق كوكياتك مع كل طلب يذهب لموقع بغض النظر عن الصفحة التي بدأت الطلب فإذا كنت مسجلا في موقع ثم فتحت صفحة المهاجم تقدر هذي الصفحة تجعل متصفحك يرسل طلبا للموقع المسجل فيه والموقع يرى كوكي الجلسة فيعاملك أنت
ما هي الثغرة؟
لنقل أن لوحة تحكم تغير بريدك الاحتياطي بهذا الطلب:
POST /settings HTTP/1.1
Host: panel.example
Cookie: session=abc123
[email protected]المهاجم يبني صفحة تجعل متصفحك أنت يرسل نفس الطلب إلى panel.example:
<form action="https://panel.example/settings" method="POST">
<input type="hidden" name="email" value="[email protected]">
</form>
<script>document.forms[0].submit();</script>تفتح هذي الصفحة وأنت مسجل دخولك
المتصفح يرفق كوكي session تلقائيا واللوحة ترى جلسة صحيحة فتغير بريدك الاحتياطي إلى بريد المهاجم وهي أول خطوة للاستيلاء على حسابك
وأنت ما ضغطت على شيء مهم
ليش تصير؟
الكوكيات يرسلها المتصفح مع كل طلب للموقع المطابق بدون أي تدخل من الصفحة أو المستخدم المتصفح يرسلها تلقائيا والخادم الذي يقرر هل هذا الطلب مسموح بالاعتماد على الكوكي وحده لا يقدر يفرق بين طلب قصده المستخدم وطلب صنعته صفحة المهاجم نيابة عنه الاثنان يبدوان متطابقين
كيف تنحمى منها
- رمز CSRF الخادم يضع قيمة عشوائية فريدة لكل جلسة في صفحاته ويطلبها مع كل طلب يغير حالة والمهاجم على موقع آخر لا يقدر قراءة هذي القيمة (سياسة المصدر الواحد تمنعه) فلا يقدر إرفاقها
- كوكيات SameSite قيمة
SameSite=Laxتخبر المتصفح أن لا يرفق الكوكي مع معظم طلبات المواقع الأخرى وSameSite=Strictيمنعه عنها كلها - أبق تغييرات الحالة بعيدة عن GET طلب
GETيجب أن يقرأ فقط فإذا غير شيئا فرابط أو صورة بسيطة تقدر تشغله وSameSite=Laxما زال يسمح بالكوكي عند التنقل العلوي بطلب GET
app.post('/settings', (req, res) => {
if (!req.session.user) return res.status(401).end();
if (req.body.csrf !== req.session.csrfToken) return res.status(403).end();
db.setRecoveryEmail(req.session.user, req.body.email);
res.end('updated');
});
// Set-Cookie: session=...; SameSite=Lax; HttpOnly; SecureXSS و CSRF قريبان لكن متعاكسان XSS يشغل شيفرة المهاجم على الموقع فيقدر يقرأ الرمز ويهزم دفاعات CSRF و CSRF لا يشغل شيفرة على الموقع بل يجعل المتصفح يرسل طلبا فقط أصلح XSS أولا فالرمز لا يحمي صفحة يقدر المهاجم يبرمجها
اللابات
طلب يأتي من موقع آخر
محلولسهللاب في المتصفح
اصنع صفحة مهاجم ترسل طلبا مزورا يغير بريد الزعيم الاحتياطي إلى بريدك وسلمها له
ادخل اللابمقفلرمز على الباب الأمامي فقط
محلولمتوسطلاب في المتصفح
غير بريد الزعيم الاحتياطي إلى بريدك رغم وجود الرمز على طلب POST
ادخل اللابمقفلثغرة في الملاذ الأخير
محلولصعبلاب في المتصفح
غير بريد الزعيم الاحتياطي إلى بريدك رغم حماية SameSite=Lax
ادخل اللابمقفل
