Загрузка...

CSRF уязвимость и защите от нее

CSRF (Cross-Site Request Forgery)

Что такое CSRF?

CSRF (Cross-Site Request Forgery) – это вид уязвимости сайта. Когда может произойти подмена данных.
Простым языком, это подмена данных (как правило форм), отравляемых авторизованным пользователем через вредоносный ресурс (сайт, приложение).

Пример CSRF атаки

У нас есть HTML-форма, которую пользователь должен заполнить: ввести адрес и нажать кнопку «Сохранить». В результате в бэкенд полетит POST-запрос с HTML-формой. Мы видим, что браузер автоматически поставил туда сессионные куки пользователя. Бэкенд, когда получит такой запрос, посмотрит, что есть такая сессия, это легитимный пользователь, и изменит ему адрес доставки.

Как это может произойти?

Пользователь получил email, перешел по ссылке на вредоносный сайт. Вредоносный сайт отправляет запрос с сессионными данными пользователя для изменения/подмены каких-то данных на атакуемом сайте.
csrf

Защита

Наиболее популярный метод защиты от такой атаки – использование уникального токена (генерируемого нашим сайтом и меняющегося с сессией пользователя или со временем) в составе полей формы на изменение данных. Это будет гарантировать, что форма отправлена с нашего сайта, а не вредоносного.
Для этого нужно изменить данные формы, добавить поле с csrf-ключем и сделать проверку csrf-ключа на стороне обработчика формы.

В Laravel

В laravel это будет выглядеть так:
<form action="/somewhere" method="POST">
@csrf
<!-- эквивалент для html, который генерирует @csrf -->
<input name="_token" type="hidden" value="{{ csrf_token() }}" />
</form>

Код генерирует csrf-токен для каждой активной сессии на веб-сайте.

Проверяется токен через специальный middleware VerifyCsrfToken, входящий в состав прослоек для группы web.

В WordPress

В WordPress используется функция wp_nonce_field(); которая также генерируется html поле в составе формы. Проверка в обработчике осуществляется функцией wp_verify_nonce(), куда передаются данные запроса. Дополнить защиту, можно функцией wp_referer_field(), если запрос должен приходить только с определенной, заранее известной страницы.

Любой php код

В PHP вы можете использовать функцию uniqid() для генерации токена CSRF:

$csrf_token = uniqid();

Затем вы можете отправить токен CSRF клиенту в виде скрытого поля формы:

<form>
<input type="hidden" name="_csrf_token" value="<?php echo $csrf_token; ?>">
<!-- другие поля формы -->
</form>

Когда форма отправляется на сервер, вы можете проверить токен CSRF, сравнив его с тем, который был отправлен клиенту:

if ($_POST['_csrf_token'] !== $csrf_token) {
// CSRF-атака, отклоняем запрос
exit;
}

2. Использование заголовка запроса

Вместо использования скрытого поля формы, вы можете отправлять токен CSRF в заголовке запроса. В PHP вы можете использовать функцию header() для отправки заголовка:

header('X-CSRF-Token: ' . $csrf_token);

Затем вы можете проверить заголовок запроса на сервере:

if ($_SERVER['HTTP_X_CSRF_TOKEN'] !== $csrf_token) {
// CSRF-атака, отклоняем запрос
exit;
}

3. Использование сессии

Вы можете хранить токен CSRF в сессии и проверять его при каждом запросе. В PHP вы можете использовать функцию session_start() для начала сессии и функцию $_SESSION для хранения токена CSRF:

session_start();
$csrf_token = uniqid();
$_SESSION['csrf_token'] = $csrf_token;

Затем вы можете проверить токен CSRF при каждом запросе:

if ($_POST['_csrf_token'] !== $_SESSION['csrf_token']) {
// CSRF-атака, отклоняем запрос
exit;
}

После успешной проверки формы, необходимо обновить токен.

4. Использование библиотеки OWASP CSRFGuard

OWASP CSRFGuard – это библиотека, которая помогает защитить ваш сайт от CSRF. Она генерирует токен CSRF и проверяет его при каждом запросе.

В PHP вы можете использовать библиотеку OWASP CSRFGuard, включив ее в ваш проект и настроив ее в соответствии с документацией.

Вот несколько примеров кода, которые помогут вам защитить ваш сайт от CSRF:

// Генерация токена CSRF
$csrf_token = OWASP_CSRFGuard::generateToken();

// Отправка токена CSRF клиенту
echo '<input type="hidden" name="_csrf_token" value="' . $csrf_token . '">';

// Проверка токена CSRF на сервере
if (!OWASP_CSRFGuard::validateToken($_POST['_csrf_token'])) {
// CSRF-атака, отклоняем запрос
exit;
}
Вот несколько способов защиты вашего сайта на PHP от CSRF. Важно помнить, что защита от CSRF – это только одна часть общей безопасности вашего веб-приложения.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *