Ответ
CSRF (Cross-Site Request Forgery) — это вид атаки на веб-приложения, при которой злоумышленник заставляет браузер авторизованного пользователя выполнить нежелательный запрос к доверенному сайту. Атака возможна, потому что браузер автоматически отправляет cookies (включая сессионные) при каждом запросе к домену.
Сценарий атаки:
- Пользователь авторизуется на сайте
bank.com. Его сессия сохраняется в cookie. - Пользователь переходит на вредоносный сайт, который содержит скрытую форму или отправляет AJAX-запрос на
bank.com/transfer?to=attacker&amount=1000. - Браузер автоматически прикрепляет cookies сессии к этому запросу.
- Сервер
bank.comвидит валидную сессию и выполняет перевод.
Основной метод защиты — CSRF-токены: Сервер генерирует уникальный, секретный токен для каждой пользовательской сессии и внедряет его в формы (как скрытое поле) или в заголовки AJAX-запросов. При получении запроса на изменение состояния сервер проверяет соответствие токена из запроса токену в сессии.
Пример реализации защиты на PHP:
// 1. Генерация и сохранение токена в сессии при её старте
session_start();
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// 2. Внедрение токена в HTML-форму
<form action="/transfer.php" method="POST">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token'], ENT_QUOTES); ?>">
<!-- остальные поля формы -->
</form>
// 3. Проверка токена при обработке POST-запроса
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'] ?? '')) {
http_response_code(403);
die('Invalid CSRF token.');
}
// Токен верный, обрабатываем запрос
}
Важные моменты:
- Используйте криптографически безопасные генераторы (
random_bytes()). - Проверяйте с помощью
hash_equals()для защиты от атак по времени. - В современных фреймворках (Laravel, Symfony, Django, Spring Security) защита от CSRF встроена и включается по умолчанию.