
CSRF (Cross-Site Request Forgery) токен представляет собой уникальную случайную строку, которая используется для подтверждения, что запрос на сервер инициирован легитимным пользователем. Он защищает веб-приложения от атак, при которых злоумышленник может выполнить нежелательные действия от имени пользователя без его ведома.
Токен генерируется сервером при каждом сеансе или при отправке формы, сохраняется в сессии пользователя и добавляется в форму или заголовок запроса. Сервер сравнивает значение токена из запроса с сохраненным значением, и только при совпадении разрешает выполнение действия. Несоответствие токенов приводит к отклонению запроса.
Внедрение CSRF токена в веб-приложения требует точного соблюдения правил передачи: он должен быть недоступен через сторонние сайты, использоваться во всех изменяющих данные запросах (POST, PUT, DELETE) и обновляться при каждой важной операции. Игнорирование этих правил снижает защиту и делает токен уязвимым.
Для AJAX-запросов CSRF токен включается в заголовки или тело запроса, а для стандартных форм – в скрытое поле. Серверная проверка должна быть строгой, без исключений для конкретных маршрутов, чтобы предотвратить обход механизма. Использование токена вместе с HTTPS повышает безопасность передачи данных.
CSRF токен: значение и принцип работы
Сервер создает токен при открытии сессии или при загрузке формы, сохраняет его в серверной сессии и отправляет клиенту. При отправке запроса клиент должен включить токен: в скрытое поле формы или в заголовок AJAX-запроса. Сервер сверяет значение из запроса с сохраненным, разрешая действие только при совпадении.
Для повышения надежности токен должен быть случайным, с достаточной длиной (рекомендуется не менее 32 байт при использовании base64), и обновляться при критических действиях пользователя. Использование одного токена для всех сеансов или отсутствие проверки делает механизм уязвимым.
Рекомендуется применять CSRF токен ко всем запросам, которые изменяют состояние приложения (POST, PUT, DELETE), избегать его включения в GET-запросы и передавать только через защищенные каналы (HTTPS). В комбинации с правильной проверкой сессий это обеспечивает надежную защиту от большинства CSRF-атак.
Что такое CSRF токен и зачем он нужен в веб-приложениях

Без CSRF токена злоумышленник может отправлять поддельные POST-запросы, используя авторизованную сессию пользователя, например, для перевода средств, изменения пароля или удаления данных. Токен гарантирует, что только запросы с корректным значением, полученным от сервера, будут обработаны.
В веб-приложениях токен внедряется в формы через скрытые поля или передается в заголовках AJAX-запросов. Сервер проверяет его на совпадение с сохраненным в сессии значением, и при несоответствии отклоняет запрос. Рекомендуется применять токены для всех действий, влияющих на состояние данных, и обновлять их при каждой критической операции.
Механизм генерации CSRF токена на сервере

Генерация CSRF токена на сервере требует случайности и однозначной привязки к сессии пользователя. Рекомендуется использовать криптографически стойкие генераторы случайных чисел для создания строк длиной не менее 32 байт в формате base64.
Процесс генерации обычно включает следующие шаги:
- Создание случайного значения с помощью безопасного генератора (например, openssl_random_pseudo_bytes в PHP или secrets.token_bytes в Python).
- Кодирование значения в безопасный для передачи формат (base64 или hex).
- Сохранение токена в сессии пользователя на сервере с привязкой к уникальному идентификатору сессии.
- Включение токена в форму или заголовок ответа, чтобы клиент мог отправить его обратно с запросом.
Рекомендуется обновлять токен при критических операциях, таких как изменение пароля или финансовые транзакции, и проверять совпадение при каждом запросе. Использование одного токена для всех сессий или статичных значений снижает защиту и делает приложение уязвимым к атакам.
Как CSRF токен передается между клиентом и сервером
Передача CSRF токена требует надежного канала и строгого контроля его доступности. Токен должен быть доступен только для легитимного клиента и защищен от сторонних сайтов.
Основные способы передачи токена:
- Через скрытые поля формы. При отправке POST-запроса значение токена включается в <input type=»hidden»>, сервер сверяет его с сохраненным значением.
- Через заголовки AJAX-запросов. Токен добавляется в заголовок (например, X-CSRF-Token) при отправке fetch или XMLHttpRequest, что исключает его случайное раскрытие.
- Через cookie с защитой SameSite. Токен может храниться в cookie с атрибутом SameSite=Strict или SameSite=Lax, но его необходимо проверять на стороне сервера, а не полагаться только на браузер.
Рекомендации по передаче:
- Использовать HTTPS для всех запросов, чтобы исключить перехват токена.
- Не включать токен в URL или GET-запросы, так как они могут сохраняться в логах и быть доступны посторонним.
- Обновлять токен при каждой критической операции или при окончании сессии, чтобы минимизировать риск повторного использования.
Методы проверки CSRF токена на серверной стороне

Проверка CSRF токена на сервере направлена на подтверждение, что запрос поступил от легитимного клиента, и предотвращение выполнения действий злоумышленниками. Основной принцип – сверка токена, полученного с клиента, с токеном, сохраненным в сессии пользователя.
Существуют несколько подходов к проверке токена:
| Метод | Описание | Рекомендации |
|---|---|---|
| Сравнение сессий | Токен, полученный с запроса, сверяется с токеном, сохраненным в сессии пользователя. | Использовать уникальные токены для каждой сессии, обновлять при критических действиях. |
| Сопоставление с формой | Для каждой формы генерируется отдельный токен, который проверяется при отправке. | Применять для всех POST-запросов, включая AJAX-запросы, чтобы исключить поддельные формы. |
| Проверка через заголовки | Токен передается в специальном заголовке, сервер сверяет его с сессионным значением. | Использовать заголовки для AJAX и API-запросов, избегать передачи через URL. |
| Сравнение с cookie | Токен хранится в cookie с атрибутом SameSite и сверяется с переданным значением в теле запроса. | Не полагаться только на cookie, обязательно проверять значение на сервере. |
Любой несоответствующий или отсутствующий токен должен приводить к отклонению запроса. Регулярное обновление токенов и проверка для всех изменяющих данные действий повышают защиту приложения от CSRF-атак.
Использование CSRF токена в формах и AJAX-запросах

