الحماية CSRF في Laravel

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

مقدمة

يُسهّل 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.

مصادر