Подделка межсайтовых запросов (CSRF)

Подделка межсайтовых запросов (CSRF)

by moiseevrus

Что такое 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.

Еще один вариант предыдущей уязвимости заключается в том, что некоторые приложения не ведут никаких записей о выданных маркерах на стороне сервера, а вместо этого дублируют каждый маркер в файле 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

You may also like

Leave a Comment