Блог

CSRF-атаки: что это и как их предотвратить

CSRF (Cross-Site Request Forgery, «межсайтовая подделка запроса») — атака, при которой браузер авторизованного пользователя отправляет запросы на целевой сервер без его ведома. Атакующий формирует вредоносную ссылку или форму — и когда пользователь открывает подготовленную страницу, браузер автоматически добавляет активную сессию к запросу. Сервер получает корректные данные аутентификации и выполняет команду: перевод денег, смена пароля, удаление данных. Владелец аккаунта об этом не узнает.

Как атака работает изнутри

Логика атаки становится понятной, если пройти по каждому этапу:
  1. Пользователь входит на доверенный ресурс — банк, корпоративный портал, онлайн-сервис. Браузер сохраняет cookie сессии.
  2. Атакующий создаёт страницу с формой или скриптом, который при открытии отправляет запрос на целевой сайт. Параметры этого запроса, как правило, предсказуемы — URL и поля известны заранее.
  3. Ссылку доставляют по email, через мессенджер или размещают на форуме. Достаточно одного перехода.
  4. Браузер автоматически добавляет к запросу сохранённые cookie. Сервер видит доверенный запрос от авторизованного пользователя и выполняет его.
Суть уязвимости: сервер доверяет браузеру, а браузер хранит сессию. CSRF эксплуатирует именно это доверие — у сервера нет встроенного механизма, который верифицировал бы источник каждого запроса. Он видит только факт: cookie корректный, сессия активна. Откуда именно пришёл запрос — с настоящей страницы приложения или со сторонней — по умолчанию не отслеживается.
Четыре шага выше указывают на три условия, при которых атака срабатывает:
  • пользователь авторизован;
  • браузер автоматически прикладывает cookie;
  • сервер не проверяет, откуда пришёл запрос.
Убрать любое из этих условий — значит заблокировать атаку. Авторизация — в руках пользователя. Поведение cookie и контроль источника запросов — в руках разработчика. Именно на этом строится вся логика защиты.

Методы защиты

Каждый из методов атакует одно из условий срабатывания CSRF.

CSRF-токен

Самый популярный метод. Сервер генерирует уникальный токен для каждой сессии или отдельного запроса и добавляет его в форму как скрытое поле. При отправке сервер сверяет значение — если токен отсутствует или не совпадает, запрос отклоняется.
Атакующий не знает значение токена. Оно не хранится в cookie и недоступно с других доменов из-за политики браузера Same-Origin Policy.

SameSite для cookie

Атрибут SameSite управляет тем, когда браузер добавляет cookie к запросам, поступающим с других доменов.
Таблица 1. Режимы атрибута SameSite и поведение браузера
Значение
Поведение
Strict
Cookie не передаётся при любом переходе с внешнего домена
Lax
Cookie передаётся только при безопасных методах (GET) и прямых переходах
None
Cookie передаётся всегда — требует атрибута Secure
Strict даёт максимальную защиту, но иногда ломает привычный сценарий: пользователь переходит по внешней ссылке и ожидает попасть сразу в авторизованную сессию — с этим режимом так не получится. Lax — компромисс. Он блокирует POST-запросы с чужих доменов, но не мешает навигации. None применяют только там, где cookie намеренно должны работать в кросс-доменном контексте — например, во встроенных виджетах или фреймах. Для форм с операциями изменения данных (POST, PUT, DELETE) оптимален Strict или Lax.

Проверка заголовков Origin и Referer

Каждый HTTP-запрос содержит заголовок Origin или Referer — адрес домена-отправителя. Сервер извлекает это значение и сверяет с перечнем допустимых доменов. Если домен не совпадает или заголовок отсутствует, запрос отклоняется. Метод прост в реализации и не требует дополнительного состояния на сервере.
ВАЖНО: Этот метод работает как дополнительный барьер. Часть браузеров или прокси может не передавать эти заголовки, поэтому строить защиту только на них — недостаточно.

Double Submit Cookie

Вариант без серверного хранения токена — удобен, когда состояние между запросами хранить негде. Сервер генерирует случайное значение и одновременно записывает его в cookie и в тело или заголовок запроса. При получении сравнивает оба — они должны совпасть.
Атака ломается на одном простом факте: JavaScript с чужого домена не может прочитать cookie целевого сайта — политика Same-Origin Policy это запрещает. Атакующий видит только cookie своего домена. Сформировать запрос с верным значением в теле он физически не в состоянии.

Повторная аутентификация для критичных операций

Для действий с высоким риском — смена пароля, перевод средств, изменение прав доступа — сервер запрашивает подтверждение пароля или второй фактор (2FA).
Даже если браузер отправил запрос автоматически, атакующий не знает пароль пользователя. Операция требует явного подтверждения — и без него не выполнится. Метод особенно важен там, где цена ошибки высока: финансовые операции, управление правами, административные функции.

Кто в группе риска

CSRF актуален для любого веб-приложения с авторизацией через браузер. Под угрозой в первую очередь:
  • Финансовые сервисы и банки — переводы, платёжные операции, изменение реквизитов. Атака на банковский аккаунт даёт прямой финансовый результат, поэтому финансовый сектор остаётся главной мотивацией атакующих.
  • Корпоративные порталы и панели администратора — управление правами, настройки системы, данные пользователей. Один скомпрометированный администратор открывает доступ ко всей организации.
  • Системы управления контентом (CMS) — публикация материалов, смена настроек, удаление данных. Атака здесь может навредить репутации и привести к потере контента.
  • Онлайн-магазины — изменение адреса доставки, оформление заказов за счёт пользователя, манипуляции с корзиной.
Общий признак — наличие POST-запросов, которые меняют состояние системы. Небольшой корпоративный портал уязвим ровно так же, как крупный банк — просто ставки другие. Масштаб компании не влияет на саму уязвимость.

Выводы

CSRF — атака на доверие между браузером и сервером. Атакующий не взламывает аккаунт напрямую: он заставляет браузер авторизованного пользователя выполнить нужный запрос, подставив активную сессию.
Атака срабатывает при трёх условиях: пользователь авторизован, браузер автоматически прикладывает cookie к запросам, сервер не проверяет источник. Убрать хотя бы одно — и атака провалится.
Надёжная защита выстраивается в несколько уровней:
  1. CSRF-токен — основной метод: уникальное значение, недоступное атакующему.
  2. SameSite=Strict / Lax — ограничивает передачу cookie с внешних доменов.
  3. Проверка Origin/Referer — дополнительный контроль источника запроса.
  4. Double Submit Cookie — вариант без серверного хранения токена.
  5. Повторная аутентификация — финальный барьер для критичных операций.
Ни один из методов по отдельности не даёт абсолютной защиты. Работает именно сочетание: комбинация нескольких уровней закрывает подавляющее большинство CSRF-векторов.