Глоссарий
Что такое CSRF (Cross-Site Request Forgery) — как заставить вошедшего пользователя действовать ненамеренно
CSRF (Cross-Site Request Forgery) использует браузер вошедшего пользователя, чтобы отправить запрос, который тот не собирался делать (перевод, изменение настроек), через другой сайт. Как это работает и реальная защита (CSRF-токены, куки SameSite, проверка Origin) — объяснено с точки зрения защиты, без шагов атаки.
«Стоит лишь открыть другой сайт, оставаясь в системе, как без вашего ведома срабатывает перевод или изменение настроек» — это и есть CSRF. Разберём, как он работает и как надёжно его предотвратить (без шагов атаки).
Почему это работает (механизм)
Браузер автоматически прикрепляет куки сайта к запросам к этому сайту. Поэтому если пользователь вошёл в свой банк, запрос к банку, инициированный с вредоносной страницы, всё равно несёт «куки пользователя». Для сервера он неотличим от легитимного действия.
Если XSS «выполняет код в браузере жертвы», то CSRF «заимствует активный сеанс жертвы» (→ Что такое XSS).
Защита
Требуйте CSRF-токен
На действиях, меняющих состояние (отправка форм, API), требуйте непредсказуемый одноразовый токен, выданный сервером; отклоняйте запросы без него. Большинство фреймворков это поставляют.
Установите куки SameSite
Помечайте сеансовые куки SameSite=Lax (или Strict), чтобы куки не прикреплялись к запросам, исходящим с других сайтов. Lax — современное значение по умолчанию и сам по себе сильно помогает.
Не используйте GET для изменений состояния
GET (просмотр) не должен иметь побочных эффектов. Делайте изменения через POST/PUT/DELETE и пропускайте их через проверку токена.
Проверяйте Origin / Referer
Для чувствительных действий убедитесь, что Origin запроса — ваш собственный сайт, и отклоняйте внешние источники.
Мнение этого сайта: в основном «решено», но не расслабляйтесь
CSRF-токены фреймворков плюс значение SameSite=Lax по умолчанию в браузерах резко сократили классический CSRF. И всё же он кусается в самописных API, легаси-настройках и админ-панелях, где про токен забыли. Даже если вы «доверяете это фреймворку», один раз сами проверьте, что пути, меняющие состояние, действительно выполняют проверку токена.
Частые пробелы
Даже зная механизм, реализации обычно проскальзывают в двух местах.
- GET с побочными эффектами: если просматривающий GET меняет состояние, для CSRF достаточно тега изображения или обычной ссылки. Делайте изменения состояния через POST/PUT/DELETE и пропускайте их через проверку токена.
- Забытая проверка токена на части путей: API и админ-функции, добавленные позже, часто пропускают токен. Не считайте, что «во фреймворке это есть» — один раз проинвентаризируйте каждый путь, меняющий состояние.
Читать дальше
- Глоссарий: Что такое XSS · Что такое SSRF
- Основы: Основы безопасности
FAQ
QЧем CSRF отличается от XSS?
XSS выполняет скрипт в браузере жертвы; CSRF использует активный сеанс жертвы, чтобы отправить непреднамеренный запрос. CSRF работает даже без выполнения какого-либо скрипта — просто за счёт того, что браузер автоматически отправляет куки.
QКакая защита от CSRF главная?
Требовать CSRF-токен на запросах, меняющих состояние (POST и т. п.), и устанавливать SameSite (Lax/Strict) на сеансовых куках. Большинство фреймворков поставляют токен по умолчанию. И ещё: никогда не используйте GET для изменений состояния.
QДостаточно ли одного SameSite?
Он сильно помогает, но не панацея. Остаются пробелы на старых браузерах, при некоторых переходах и в части настроек с поддоменами — поэтому сочетайте его с CSRF-токенами для эшелонированной защиты.