Contents
Что такое CSRF?
Подделка межсайтовых запросов (также известная как CSRF) — это уязвимость веб-безопасности, которая позволяет злоумышленнику побуждать пользователей выполнять действия, которые они не намерены выполнять. Это позволяет злоумышленнику частично обойти одну и ту же политику происхождения, которая предназначена для предотвращения взаимодействия разных веб-сайтов друг с другом.
Лаборатории
Если вы уже знакомы с основными понятиями, лежащими в основе CSRF-уязвимостей, и просто хотите попрактиковаться в их использовании на некоторых реалистичных, преднамеренно уязвимых целях, вы можете получить доступ ко всем лабораторным работам в этом разделе по ссылке ниже.
Каково влияние CSRF-атаки?
При успешной атаке CSRF злоумышленник заставляет пользователя-жертву непреднамеренно выполнить действие. Например, это может быть изменение адреса электронной почты в их учетной записи, изменение пароля или перевод средств. В зависимости от характера действия злоумышленник может получить полный контроль над учетной записью пользователя. Если скомпрометированный пользователь имеет привилегированную роль в приложении, злоумышленник может получить полный контроль над всеми данными и функциями приложения.
Как работает CSRF?
Чтобы CSRF-атака была возможной, должны быть соблюдены три ключевых условия:
- Актуальное действие. В приложении есть действие, которое у злоумышленника есть причина вызвать. Это может быть привилегированное действие (например, изменение разрешений для других пользователей) или любое действие с данными пользователя (например, изменение собственного пароля пользователя).
- Обработка сеансов на основе файлов cookie. Выполнение действия включает в себя отправку одного или нескольких HTTP-запросов, и приложение полагается исключительно на файлы cookie сеанса для идентификации пользователя, отправившего запросы. Другого механизма для отслеживания сеансов или проверки пользовательских запросов не существует.
- Нет непредсказуемых параметров запроса. Запросы, выполняющие действие, не содержат параметров, значения которых злоумышленник не может определить или угадать. Например, когда пользователь заставляет пользователя изменить свой пароль, функция не уязвима, если злоумышленнику необходимо знать значение существующего пароля.
Например, предположим, что приложение содержит функцию, которая позволяет пользователю изменить адрес электронной почты в своей учетной записи. Когда пользователь выполняет это действие, он делает HTTP-запрос, подобный следующему:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE
email=wiener@normal-user.com
Это соответствует условиям, необходимым для CSRF:
- Действие по изменению адреса электронной почты в учетной записи пользователя представляет интерес для злоумышленника. После этого действия злоумышленник, как правило, сможет инициировать сброс пароля и получить полный контроль над учетной записью пользователя.
- Приложение использует файл cookie сеанса, чтобы определить, какой пользователь выдал запрос. Других токенов или механизмов для отслеживания сеансов пользователей не существует.
- Злоумышленник может легко определить значения параметров запроса, необходимые для выполнения действия.
С учетом этих условий злоумышленник может создать веб-страницу, содержащую следующий HTML-код:
<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>
Если пользователь-жертва посещает веб-страницу злоумышленника, происходит следующее:
- Страница злоумышленника инициирует HTTP-запрос к уязвимому веб-сайту.
- Если пользователь авторизовался на уязвимом веб-сайте, его браузер автоматически включит файл cookie сеанса в запрос (при условии , что файлы cookie SameSite не используются).
- Уязвимый веб-сайт обработает запрос обычным образом, расценит его как сделанный пользователем-жертвой и изменит его адрес электронной почты.
Примечание
Хотя CSRF обычно описывается в связи с обработкой сеансов на основе файлов cookie, он также возникает в других контекстах, когда приложение автоматически добавляет некоторые учетные данные пользователя в запросы, такие как базовая аутентификация HTTP и аутентификация на основе сертификатов.
Как построить CSRF-атаку
Создание вручную HTML-кода, необходимого для эксплойта CSRF, может быть громоздким, особенно если желаемый запрос содержит большое количество параметров или в запросе есть другие особенности. Самый простой способ создать эксплойт CSRF — использовать генератор CSRF PoC , встроенный в Burp Suite Professional :
- Выберите запрос в любом месте Burp Suite Professional, который вы хотите протестировать или использовать.
- В контекстном меню, вызываемом правой кнопкой мыши, выберите Инструменты взаимодействия / Создать CSRF PoC.
- Burp Suite сгенерирует некоторый HTML-код, который инициирует выбранный запрос (за исключением файлов cookie, которые будут автоматически добавлены браузером жертвы).
- Вы можете настроить различные параметры в генераторе PoC CSRF, чтобы точно настроить аспекты атаки. Вам может понадобиться сделать это в некоторых необычных ситуациях, чтобы иметь дело с причудливыми особенностями запросов.
- Скопируйте сгенерированный HTML-код на веб-страницу, просмотрите его в браузере, авторизованном на уязвимом веб-сайте, и проверьте, успешно ли выполняется предполагаемый запрос и выполняется ли желаемое действие.
Как доставить эксплойт CSRF
Механизмы доставки для атак с подделкой межсайтовых запросов практически такие же, как и для отраженных XSS . Как правило, злоумышленник размещает вредоносный HTML-код на контролируемом им веб-сайте, а затем побуждает жертв посетить этот веб-сайт. Это можно сделать, предоставив пользователю ссылку на веб-сайт по электронной почте или в сообщении в социальных сетях. Или, если атака размещена на популярном веб-сайте (например, в комментарии пользователя), они могут просто подождать, пока пользователи не посетят веб-сайт.
Обратите внимание, что некоторые простые эксплойты CSRF используют метод GET и могут быть полностью автономными с одним URL-адресом на уязвимом веб-сайте. В этой ситуации злоумышленнику может не понадобиться использовать внешний сайт, и он может напрямую передать жертве вредоносный URL-адрес в уязвимом домене. В предыдущем примере, если запрос на изменение адреса электронной почты можно выполнить с помощью метода GET, то автономная атака будет выглядеть так:
<img src="https://vulnerable-website.com/email/change?email=pwned@evil-user.net">
Предотвращение CSRF-атак
Самый надежный способ защиты от CSRF-атак — включение токена CSRF в соответствующие запросы. Токен должен быть:
- Непредсказуемый с высокой энтропией, как для сессионных токенов в целом.
- Привязан к сеансу пользователя.
- Строго проверяется в каждом случае перед выполнением соответствующего действия.
Распространенные CSRF-уязвимости
Наиболее интересные CSRF-уязвимости возникают из-за ошибок, допущенных при проверке CSRF-токенов .
В предыдущем примере предположим, что приложение теперь включает токен CSRF в запрос на изменение электронной почты пользователя:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm
csrf=WfF1szMUHhiokx9AHFply5L2xAOfjRkE&email=wiener@normal-user.com
Это должно предотвратить атаки CSRF, поскольку нарушает необходимые условия для уязвимости CSRF: приложение больше не полагается исключительно на файлы cookie для обработки сеанса, а запрос содержит параметр, значение которого злоумышленник не может определить. Однако существуют различные способы взлома защиты, а это означает, что приложение по-прежнему уязвимо для CSRF.
Проверка токена CSRF зависит от метода запроса
Некоторые приложения правильно проверяют токен, когда запрос использует метод POST, но пропускают проверку, когда используется метод GET.
В этой ситуации злоумышленник может переключиться на метод GET, чтобы обойти проверку и провести CSRF-атаку:
GET /email/change?email=pwned@evil-user.net HTTP/1.1
Host: vulnerable-website.com
Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm
Проверка токена CSRF зависит от наличия токена
Некоторые приложения правильно проверяют маркер, если он присутствует, но пропускают проверку, если маркер отсутствует.
В этой ситуации злоумышленник может удалить весь параметр, содержащий токен (а не только его значение), чтобы обойти проверку и провести CSRF-атаку:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm
email=pwned@evil-user.net
Токен CSRF не привязан к сеансу пользователя
Некоторые приложения не проверяют, принадлежит ли токен тому же сеансу, что и пользователь, выполняющий запрос. Вместо этого приложение поддерживает глобальный пул выпущенных им токенов и принимает любые токены, которые появляются в этом пуле.
В этой ситуации злоумышленник может войти в приложение, используя свою учетную запись, получить действительный токен, а затем передать этот токен пользователю-жертве в своей CSRF-атаке.
В варианте предыдущей уязвимости некоторые приложения привязывают токен CSRF к файлу cookie, но не к тому же файлу cookie, который используется для отслеживания сеансов. Это может легко произойти, когда приложение использует две разные платформы, одну для обработки сеансов и одну для защиты CSRF, которые не интегрированы вместе:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Cookie: session=pSJYSScWKpmC60LpFOAHKixuFuM4uXWF; csrfKey=rZHCnSzEp8dbI6atzagGoSYyqJqTz5dv
csrf=RhV7yQDO0xcq9gLEah2WVbmuFqyOq7tY&email=wiener@normal-user.com
Эту ситуацию труднее использовать, но она по-прежнему уязвима. Если веб-сайт содержит какое-либо поведение, позволяющее злоумышленнику установить файл cookie в браузере жертвы, возможна атака. Злоумышленник может войти в приложение, используя свою учетную запись, получить действительный токен и связанный файл cookie, использовать поведение настройки файлов cookie, чтобы поместить свой файл cookie в браузер жертвы, и передать свой токен жертве в своей CSRF-атаке.
Примечание
Поведение настройки файлов cookie даже не обязательно должно существовать в том же веб-приложении, что и CSRF-уязвимость. Любое другое приложение в пределах того же общего домена DNS потенциально может быть использовано для установки файлов cookie в целевом приложении, если контролируемый файл cookie имеет подходящую область действия. Например, функция установки файлов cookie staging.demo.normal-website.com
может использоваться для размещения файла cookie, отправленного в secure.normal-website.com
.
Токен CSRF просто дублируется в куки
Еще один вариант предыдущей уязвимости заключается в том, что некоторые приложения не ведут никаких записей о выданных маркерах на стороне сервера, а вместо этого дублируют каждый маркер в файле cookie и параметре запроса. Когда последующий запрос проверяется, приложение просто проверяет, что токен, отправленный в параметре запроса, соответствует значению, указанному в файле cookie. Это иногда называют защитой от CSRF «двойной отправки», и ее рекомендуют, потому что она проста в реализации и позволяет избежать необходимости в каком-либо состоянии на стороне сервера:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Cookie: session=1DQGdzYbOJQzLP7460tfyiv3do7MjyPw; csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa
csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa&email=wiener@normal-user.com
В этой ситуации злоумышленник может снова выполнить атаку CSRF, если веб-сайт содержит какие-либо функции настройки файлов cookie. Здесь злоумышленнику не нужно получать собственный действительный токен. Они просто изобретают токен (возможно, в требуемом формате, если он проверяется), используют поведение настройки файлов cookie, чтобы поместить свой файл cookie в браузер жертвы, и передают свой токен жертве в своей CSRF-атаке.
Защита от CSRF на основе рефералов
Помимо средств защиты, использующих токены CSRF, некоторые приложения используют Referer
заголовок HTTP, чтобы попытаться защититься от атак CSRF, обычно путем проверки того, что запрос исходит из собственного домена приложения. Этот подход, как правило, менее эффективен и часто подлежит обходным путям.
См. заголовок
Заголовок HTTP Referer (который случайно написан с ошибкой в спецификации HTTP) — это необязательный заголовок запроса, который содержит URL-адрес веб-страницы, связанной с запрашиваемым ресурсом. Как правило, он автоматически добавляется браузерами, когда пользователь запускает HTTP-запрос, в том числе щелкая ссылку или отправляя форму. Существуют различные методы, которые позволяют странице ссылки скрывать или изменять значение Referer
заголовка. Часто это делается из соображений конфиденциальности.
Проверка Referer зависит от наличия заголовка
Некоторые приложения проверяют Referer
заголовок, если он присутствует в запросах, но пропускают проверку, если заголовок опущен.
В этой ситуации злоумышленник может создать свой эксплойт CSRF таким образом, что браузер пользователя-жертвы отбросит Referer
заголовок в результирующем запросе. Этого можно добиться разными способами, но самый простой — использовать META-тег на HTML-странице, на которой размещена CSRF-атака:
<meta name="referrer" content="never">
Валидацию Referer можно обойти
Некоторые приложения проверяют Referer
заголовок наивным способом, который можно обойти. Например, если приложение проверяет, что домен Referer
начинается с ожидаемого значения, злоумышленник может поместить это как поддомен своего собственного домена:
http://vulnerable-website.com.attacker-website.com/csrf-attack
Аналогичным образом, если приложение просто подтверждает, что Referer
содержит собственное доменное имя, злоумышленник может поместить требуемое значение в другое место в URL-адресе:
http://attacker-website.com/csrf-attack?vulnerable-website.com
Примечание
Хотя вы можете определить это поведение с помощью Burp, вы часто обнаружите, что этот подход больше не работает, когда вы начинаете тестировать свою концепцию в браузере. Пытаясь снизить риск утечки конфиденциальных данных таким образом, многие браузеры теперь Referer
по умолчанию удаляют строку запроса из заголовка.
Вы можете переопределить это поведение, убедившись, что ответ, содержащий ваш эксплойт, имеет установленный Referrer-Policy: unsafe-url
заголовок (обратите внимание, что Referrer
в этом случае он написан правильно, просто чтобы убедиться, что вы обращаете внимание!). Это гарантирует, что будет отправлен полный URL-адрес, включая строку запроса.
Статья является переводом portswigger.net