Захист від CSRF
Вступ
Крос-сайтові підробки запитів є типом зловмисної експлуатації, при якій несанкціоновані команди виконуються від імені автентифікованого користувача. На щастя, Laravel робить захист вашого застосунку від крос-сайтових підробок запитів (CSRF) простим.
Пояснення вразливості
Якщо ви не знайомі з міжсайтовими підробками запитів, давайте розглянемо приклад того, як ця вразливість може бути використана. Уявіть, що ваш застосунок має маршрут /user/email, який приймає POST запит для зміни адреси електронної пошти автентифікованого користувача. Найімовірніше, цей маршрут очікує, що поле введення email міститиме адресу електронної пошти, яку користувач хотів би почати використовувати.
Без захисту CSRF, зловмисний вебсайт міг би створити HTML-форму, яка вказує на маршрут вашого застосунку /user/email і відправляє електронну адресу самого зловмисника:
<form action="https://your-application.com/user/email" method="POST">
<input type="email" value="example@example.com">
</form>
<script>
document.forms[0].submit();
</script>
Якщо зловмисний вебсайт автоматично надсилає форму при завантаженні сторінки, зловмиснику потрібно лише заманити нічого не підозрюючого користувача вашого застосунку відвідати їхній вебсайт, і їхня електронна адреса буде змінена у вашому застосунку.
Щоб запобігти цій уразливості, нам потрібно перевіряти кожен вхідний запит POST, PUT, PATCH або DELETE на наявність секретного значення сесії, до якого зловмисний застосунок не має доступу.
Запобігання CSRF-запитам
Laravel автоматично генерує CSRF "токен" для кожної активної сесії користувача, якою керує застосунок. Цей токен використовується для перевірки, що автентифікований користувач є особою, яка фактично робить запити до застосунку. Оскільки цей токен зберігається в сесії користувача і змінюється щоразу, коли сесія регенерується, зловмисний застосунок не може отримати до нього доступ.
Поточний CSRF токен сесії можна отримати через сесію запиту або через допоміжну функцію csrf_token:
use Illuminate\Http\Request;
Route::get('/token', function (Request $request) {
$token = $request->session()->token();
$token = csrf_token();
// ...
});
Кожного разу, коли ви визначаєте HTML-форму "POST", "PUT", "PATCH" або "DELETE" у вашому застосунку, ви повинні включити приховане поле CSRF _token у форму, щоб middleware захисту від CSRF міг перевірити запит. Для зручності, ви можете використовувати директиву Blade @csrf для генерації прихованого поля токена:
<form method="POST" action="/profile"> @csrf <!-- Ідентично до... --> <input type="hidden" name="_token" value="{{ csrf_token() }}" /> </form>
Illuminate\Foundation\Http\Middleware\ValidateCsrfToken middleware, яке за замовчуванням включено в групу middleware web, автоматично перевірить, що токен у вхідних даних запиту відповідає токену, збереженому в сесії. Коли ці два токени збігаються, ми знаємо, що автентифікований користувач є тим, хто ініціює запит.
CSRF токени & SPA
Якщо ви створюєте SPA, що використовує Laravel як API бекенд, вам слід звернутися до документації Laravel Sanctum для отримання інформації про автентифікацію з вашим API та захист від вразливостей CSRF.
Виключення URI з захисту CSRF
Іноді ви можете захотіти виключити набір URI з захисту CSRF. Наприклад, якщо ви використовуєте Stripe для обробки платежів і використовуєте їхню систему вебхуків, вам потрібно буде виключити маршрут обробника вебхуків Stripe з захисту CSRF, оскільки Stripe не знатиме, який CSRF-токен відправити на ваші маршрути.
Зазвичай, ви повинні розміщувати такі маршрути поза групою middleware 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/*',
]);
})
Для зручності, middleware CSRF автоматично відключається для всіх маршрутів під час запуску тестів.
X-CSRF-TOKEN
На додаток до перевірки CSRF токена як параметра POST, middleware Illuminate\Foundation\Http\Middleware\ValidateCsrfToken, яке за замовчуванням включено в групу middleware web, також перевірятиме заголовок запиту X-CSRF-TOKEN. Ви можете, наприклад, зберігати токен у HTML тегу meta:
<meta name="csrf-token" content="{{ csrf_token() }}">
Потім, ви можете вказати бібліотеці, такій як jQuery, автоматично додавати токен до всіх заголовків запитів. Це забезпечує простий, зручний захист від CSRF для ваших AJAX-застосунків, що використовують застарілу технологію JavaScript:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
X-XSRF-TOKEN
Laravel зберігає поточний CSRF токен в зашифрованому cookie XSRF-TOKEN, який включається в кожну відповідь, згенеровану фреймворком. Ви можете використовувати значення cookie для встановлення заголовка запиту X-XSRF-TOKEN.
Цей cookie в основному відправляється для зручності розробника, оскільки деякі JavaScript фреймворки та бібліотеки, такі як Angular та Axios, автоматично розміщують його значення в заголовку X-XSRF-TOKEN для запитів з того ж джерела.
За замовчуванням файл resources/js/bootstrap.js включає бібліотеку Axios HTTP, яка автоматично відправляє заголовок X-XSRF-TOKEN за вас.
