Skip to content
Icon

ПРЕДУПРЕЖДЕНИЕ Вы просматриваете документацию к старой версии Laravel. Рассмотрите возможность обновления Вашего проекта до Laravel 9.x.

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="malicious-email@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, чтобы мидлвар защиты CSRF могло проверить запрос. Для удобства вы можете использовать директиву Blade @csrf для генерации поля ввода скрытого токена:

<form method="POST" action="/profile">
@csrf
 
<!-- Эквивалентно... -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>

App\Http\Middleware\VerifyCsrfToken мидлвар, которое по умолчанию включено в группу мидлваров web, автоматически проверяет соответствие токена во входном запросе токен, хранящийся в сессии. Когда эти два токена совпадают, мы знаем, что аутентифицированный пользователь инициирует запрос.

Токены CSRF и SPA

Если Вы создаете SPA, который использует Laravel в качестве серверной части API, Вам следует обратиться к документации Laravel Sanctum для получения информации об аутентификации с помощью Вашего API и защите от уязвимостей CSRF.

Исключение URI из защиты CSRF

Иногда Вы можете захотеть исключить набор URI из защиты CSRF. Например, если Вы используете Stripe для обработки платежей и используете их систему веб-перехватчиков, Вам нужно будет исключить маршрут обработчика веб-перехватчиков Stripe из защиты CSRF, поскольку Stripe не будет знать, какой токен CSRF отправить по Вашим маршрутам.

Как правило, Вы должны размещать эти виды маршрутов вне группы мидлвара web, который App\Providers\RouteServiceProvider применяет ко всем маршрутам в файле routes/web.php. Однако Вы также можете исключить маршруты, добавив их URI в свойство $except мидлвара VerifyCsrfToken:

<?php
 
namespace App\Http\Middleware;
 
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
 
class VerifyCsrfToken extends Middleware
{
/**
* URI, которые следует исключить из проверки CSRF.
*
* @var array
*/
protected $except = [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
];
}

{tip} Для удобства мидлвар CSRF автоматически отключается для всех маршрутов при выполнение тестов.

X-CSRF-ТОКЕН

В дополнение к проверке токена CSRF в качестве параметра POST мидлвар App\Http\Middleware\VerifyCsrfToken также проверяет заголовок запроса 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-ТОКЕН

Laravel хранит текущий токен CSRF в зашифрованном файле куки XSRF-TOKEN, который включается в каждый ответ, сгенерированный платформой. Вы можете использовать значение cookie для установки заголовка запроса X-XSRF-TOKEN.

Этот файл куки в первую очередь отправляется для удобства разработчика, поскольку некоторые фреймворки и библиотеки JavaScript, такие как Angular и Axios, автоматически помещают его значение в заголовок X-XSRF-TOKEN в запросах с одним и тем же источником.

{tip} По умолчанию файл resources/js/bootstrap.js включает HTTP-библиотеку Axios, которая автоматически отправляет Вам заголовок X-XSRF-TOKEN.