маркер csrf laravel

У цьому підручнику Laravel ми говоримо про веб-безпеку та про те, як захистити веб-додаток від міжсайтових підробок запитів або атак CSRF.

CSRF — це зловмисна діяльність, яку виконує зловмисник, який виконує дії від імені автентифікованого користувача, що завдає шкоди веб-безпеці. На щастя, Laravel надає інструменти для запобігання такому типу вразливості.

Приблизний час читання: 5 хвилин

Що таке CSRF?

Атаки CSRF захоплюють сесії користувачів. Вони роблять це, обманом змушуючи користувача надіслати запит за допомогою прихованих тегів форми або шкідливих URL-адрес (зображень або посилань) без відома користувача.

Ця атака призводить до зміни стану сеансу користувача, витоку даних, а іноді хакери можуть маніпулювати даними кінцевого користувача в програмі.

веб-безпека csrf

Зображення вище ілюструє сценарій, коли веб-безпеку порушено. Жертва надсилає запит, натискаючи на посилання (отримано), надсилаючи запит на сервер веб-сайту, який спричиняє бажані ефекти хакеру, який отримує інформацію, корисну для доступу та маніпулювання сервером веб-сайту.

Як запобігти запитам CSRF

Щоб покращити безпека мережі ваших програм, під час кожного сеансу користувача Laravel генерує захищені маркери, які він використовує, щоб переконатися, що автентифікований користувач є тим, хто запитує програму.

Оскільки цей маркер змінюється кожного разу, коли сеанс користувача повторно генерується, зловмисник не може отримати до нього доступ.

Кожного разу, коли надходить запит на зміну інформації користувача на стороні сервера (сервер), наприклад POSTPUTPATCHDELETE, ви повинні включити директиву @csrf у формі запиту blade HTML. The @csrf тому це директива Blade використовується для створення прихованого маркера, перевіреного програмою.

Директива Blade це синтаксис, який використовується в системі шаблонів Laravel під назвою Лезо . Щоб створити файл blade ви повинні дати йому ім’я – у нашому випадку форму – після чого розширення леза. Це означає, що файл матиме назву form.blade.php.

Файл використовується blade для візуалізації переглядів для користувачів на веб-сторінці. Існує кілька попередньо визначених директив або скорочених синтаксисів, які можна використовувати. Наприклад, @if перевірити, чи виконується умова, @empty перевірте, чи не порожні записи, @auth перевірити, чи автентифікований користувач тощо.

Але повернемося до директиви @csrf. Ось як це використовувати:

<form method="POST" action="{{route('pay')}}">

    @csrf
    
</form>

Попередні версії Laravel у них був інший підхід: вони і працюють, і роблять те саме.

<form method="POST" action="{{route('pay')}}">
    
    <input type="hidden" name="_token" value="{{ csrf_token() }}" />
    
</form>

Коли маркер CSRF відсутній у запиті форми, який надсилається, або якщо він виглядає недійсним, Laravel генерує повідомлення про помилку «Сторінка закінчилася» з кодом статусу 419.

термін безпеки веб-сторінки минув

Як і де відбувається перевірка CSRF

Проміжне програмне забезпечення VerifyCsrfToken керує перевіркою CSRF у програмі Laravel. The middleware зареєстрований в Kernel.php і знаходиться в каталозі app/Http/Middleware. Це означає, що middleware він запускається для запитів у мережі, не пов’язаних з API.

protected $middlewareGroups = [
        'web' => [
           .
           .
           .
           .
           .
            \App\Http\Middleware\VerifyCsrfToken::class,
        ],
    ];

Проміжне програмне забезпечення VerifyCsrfToken розширює клас Illuminate\Foundation\Http\Middleware\VerifyCsrfToken, тобто перевірка CSRF визначається в межах класу.

Давайте зануримося глибше, щоб дізнатися, як Laravel обробляє перевірку CSRF.

Усередині класу ми маємо функцію tokensMatch.

protected function tokensMatch($request)
{
     $token = $this->getTokenFromRequest($request);

     return is_string($request->session()->token()) &&
            is_string($token) &&
            hash_equals($request->session()->token(), $token);
}

у коді визначає, чи збігаються сеанс і вхідні маркери CSRF.

Функція робить дві речі:

  1. отримати $this->getTokenFromRequest токен із вхідного запиту, доданий через приховане поле або заголовок запиту. Маркер розшифровується, а потім повертається до змінної маркера.
protected function getTokenFromRequest($request)
{
    $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');

    if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
        try {
            $token = CookieValuePrefix::remove($this->encrypter->decrypt($header, static::serialized()));
        } catch (DecryptException $e) {
            $token = '';
            }
    }

    return $token;
}

У коді він отримує маркер із заголовка

2. Переведіть і маркер запиту, і сеанс до рядка, а потім використовуйте hash_equals вбудований у PHP для порівняння рівності обох рядків. Результат цієї операції завжди bool (істина) або (хибність) .

Виключення URI із захисту CSRF

Можливо, нам знадобиться виключити набір URI із захисту CSRF. Наприклад, якщо ми використовуємо PayPal  щоб обробляти платежі та використовувати їхню систему веб-хуку, вам потрібно буде виключити маршрут обробки веб-хуку PayPal із захисту CSRF, оскільки PayPal не знатиме, який токен CSRF надсилати на ваші маршрути.

Як правило, такі типи шляхів потрібно розміщувати ззовні групи web проміжне програмне забезпечення, що Laravel застосовується до всіх шляхів у файлі routes/web.php. Ми також можемо виключити певні шляхи, надавши їх URI методу validateCsrfTokens у файлі програми bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: [
        'stripe/*',
        'http://example.com/foo/bar',
        'http://example.com/foo/*',
    ]);
})

Пов'язані читання

Ercole Palmeri

Авторе

Вам може бути цікаво…