Получить доступ

Что такое CSRF и как он связан с CORS?

MiddleБезопасность
Ещё спрашивают так:
  • Что такое межсайтовая подделка запроса?
  • Зачем нужен CSRF-токен?
  • Что делает CORS и от чего он не защищает?
  • Что такое SameSite у cookie?
Коротко

CSRF — чужой сайт заставляет браузер жертвы отправить запрос на ваш сайт; браузер сам приложит cookie, и запрос выполнится от имени пользователя. CORS — правила, когда скрипт с одного домена может читать ответы другого.

  • Защита от CSRF: cookie SameSite, CSRF-токен, проверка Origin, не менять состояние через GET
  • CORS не защищает от CSRF: простой POST с формы уходит и без CORS — запрещено лишь прочитать ответ
  • CORS ослабляет политику одного источника, а не усиливает

А ещё С токеном в заголовке Authorization (не в cookie) классического CSRF нет

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Политика одного источника (same-origin policy): скрипт со страницы evil.example не может читать ответы с bank.ru. Источник — схема + домен + порт.

CSRF. Но отправлять запросы на другой источник браузер разрешает: формы, картинки, ссылки. И при отправке он прикладывает cookie этого сайта. Если пользователь вошёл в банк, страница злоумышленника с автоматически отправляемой формой POST bank.ru/transfer выполнит перевод: сервер видит валидную сессионную cookie. Злоумышленник ответа не видит, но ему и не нужно — действие выполнено.

Защита от CSRF:

  • SameSite у cookie — Lax (по умолчанию в современных браузерах): cookie не отправляется в межсайтовых POST и фоновых запросах, только при переходе по ссылке; Strict — никогда в межсайтовых. Основная защита сегодня;
  • CSRF-токен — случайное значение в форме или заголовке, которое сервер сверяет с сессией. Чужой сайт не знает токена и прочитать его не может (той самой политикой одного источника). Spring Security, Django делают это из коробки;
  • **проверка заголовков Origin/Referer** на изменяющих запросах;
  • GET не меняет состояние — иначе хватит картинки <img src=".../delete">;
  • для API с токеном в заголовке Authorization CSRF не работает: браузер такой заголовок сам не подставит.

CORS (Cross-Origin Resource Sharing) — механизм, которым сервер разрешает скриптам с других источников читать свои ответы. Браузер добавляет Origin, сервер отвечает Access-Control-Allow-Origin. Для «непростых» запросов (PUT, DELETE, JSON-тело, свои заголовки) браузер сначала шлёт preflight — OPTIONS с вопросом «можно?».

Важно: CORS — это ослабление ограничений, а не защита сервера. Он не останавливает отправку простых запросов (а значит, CSRF), и не мешает curl или серверу злоумышленника — это проверка только в браузере. Опасная конфигурация — отражать любой Origin вместе с Access-Control-Allow-Credentials: true: тогда любой сайт сможет читать данные пользователя.

Пример

# preflight перед PUT с JSON
OPTIONS /api/profile HTTP/1.1
Origin: https://app.shop.ru
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.shop.ru
Access-Control-Allow-Methods: GET, PUT
Access-Control-Allow-Credentials: true
Vary: Origin

Set-Cookie: session=…; HttpOnly; Secure; SameSite=Lax

Что хотят услышать

  • Механика CSRF: браузер сам прикладывает cookie.
  • Защиты: SameSite, токен, проверка Origin, безопасный GET.
  • Что делает CORS, preflight, и почему он не защищает от CSRF.
  • Опасность Allow-Origin со звёздочкой или отражением при credentials.

Частые ошибки

  • «Включим CORS, и CSRF не страшен».
  • Разрешать Access-Control-Allow-Origin: * для API с cookie-сессией (браузер такое не пропустит с credentials — и начинают отражать любой Origin).

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем