CSRF произносится как sea-surf.
Cross-Site Request Forgery.
Межсайтовая подделка запроса.
❓ В чем суть кейса?
🔴 Злоумышленник делает лжесайт, например:
bank-darit-million-rublei.ru
внутри которого будут скрытые HTML-формы. JS-скрипт будет с этих форм отправлять запросы на настоящий сайт банка. Злоумышленник рассчитывает, что пользователь прямо сейчас на нем авторизован.
🔴 По-скольку пользователь авторизован, то у него есть активная сессия и куки. JS-скрипт выполняется. В банке, в личном кабинете человека, отправляется запрос, например, на перевод денег со счета клиента.
🔴 Злоумышленник улетает на Кипр, человек остается с опытом. ИТ-отдел получает ремня.
Вредоносная CSRF-форма не крадет ваши данные, например, логин и пароль!
Она заставляет ваш браузер отправить запрос на другой сайт без вашего ведома.
Для кражи данных потребуется связка CSRF + XSS (Кросс-сайтовый скриптинг).
❓ Как защититься?
Есть разные способы. Основной — это использовать CSRF-токен.
Сервер генерирует уникальное непредсказуемое значение и отдает его на клиент. Сохраняется в cookie, оттуда встраивается в формы. Когда поступает запрос на изменение данных (POST / PUT / PATCH / DELETE, а также поломанный GET, у которого убрана идемпотентность), сервер сверяет токен который выдал с пришедшим в запросе.
Если совпал — сервер выполняет действие (переводит деньги, меняет логин-пароль и т.д.).
Мошенник же отправляет HTTP-запрос с собственной HTML-формы, не имеющей CSRF-токена. Поэтому такой запрос не будет обработан. В этом и заключается защита.
❓ Почему вредоносный сайт не может узнать CSRF-токена?
Чужой токен нельзя узнать со стороннего домена. В браузерах по-умолчанию реализована Same-Origin Policy (SOP, политика одного источника). CSRF-токен параметром формы передается. Чтобы он туда попал, нужно прочитать чужие cookie, и этого браузер не даст сделать. Если бы давал, то мошенник использовал бы ваши cookie аутентификации чтобы залогиниться в ваш аккаунт в соцсети и т.д.
❓ Как выглядит HTML-форма?
Пример формы на изменение email:
<html>
<body>
<form action="https://vulnerable-website.com/email/change" method="POST">
<input type="hidden" name="email" value="pwned@evil-user.net" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
❓ Как CSRF-атака становится возможной?
Должны быть выполнены все 3 условия:
🔴 Сервис предоставляет целевое действие.
Тут все очевидно: приложение или сайт должны уметь делать то, что хочет мошенник. Изменить пароль или сделать денежный перевод...
🔴 Сессии обрабатываются только на основе cookie.
Сайт или приложение идентифицируют пользователя только на основе cookie сессии, и никак больше.
🔴 Нет неизвестных параметров.
Мошенник хочет сменить вам пароль. Форма на сайте просит ввести текущий пароль. Откуда его знать мошеннику?
❓ Какими "слоями" еще защититься?
Проверять на сервере заголовки Origin и Referer, для подтверждения того, что запрос пришел с настоящего сайта.
Origin, это комбинация протокол + домен + порт, и он отправляется браузером, его значения нельзя подставить самому. Он сообщает серверу, с какого ресурса пришёл запрос.
Referer содержит URL страницы, с которой вы попали на текущую.
Настроить свойство SameSite=Strict в cookie. Так браузер не будет отправлять cookie при межсайтовом запросе.
❓ Где попрактиковаться?
Пощупать атаку можно на PortSwigger. Там есть видео с решениями задач + текстовое описание решения (Solution). Из минусов - изучение платформы займет некоторое время. Стоит скачать прогу Burp Suit (можно бесплатную community-версию).
❓ Что еще почитать?
Про CSRF написано очень много. Вот замечательные технические статьи, которые позволяют лучше понять суть:
⚡️ Описание на PortSwigger
⚡️ CSRF атака: механика эксплуатации, обход защит и построение PoC
⚡️ Межсайтовая подделка запроса (CSRF): Находим и обезвреживаем. Гайд для начинающих
Понравился пост? Подписывайся, чтобы не пропустить следующий.
Артем Лещев