Перейти к содержимому

CSRF: сценарии ​

TIP

Это текущая реализация; при переезде на BFF её заменяет Авторизация и CSRF в BFF.

Как CSRF-защита ведёт себя в каждом случае. Устройство — «Как устроено», команды проверки и известные пробелы — «Проверка и ограничения».

На схемах: F — код фронта, B — браузер (хранит cookie и сам прикладывает их к запросам), A — API, E — чужой сайт. «Анонимный» и «подписанный» — виды токена __Host-csrf. Под каждой схемой — как сценарий проверен.

Первый заход в чистом браузере ​

У гостя нет cookie. Стартовая проверка сессии — изменяющий запрос, поэтому получает 403, но этот же ответ приносит анонимную __Host-csrf: к форме входа токен уже есть.

Проверено на проде 07.10.2026 в Chrome.

Регистрация ​

Проверено на проде 07.10.2026 в Chrome.

Вход ​

Так же, как регистрация: Double Submit без подписи (пользователя ещё нет), в ответе — новые cookie и подписанный токен. Токен, выданный до входа, после входа не действует.

Проверено на проде 07.10.2026 в Chrome и curl.

Вход с неверным паролем ​

CSRF-проверка пройдена, отказывает обработчик: 401, cookie не меняются.

Проверено на проде 07.10.2026 curl.

Перезагрузка страницы со входом ​

После F5 память фронта пуста, cookie остались. Refresh проверяет подпись токена для владельца refresh-сессии и выдаёт новую сессию.

Проверено на проде 07.10.2026 в Chrome.

Изменяющий запрос ​

Создание блокнота, добавление и удаление ячеек. Токен тот же, что выдан при входе или последнем refresh: обычные запросы его не меняют.

Проверено на проде 07.10.2026 в Chrome.

Выход и повторный вход без перезагрузки ​

Выход стирает access и refresh и ставит новый анонимный токен. Фронт читает cookie перед каждым запросом, поэтому следующий вход сразу идёт с новым значением.

Проверено на проде 07.10.2026 в Chrome.

Чужой компьютер ​

Алиса вышла, Боб вошёл на том же компьютере. Токен Алисы, сохранённый заранее, у Боба не проходит: подпись привязана к пользователю.

Проверено на проде 07.10.2026 curl (два пользователя).

Истёк access посреди работы ​

Через 15 минут браузер сам удаляет access_token. Запрос получает 401, фронт делает один refresh и повторяет запрос со свежим заголовком.

Только по коду: authMiddleware фронта и CSRF бэка.

Атака с чужого сайта ​

Страница на evil.example отправляет форму на наш API. Форма не может поставить заголовок X-CSRF-Token, а fetch с ним вызывает preflight, который CORS для чужого Origin не пропускает. С SameSite=Lax браузер и не приложит наши cookie к межсайтовому POST, но защита на это не рассчитывает.

Проверено на проде 07.10.2026 curl: POST /auth/register с Origin: https://evil.example — 403. Поведение браузера с формой и preflight — по спецификации Fetch.

Токен другого пользователя ​

Даже если злоумышленник подставит свой подписанный токен и в cookie, и в заголовок запроса жертвы, подпись не сойдётся для её userID.

Проверено на проде 07.10.2026 curl.

Вход без __Host-csrf ​

Cookie удалили в другой вкладке или в DevTools. Вход получает 403, но ответ уже принёс новую cookie, и фронт один раз повторяет запрос.

Проверено на проде 07.10.2026 в Chrome.

Сессия есть, __Host-csrf нет ​

Пользователь вошёл, но cookie удалили (или он вошёл до выкатки CSRF-защиты). Бэк в ответе 403 сразу выдаёт подписанный токен, но фронт повторяет только вход и регистрацию: стартовая проверка уводит на страницу входа, выход и изменения показывают ошибку. Перезагрузка или повтор действия проходит. Задача — frontend#34.

Проверено на проде 07.10.2026 в Chrome.

Две вкладки обновляют сессию одновременно ​

Refresh удаляет старую сессию, поэтому из двух одновременных refresh с одной cookie проходит только первый. Вторая вкладка показывает вход, хотя cookie уже обновлены. Бывает после перезапуска браузера с несколькими вкладками или когда access истёк во всех вкладках сразу. Задача — backend#12.

Проверено на проде 07.10.2026 curl: два параллельных refresh — 204 и 401.

http:// вместо https:// ​

__Host-csrf требует Secure и по http:// не сохранится. Сайт отвечает 308 и переводит на https://, поэтому до API по http:// браузер не доходит.

Проверено на проде 07.10.2026 curl.