حفاظت CSRF

اصول آموزش Laravel

تاریخ : جمعه 13 بهمن 1396

به حملاتی که از طریق درخواست‌های متقابل جعلی به سایت صورت می‌گیرد، CSRF گفته می‌شود. ان عبارت مخفف عبارت cross-site request forgery است. لاراول یک روش آسان برای حفاظت در برابر این حملات ارائه می‌دهد. درخواست‌های متقابل جعلی نوعی سوءاستفاده مخرب است که به موجب آن هکرها دستورات غیرمجاز را از طریق کاربر لاگین شده اجرا می‌کنند. در این در از آموزش لاراوال 5.5 با هم این قابلیت لاراول را بررسی می‌کنیم.

هر کاربر فعال که توسط برنامه مدیریت می‌شود، یک سشن دارد. لاراول به صورت خودکار یک نشانه CSRF برای هر سشن تولید می‌کند. از این نشانه برای شناسایی کاربر لاگین شده‌ که درخواست‌ها را به صورت واقعی به برنامه می‌فرستد، استفاده می‌کنیم.

هر زمان که یک فرم HTML را در برنامه خود تعریف می‌کنید، باید فیلد پنهان CSRF را در درون فرم قرار دهید تا middleware مربوط به حفاظت CSRF بتواند درخواست کاربر را تایید کند. برای تولید فیلد نشانه می‌توان از تابع کمکی csrf_field به صورت زیر استفاده کرد:

<form method="POST" action="/profile">
    {{ csrf_field() }}
    ...
</form>

middlewareVerifyCsrfToken، که در گروه middleware web قرار دارد، به صورت خودکار نشانه‌ی موجود در درخواست ورودی برنامه را با نشانه ذخیره شده در سشن (session) کاربر مقایسه می‌کند تا مشخص کند که با هم مطابقت دارند یا خیر.


توکن CSRF و جاوا اسکریپت

در هنگام ایجاد برنامه‌های کاربردی تحت جاوا اسکریپت، برای راحتی کار، به صورت خودکار کتابخانه HTTP جاوا اسکریپت نشانه CSRF را برای هر درخواست خروجی پیوست می‌کند. در حالت پیش‌فرض، فایل resources/assets/js/bootstrap.js مقدار تگ متا csrf-token را با کتابخانه Axisse HTTP ثبت می‌کند. اگر از این کتابخانه در برنامه خود استفاده نمی‌کنید، باید این کار را به صورت دستی برای برنامه خود پیکربندی کنید.


حذف برخی از URIها از حفاظت CSRF در لاراول

گاهی اوقات ممکن است بخواهید مجموعه‌ای از URIها را از حفاظت CSRF حذف کنید. برای مثال، اگر از روش Stripe برای پردازش پرداخت‌ها استفاده می‌کنید و همچنین از سیستم webhook نیز بهره می‌برید، باید مسیر Stripe webhook handler خود را از حفاظت CSRF حذف کنید، زیرا Stripe نمی‌داند که کدام نشانه CSRF برای مسیرهای شما ارسال می‌شود.

این نوع مسیرها را باید خارج از گروه middlewareweb قرار دهید که RouteServiceProvider در تمام مسیرها در فایل routes/web.php اعمال می‌کند. می‌توانید مسیرها را با اضافه کردن URIهای خود به خصوصیت $except به middleware VerifyCsrfToken حذف کنید:


<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'stripe/*',
        'http://example.com/foo/bar',
        'http://example.com/foo/*',
    ];
}


در لاراول X-CSRF-TOKEN

middlewareVerifyCsrfToken علاوه بر چک کردن نشانه CSRF به عنوان پارامتر POST، همچنین هدر درخواست 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')
    }
});

By default, the resources/assets/js/bootstrap.js file registers the value of the csrf-token meta tag with the Axios HTTP library. If you are not using this library, you will need to manually configure this behavior for your application.


در لاراول X-XSRF-TOKEN

لاراول نشانه CSRF فعلی را در کوکی XSRF-TOKEN ذخیره می‌کند که هر پاسخی که توسط فریم ورک تولید شده است را شامل می‌شود. می‌توانید از مقدار کوکی برای تنظیم هدر درخواست X-XSRF-TOKEN استفاده کنید.

برخی از کتابخانه‌ها و فریم ورک‌های جاوا اسکریپت، مانند Angular و Axios، این مقدار را به صورت خودکار در هدر X-XSRF-TOKEN قرار می‌دهند.


منابع مورد مطالعه جهت جمع آوری این مطلب:
https://laravel.com/docs/5.5/csrf
https://www.lydaweb.com/article/courses/laravel-5-5-tutorial/225/حفاظت-csrf-لاراول


نظرات