الحماية CSRF في Laravel
مقدمة
يُسهّل Laravel حماية تطبيقك من الهجمات مُزوّرة الطلب عبر المواقع (cross-site request forgery) واختصارها CSRF. تزويرات الطلب عبر المواقع هن نوع من الاستغلال تُنفّذ فيها أوامر غير مُرخّصة نيابة عن المستخدم المصادق عليهالمُستوثق (authenticated user).
يُولّد Laravel تلقائيًّا "رمز" CSRF لكل جلسة مستخدم نشطة يديرها التطبيق. يُستخدم هذا الرمز (token) للتحقّق من كون المستخدم المصادق عليه نفس الشخص الذي يقدّم الطلبات للتطبيق.
يجب أن تضيف حقل CSRF مخفي في كل مرّة تعرّف فيها نموذج HTML في تطبيقك كي تتثبت برمجيّة الحماية CSRF الوسيطة من الطلب. تستطيع استخدام توجيه Blade المسمّى csrf@
لتوليد حقل الرمز:
<form method="POST" action="/profile">
@csrf
...
</form>
ستتحقق البرمجيّة الوسيطة VerifyCsrfToken
المحتواة في مجموعة البرمجيّة الوسيطة web
تلقائيًّا من تطابق الرمز المُخزّن في الجلسة مع الرمز الموجود في طلب الإدخال.
الرموز CSRF و JavaScript
من الملائم أكثر عند بناء تطبيقات مرتكزة على JavaScript أن تدع المكتبة HTTP JavaScript تُلحق الرمز CSRF تلقائيًّا لكل طلب خارج. يسجّل الملف resources/assets/js/bootstrap.js
افتراضيًّا قيمة العنصر (meta tag) المسمى csrf-token
بالمكتبة HTTP Axios. ان لم تستخدم هذه المكتبة سيكون عليك إعداد هذا السلوك (behavior) يدويًّا لتطبيقك.
استثناء URIs من الحماية CSRF
قد ترغب أحيانا في استثناء مجموعة URI من الحماية CSRF. مثلا إن استخدمت Stripe لمعالجة الدفعات ونظامهم webhook ستحتاج لاستثناء معالج مسار webhook Stripe من الحماية CSRF بما أن Stripe لن يعلم ما سيرسل كرمز CSRF لمساراتك.
عموما عليك وضع هذا النوع من المسارات خارج مجموعة البرمجيّات الوسيطة web
التي يطبّقها RouteServiceProvider
على كل المسارات في الملف routes/web.php
. يمكنك استثناء المسارات بإضافة URI الخاص بهن للخاصيّة except$
من برمجيّة VerifyCsrfToken
الوسيطة:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* CSRF التي يجب استثنائها من التحقق URIs
*
* @var array
*/
protected $except = [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
];
}
ملاحظة: برمجيّة الحماية CSRF الوسيطة تُعطّل تلقائيًّا عند الاختبارات.
X-CSRF-TOKEN
إضافة للتحقق من وجود الرمز CSRF كمعامل POST، تتحقق البرمجيّات الوسيطة VerifyCsrfToken
من وجود ترويسة (header) الطلب X-CSRF-TOKEN
. تستطيع مثلا تخزين الرمز في وسم meta
HTML:
<meta name="csrf-token" content="{{ csrf_token() }}">
ثم يمكنك ،بعد إنشائك للوسم meta
إعطاء تعليمات لمكتبة مثل jQuery لتضيف الرمز تلقائيًّا لكل ترويسات الطلبات. توفّر هذه الطريقة حماية CSRF بسيطة وملائمة لتطبيقاتك المؤسّسة على AJAX:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
ملاحظة: يسجّل الملف resources/assets/js/bootstrap.js
قيمة الوسم الفوقي csrf-token
بالمكتبة HTTP Axios. إن لم تستخدم هذه المكتبة سيكون عليك إعداد هذا السلوك (behavior) يدويًّا لتطبيقك.
X-XSRF-TOKEN
يخزّن Laravel الرمز CSRF الحالي في ملف تعريف الارتباط (cookie) المُضاف لكل رد يولّده إطار العمل. يمكنك استخدام ملف تعريف الارتباط لضبط ترويسة الطلب X-XSRF-TOKEN
.
يرسل ملف تعريف الارتباط هذا مبدئيًّا لأنه يربحك الوقت بما أن بعض مكتبات وإطارات العمل JavaScript مثل Angular و Axios يضعن قيمتها تلقائيًّا في الترويسة X-XSRF-TOKEN
.