Что такое CSRF атака и как от неё защититься?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое CSRF атака?
CSRF (Cross-Site Request Forgery) — это тип атаки на веб-приложение, при которой злоумышленник заставляет пользователя выполнить нежелательные действия в приложении, где он уже авторизован. Атака основана на доверии приложения к браузеру пользователя и существующим в нем данным (например, cookies). Злоумышленник создает вредоносную страницу или элемент, который автоматически отправляет запрос к целевой веб-приложению, используя уже установленные в браузере пользователя cookies для авторизации.
Пример атаки:
- Пользователь авторизован в банковском приложении на
bank.com. - Злоумышленник создает страницу с таким кодом:
<!-- Страница на злоумышленника.com -->
<form action="https://bank.com/transfer" method="POST" id="maliciousForm">
<input type="hidden" name="amount" value="1000">
<input type="hidden" name="to_account" value="attacker_account">
</form>
<script>
document.getElementById('maliciousForm').submit();
</script>
Если пользователь посетил эту страницу, в его браузер автоматически отправляется POST-запрос на bank.com. Браузер добавит к этому запросу cookies авторизации, и банковское приложение выполнит перевод, считая запрос легальным.
Как защититься от CSRF?
1. Использование CSRF-токенов (наиболее распространенный метод)
Приложение генерирует уникальный, секретный токен для каждой сессии пользователя или для каждого запроса формы. Этот токен добавляется в формы как скрытое поле (<input type="hidden">) или передается через заголовки запроса (для AJAX). При обработке запроса приложение проверяет наличие и корректность токена.
// Пример генерации и проверки CSRF-токена в PHP
session_start();
function generateCsrfToken() {
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
function validateCsrfToken($token) {
if (empty($_SESSION['csrf_token']) || $token !== $_SESSION['csrf_token']) {
return false;
}
return true;
}
// В форме:
<form method="POST">
<input type="hidden" name="csrf_token" value="<?= generateCsrfToken() ?>">
<!-- другие поля формы -->
</form>
// При обработке POST-запроса:
if (!validateCsrfToken($_POST['csrf_token'])) {
die('Ошибка CSRF: неверный токен.');
}
2. Проверка заголовка Origin или Referer
Для запросов, которые не могут быть отправлены из другого источника (например, POST), можно проверять заголовки Origin или Referer. Они должны соответствовать ожидаемому домену приложения. Однако этот метод не абсолютно надежен (заголовки могут отсутствовать или быть подделаны в некоторых браузерах).
$allowedOrigin = 'https://bank.com';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$origin = $_SERVER['HTTP_ORIGIN'] ?? $_SERVER['HTTP_REFERER'] ?? '';
if (strpos($origin, $allowedOrigin) !== 0) {
die('Неверный источник запроса.');
}
}
3. Использование SameSite cookies
Атрибут SameSite для cookies позволяет ограничить отправку cookies только при запросах, инициированных с того же сайта. Значения:
SameSite=Strict: Cookies отправляются только при строго same-site запросах.SameSite=Lax: Cookies отправляются при same-site запросах и при безопасных cross-site запросах (например, переход по ссылке).
// Установка cookie с атрибутом SameSite в PHP 7.3+
setcookie('session_id', $sessionId, [
'expires' => time() + 3600,
'path' => '/',
'domain' => 'bank.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict' // или 'Lax'
]);
4. Дополнительные меры безопасности
- Для критических операций требуйте повторную аутентификацию (например, ввод пароля для финансовой транзакции).
- Ограничивайте время жизни сессии и используйте безопасные методы для ее завершения.
- Реализуйте логирование всех критических действий для отслеживания подозрительных операций.
- Обязательно используйте HTTPS, чтобы защитить передаваемые данные и cookies от перехвата.
Рекомендации для PHP Backend разработчика
В современных PHP фреймворках (Laravel, Symfony, Yii2) защита от CSRF обычно реализована "из коробки".
- В Laravel: используется middleware
VerifyCsrfToken, токен автоматически добавляется в формы через@csrfBlade-директиву. - В Symfony: компонент
Formможет генерировать и проверять CSRF-токены с помощьюCsrfTokenManager.
Обязательно активируйте и используйте эти механизмы. Для защиты API эндпоинтов, которые используют cookies для авторизации, также необходимо применять CSRF-токены или переходить на авторизацию по токенам (например, JWT), которая не зависит от cookies браузера и менее подвержена CSRF.
Вывод: Защита от CSRF является обязательным элементом безопасности любого веб-приложения. Комбинация CSRF-токенов и SameSite cookies сегодня считается наиболее эффективной и надежной стратегией для предотвращения таких атак.