Что такое CSRF и как он связан с CORS?
- Что такое межсайтовая подделка запроса?
- Зачем нужен CSRF-токен?
- Что делает CORS и от чего он не защищает?
- Что такое SameSite у cookie?
CSRF — чужой сайт заставляет браузер жертвы отправить запрос на ваш сайт; браузер сам приложит cookie, и запрос выполнится от имени пользователя. CORS — правила, когда скрипт с одного домена может читать ответы другого.
- Защита от CSRF: cookie SameSite, CSRF-токен, проверка Origin, не менять состояние через GET
- CORS не защищает от CSRF: простой POST с формы уходит и без CORS — запрещено лишь прочитать ответ
- CORS ослабляет политику одного источника, а не усиливает
А ещё С токеном в заголовке Authorization (не в cookie) классического CSRF нет
Подробно
Политика одного источника (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 с токеном в заголовке
AuthorizationCSRF не работает: браузер такой заголовок сам не подставит.
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).
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗CORS запрещает чужим сайтам отправлять любые запросы на ваш домен, поэтому достаточно правильно настроить CORS, и CSRF невозможна
- ✓Чужой сайт отправляет запрос с cookie жертвы; защита — SameSite, токен, проверка Origin
- ✗CSRF — внедрение чужого скрипта на страницу через комментарии пользователей
- ✗Достаточно перевести сайт на HTTPS — запросы с чужих сайтов станут невозможны
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.