CSRF токен вставляется в HTML-формы как скрытое поле с уникальным значением для каждого сеанса пользователя. Пример реализации на сервере: генерация токена при создании сессии и сохранение его в базе данных или в памяти сервера. В форме токен добавляется так: .
При отправке формы сервер сверяет присланный токен с сохранённым. Несовпадение означает потенциальную атаку, и запрос отклоняется с ошибкой 403.
Для AJAX-запросов токен передаётся в заголовке HTTP или в теле запроса. В JavaScript это реализуется через добавление токена в fetch или XMLHttpRequest: например, fetch(url, { method: ‘POST’, headers: { ‘X-CSRF-Token’: token }, body: formData }). Сервер проверяет заголовок так же, как значение формы.
Рекомендуется обновлять CSRF токен при каждой успешной аутентификации и при длительных сессиях. Токены должны быть случайными, длиной не менее 32 байт, и использовать криптографически стойкий генератор случайных чисел.
В многосайтовых приложениях важно разделять токены для разных доменов и путей, чтобы исключить возможность межсайтовой подделки. Для SPA (Single Page Application) токен часто сохраняется в JavaScript-переменной и автоматически добавляется ко всем POST-запросам.
Валидация токена должна выполняться до любых изменений состояния сервера, включая записи в базу данных или изменения настроек пользователя. Любое нарушение последовательности проверки может позволить злоумышленнику выполнить нежелательные действия.
Типичные ошибки при внедрении CSRF токена
Использование одного токена на всех сессиях. Если токен не привязан к конкретному пользователю или сессии, атака возможна через повторное использование.
Сохранение токена в URL. Передача токена в параметрах GET делает его доступным в логах сервера и истории браузера, что снижает безопасность.
Отсутствие проверки токена на сервере. Генерация и вставка токена в форму без проверки на сервере не предотвращает CSRF.
Повторное использование токена после выхода пользователя. Токен должен инвалидироваться при завершении сессии, иначе злоумышленник может выполнить действия от имени старого пользователя.
Слабая генерация токена. Использование предсказуемых значений, например, на основе времени или идентификатора пользователя, делает защиту уязвимой.
Игнорирование AJAX-запросов. Если токен проверяется только для обычных форм, а AJAX-запросы обходят проверку, атака остаётся возможной.
Необновление токена при длительных сессиях. При постоянной сессии токен должен периодически меняться, чтобы снизить риск перехвата и повторного использования.
Неправильная область действия токена. Использование одного токена для всех путей и поддоменов увеличивает вероятность успешной атаки на отдельные части приложения.
Способы обхода CSRF токена злоумышленниками и защита от них

Перехват токена через XSS. Если на сайте присутствуют уязвимости XSS, злоумышленник может извлечь CSRF токен из страницы и отправить его вместе с поддельным запросом. Защита: устранение XSS, использование Content Security Policy (CSP), хранение токена в HttpOnly cookie не всегда эффективно, поэтому проверка токена на сервере остаётся обязательной.
Использование предсказуемых токенов. Если токены формируются на основе предсказуемых данных, атакующий может вычислить их. Защита: генерация токенов криптографически стойким генератором случайных чисел, длиной не менее 32 байт.
Повторное использование старого токена. Злоумышленник может повторно отправить ранее перехваченный токен. Защита: привязка токена к сессии и инвалидация после использования, обновление токена при длительных сессиях.
Обход проверки через CORS или поддомены. Атаки возможны, если сервер некорректно обрабатывает запросы с других источников. Защита: строгая проверка Origin и Referer заголовков, настройка CORS только для доверенных доменов.
Социальная инженерия и поддельные формы. Злоумышленник может убедить пользователя отправить форму с токеном вручную. Защита: использование токенов в сочетании с проверкой пользовательских действий, ограничение операций критического уровня через дополнительные подтверждения.
Вопрос-ответ:
Что такое CSRF токен и зачем он нужен?
CSRF токен — это уникальная строка, генерируемая сервером и привязанная к конкретной сессии пользователя. Он предотвращает выполнение нежелательных действий на сайте от имени пользователя, если злоумышленник пытается отправить поддельный запрос с другой страницы или сервиса.
Как правильно вставлять CSRF токен в HTML-формы?
Токен добавляется в форму как скрытое поле: . При отправке формы сервер сверяет присланное значение с токеном, сохранённым для текущей сессии. Несовпадение приводит к отклонению запроса.
Можно ли использовать один и тот же CSRF токен для всех пользователей и сессий?
Нет. Если токен общий для всех сессий, злоумышленник может использовать его для подделки запросов. Каждый пользователь должен получать уникальный токен, который изменяется при создании новой сессии или после длительного времени.
Как защитить AJAX-запросы с CSRF токеном?
Токен передаётся в заголовке запроса или в теле POST-запроса. Например, в fetch это выглядит так: fetch(url, { method: ‘POST’, headers: { ‘X-CSRF-Token’: token }, body: formData }). Сервер проверяет заголовок или тело запроса аналогично проверке формы, отклоняя запрос при несоответствии.
