CSRF-атака - это метод, при котором злоумышленник заставляет браузер выполнять действия на сайте от имени пользователя без его ведома. В статье разъясняются механизмы атаки, роль cookies, способы защиты с помощью CSRF-токенов и других мер, а также различие между CSRF и XSS.
CSRF-атака - это способ заставить браузер авторизованного пользователя выполнить действие на сайте без его явного согласия. При этом злоумышленнику необязательно знать пароль, перехватывать сессию или напрямую получать доступ к аккаунту: достаточно воспользоваться тем, что браузер уже считает пользователя вошедшим в систему.
Название CSRF расшифровывается как Cross-Site Request Forgery - "подделка межсайтовых запросов". Суть атаки в том, что вредоносная страница или ссылка инициирует запрос к другому сайту, а браузер может автоматически добавить к нему данные авторизации, например сессионные cookies. Если сервер не проверяет происхождение такого запроса, он способен принять его за обычное действие владельца аккаунта.
Поэтому CSRF особенно опасен для операций, которые меняют данные: настройки профиля, адрес электронной почты, параметры аккаунта или другие важные действия. Разберём, почему такая атака вообще возможна, какую роль играют cookies и как CSRF-токены помогают отличить настоящий запрос пользователя от поддельного.
CSRF-атака использует ситуацию, когда пользователь уже авторизован на сайте, а браузер хранит данные его сессии. Например, человек вошёл в интернет-магазин, корпоративную панель или другой сервис и не выходил из аккаунта. Пока сессия активна, браузер продолжает автоматически подтверждать запросы к этому сайту.
Если в этот момент пользователь откроет специально подготовленную страницу, нажмёт вредоносную ссылку или загрузит встроенный элемент с чужого сайта, браузер может отправить запрос к сервису, где пользователь уже вошёл в аккаунт. Сам пользователь при этом может даже не видеть, что выполняется какое-либо действие.
Опасность возникает тогда, когда сервер проверяет только факт наличия действующей сессии, но не убеждается, что запрос действительно был инициирован пользователем через интерфейс самого сайта.
Упрощённо схема выглядит так: пользователь входит в аккаунт, получает активную сессию, затем посещает стороннюю страницу, которая инициирует запрос к целевому сервису. Браузер прикладывает к запросу данные авторизации, а сервер воспринимает его как действие владельца аккаунта.
Полное название CSRF - Cross-Site Request Forgery, что обычно переводят как "подделка межсайтовых запросов". Термин хорошо описывает суть атаки: запрос создаётся на одном сайте, но направляется на другой от имени уже авторизованного пользователя.
При этом важно различать саму атаку и CSRF-уязвимость. CSRF-атака - это попытка заставить браузер выполнить нежелательное действие. CSRF-уязвимость - ошибка в логике веб-приложения, из-за которой сервер принимает такой запрос без дополнительной проверки.
Сам по себе браузер здесь не работает неправильно. Он выполняет стандартное поведение: отправляет cookies и другие данные, связанные с доменом, в соответствии с настройками безопасности. Проблема появляется на стороне приложения, если оно считает наличие действующей сессии достаточным доказательством того, что действие действительно инициировал пользователь.
Поэтому CSRF не обязательно связан с кражей пароля или взломом учётной записи. Злоумышленник использует уже существующую авторизацию жертвы и пытается заставить браузер выполнить допустимое для этого пользователя действие в неподходящий момент.
После входа в аккаунт сайт обычно создаёт сессию и связывает её с браузером через cookie. При следующих обращениях к этому же домену браузер может автоматически прикладывать cookie к запросу, поэтому пользователю не приходится вводить логин и пароль заново при каждом действии.
Этим поведением и пользуется CSRF-атака. Сторонняя страница может попытаться инициировать запрос к сайту, где пользователь уже авторизован. Если условия позволяют браузеру отправить вместе с ним сессионные cookies, сервер увидит действующую авторизацию и может принять запрос за легитимный.
Ключевая проблема в том, что наличие правильной cookie подтверждает сессию, но само по себе не доказывает, что пользователь действительно хотел выполнить конкретное действие. Если приложение не использует дополнительные проверки, злоумышленник может попытаться воспользоваться этим разрывом между авторизацией и подтверждением намерения.
Представим сервис, в котором авторизованный пользователь может изменить настройки аккаунта. Если сервер принимает запрос на изменение данных только на основании активной сессии, сторонняя страница теоретически может попытаться инициировать такой же запрос.
Пользователь при этом просто открывает чужой сайт, а браузер взаимодействует с целевым сервисом в фоновом режиме. Для сервера запрос выглядит так, будто его отправил уже вошедший в систему клиент.
При этом злоумышленник не обязательно получает доступ к ответу сервера или содержимому аккаунта. В классическом сценарии CSRF основная цель - не прочитать чужие данные, а заставить систему выполнить действие от имени жертвы.
Наиболее критичны запросы, которые меняют состояние системы. Это может быть изменение контактных данных, настроек безопасности, параметров профиля или выполнение действий в административной панели.
Риск особенно велик, если подобные операции не требуют дополнительного подтверждения и выполняются сразу после получения запроса. Чем больше полномочий у пользователя, тем серьёзнее могут быть последствия: CSRF в обычном аккаунте и CSRF в учётной записи администратора имеют совершенно разный потенциальный ущерб.
Поэтому важные операции должны проверяться не только по факту действующей сессии. Серверу нужен дополнительный признак того, что запрос действительно сформирован доверенным интерфейсом и инициирован самим пользователем.
CSRF-токен - это дополнительное значение, которое сервер ожидает получить вместе с чувствительным запросом. Обычно оно генерируется отдельно для пользователя, сессии или конкретной формы и передаётся в страницу, с которой выполняется действие.
Когда пользователь отправляет форму или меняет настройки через обычный интерфейс сайта, браузер передаёт токен обратно серверу. Сервер сравнивает полученное значение с ожидаемым и только после успешной проверки выполняет операцию.
За счёт этого одной действующей сессии уже недостаточно. Даже если браузер автоматически приложит сессионную cookie, запрос без корректного CSRF-токена будет отклонён.
Сторонний сайт не должен иметь свободного доступа к содержимому страницы другого домена. Поэтому он может попытаться инициировать запрос, но обычно не может просто прочитать CSRF-токен из формы целевого сервиса и подставить его в поддельный запрос.
Именно здесь появляется главное отличие от обычной cookie. Сессионная cookie часто отправляется браузером автоматически в соответствии с её настройками, а CSRF-токен должен быть явно включён в запрос самим приложением.
Если значение токена невозможно предугадать и сервер действительно проверяет его перед выполнением операции, подделка запроса становится значительно сложнее. Простого факта, что пользователь уже вошёл в аккаунт, недостаточно.
Дополнительную защиту дают настройки cookies. Атрибут SameSite позволяет ограничивать отправку cookies в межсайтовых сценариях и тем самым уменьшать вероятность того, что сторонняя страница сможет использовать активную сессию пользователя.
Сервер также может проверять заголовки Origin или Referer, чтобы определить, откуда пришёл запрос. Такие проверки полезны как дополнительный уровень защиты, особенно для операций, которые должны выполняться только со страниц самого сервиса.
Для наиболее чувствительных действий применяют повторное подтверждение личности: например, повторный ввод пароля, одноразовый код или отдельное подтверждение операции. В таком случае даже наличие активной сессии и попытка подделать запрос не должны автоматически приводить к выполнению критичного действия.
При CSRF-атаке злоумышленник пытается воспользоваться уже существующей авторизацией пользователя. Браузер может отправить запрос к сайту вместе с сессионными cookies, а сервер - принять его как действие владельца аккаунта.
Главная особенность CSRF в том, что вредоносный код не обязательно выполняется внутри самого целевого сайта. Атака может начинаться на сторонней странице, которая пытается заставить браузер обратиться к другому сервису от имени пользователя.
XSS, или Cross-Site Scripting, работает иначе. Здесь проблема возникает, когда сайт позволяет внедрить и выполнить посторонний JavaScript в контексте своей страницы.
Если такой скрипт запускается, он получает доступ к возможностям, которые браузер разрешает коду этого сайта. В зависимости от типа уязвимости это может позволить изменять содержимое страницы, перехватывать действия пользователя или выполнять запросы от его имени.
В CSRF злоумышленник обычно не получает прямой доступ к содержимому страницы целевого сайта. Его задача - заставить браузер отправить определённый запрос. В XSS вредоносный код уже выполняется внутри доверенного сайта, поэтому потенциальные возможности атаки значительно шире.
CSRF-токены хорошо защищают от подделки запросов со сторонних сайтов, но не решают проблему XSS. Если злоумышленник уже смог выполнить JavaScript непосредственно на странице уязвимого приложения, такой скрипт во многих случаях способен взаимодействовать с интерфейсом сайта и его защитными механизмами.
Обратная ситуация тоже справедлива. Защита от XSS с помощью экранирования данных, фильтрации ввода и Content Security Policy не заменяет проверку CSRF-токенов и настройку SameSite cookies.
Поэтому CSRF и XSS относятся к разным классам веб-уязвимостей. Они могут приводить к похожим последствиям, например выполнению действий от имени пользователя, но используют разные механизмы и требуют разных способов защиты.
Защита от CSRF начинается с правильной логики веб-приложения. Запросы, которые изменяют данные пользователя или состояние системы, не должны выполняться только потому, что браузер прислал действующую сессионную cookie.
Особенно важно не использовать GET-запросы для операций, которые что-либо меняют. GET должен применяться для получения данных, а изменение настроек, удаление информации, оформление операций и другие действия лучше выполнять через методы вроде POST, PUT, PATCH или DELETE вместе с дополнительной проверкой запроса.
При этом одного выбора правильного HTTP-метода недостаточно. Если сервер всё равно доверяет только активной сессии, CSRF-уязвимость может сохраниться. Поэтому чувствительные запросы должны проходить отдельную проверку происхождения или содержать подтверждающее значение.
Один из основных способов защиты - CSRF-токены. Сервер генерирует непредсказуемое значение и ожидает его вместе с запросом. Сторонняя страница обычно не может узнать правильный токен, поэтому даже при наличии активной сессии поддельный запрос будет отклонён.
Дополнительный уровень защиты даёт атрибут SameSite у cookies. Он ограничивает передачу cookie в межсайтовых сценариях и снижает вероятность того, что браузер автоматически приложит данные авторизации к запросу, инициированному другим сайтом.
CSRF-токены и SameSite лучше рассматривать не как взаимозаменяемые решения, а как разные уровни защиты. Токен подтверждает легитимность самого запроса, а политика SameSite ограничивает автоматическую отправку cookies между сайтами.
CSRF - лишь один из классов веб-уязвимостей. Например, при SQL-инъекции злоумышленник пытается воздействовать уже не на браузер пользователя, а на запросы приложения к базе данных. Подробнее этот механизм разобран в материале SQL-инъекция: что это такое, как работает и как защитить сайт.
Для особенно важных действий одной проверки CSRF-токена может быть недостаточно. Изменение пароля, привязка нового способа восстановления доступа, управление правами или другие критичные операции могут требовать повторного подтверждения личности.
Это может быть повторный ввод пароля, одноразовый код или отдельное подтверждение действия. Такой подход уменьшает риск того, что случайно отправленный или подделанный запрос сразу приведёт к серьёзным изменениям в аккаунте.
Дополнительно сервер может анализировать заголовки Origin и Referer. Они помогают определить, с какого сайта пришёл запрос, и отклонить обращения из неожиданных источников. Но эти проверки обычно лучше использовать как дополнительный механизм, а не как единственную защиту.
Надёжная защита строится сразу на нескольких уровнях: корректная работа с HTTP-методами, CSRF-токены, SameSite cookies, проверка происхождения запросов и дополнительное подтверждение критичных действий.
CSRF-атака использует не взлом пароля, а доверие сайта к уже авторизованному браузеру. Если пользователь вошёл в аккаунт, а сервер считает наличие действующей сессии достаточным подтверждением любого действия, сторонняя страница может попытаться инициировать запрос от его имени.
Основная защита строится вокруг CSRF-токенов, которые позволяют серверу проверить, что запрос сформирован самим приложением. Дополнительно используются SameSite cookies, проверка Origin и Referer, корректные HTTP-методы и повторное подтверждение наиболее критичных операций.
Для разработчика главное правило простое: наличие действующей сессии ещё не означает, что пользователь действительно инициировал запрос. Если приложение изменяет данные, сервер должен отдельно проверять легитимность такого действия.