Межсайтовая подделка запроса

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

CSRF (англ. Сross Site Request Forgery — «Межсайтовая подделка запроса», также известен как XSRF) — вид атак на посетителей веб-сайтов, использующий недостатки протокола HTTP. Если жертва заходит на сайт, созданный злоумышленником, от её лица тайно отправляется запрос на другой сервер (например, на сервер платёжной системы), осуществляющий некую вредоносную операцию (например, перевод денег на счёт злоумышленника). Для осуществления данной атаки жертва должна быть аутентифицирована на том сервере, на который отправляется запрос, и этот запрос не должен требовать какого-либо подтверждения со стороны пользователя, которое не может быть проигнорировано или подделано атакующим скриптом.

Данный тип атак, вопреки распространённому заблуждению, появился достаточно давно: первые теоретические рассуждения появились в 1988 году[1], а первые уязвимости были обнаружены в 2000 году. A сам термин ввел Peter Watkins в 2001 году.

Основное применение CSRF — вынуждение выполнения каких-либо действий на уязвимом сайте от лица жертвы (изменение пароля, секретного вопроса для восстановления пароля, почты, добавление администратора и т. д.). Также с помощью CSRF возможна эксплуатация отраженных XSS, обнаруженных на другом сервере.

Пример[править | править вики-текст]

Атака осуществляется путём размещения на веб-странице ссылки или скрипта, пытающегося получить доступ к сайту, на котором атакуемый пользователь заведомо (или предположительно) уже аутентифицирован. Например, пользователь Алиса может просматривать форум, где другой пользователь, Мэллори, разместил сообщение. Пусть Мэллори создал тег <img>, в котором в качестве источника картинки указан URL, при переходе по которому выполняется действие на сайте банка Алисы, например:

Мэллори: Привет, Алиса! Посмотри, какой милый котик: <img src="http://bank.example.com/withdraw?account=Alice&amount=1000000&for=Mallory">

Если банк Алисы хранит её информацию об аутентификации в куки и если куки еще не истекли, при попытке загрузить картинку браузер Алисы отправит запрос на перевод денег на счет Мэллори и подтвердит аутентификацию при помощи куки. Таким образом, транзакция будет успешно завершена, хотя её подтверждение произойдет без ведома Алисы.

Защита[править | править вики-текст]

Защищаться должны все запросы изменяющие данные на сервере, а также возвращающие персональные либо иные деликатные данные.

Наиболее простым для понимания способом защиты от данного типа атак является механизм, когда веб-сайты должны требовать подтверждения большинства действий пользователя и проверять поле HTTP_REFERER, если оно указано в запросе. Но этот способ может быть небезопасен, и использовать его не рекомендуется[2].

Другим распространённым способом защиты является механизм, при котором с каждой сессией пользователя ассоциируется дополнительный секретный уникальный ключ, предназначенный для выполнения запросов. Секретный ключ не должен передаваться в открытом виде, например если это POST запрос, то ключ следует передавать в теле запроса, а не в адресе страницы. Пользователь посылает этот ключ среди параметров каждого запроса, и перед выполнением каких-либо действий сервер проверяет этот ключ. Преимуществом данного механизма, по сравнению с проверкой Referer, является гарантированная защита от атак данного типа. Недостатком же являются требование возможности организации пользовательских сессий и требование динамической генерации HTML-кода активных страниц сайта.

Спецификация протокола HTTP/1.1 [3] определяет безопасные методы запросов, такие как GET, HEAD, которые не должны изменять данные на сервере. Для таких запросов, при соответствии сервера спецификации, нет необходимости применять защиту CSRF.

Может возникнуть желание подстраховаться и добавить ключ в каждый запрос, но следует иметь в виду, что спецификация HTTP/1.1 [3] допускает наличие тела для любых запросов, но для некоторых методов запроса (GET, HEAD, DELETE) семантика тела запроса не определена, и должна быть проигнорирована. Поэтому ключ может быть передан только в самом URL, или в HTTP заголовке запроса. Необходимо защитить самого пользователя от неблагоразумного распространения ключа, в составе URL, например на форуме, где он может оказаться доступным злоумышленнику. Поэтому запросы, с ключом в URL, не следует использовать в качестве адреса для перехода, то есть исключить переход по такому адресу клиентским скриптом, перенаправлением сервера, действием формы, гиперссылкой на странице и т.п. с целью сокрытия ключа, входящего в URL. Их можно использовать лишь как внутренние запросы скриптом с использованием XMLHttpRequest или обёрткой, например AJAX.

Существенен факт того, что CSRF токен может быть предназначен не для конкретного запроса или формы, а для всех запросов пользователя вообще. Поэтому достаточно утечки CSRF токена, c URL выполняющим простое действие или не выполняющего действие вовсе, как защиты от подделки запроса лишается любое действие, а не только то с которым связан ставший известным URL.

Существует более жёсткий вариант предыдущего механизма, в котором с каждым действием ассоциируется уникальный одноразовый ключ. Такой способ более сложен в реализации и требователен к ресурсам. Способ используется некоторыми сайтами и порталами, такими как Livejournal, Rambler и др. В настоящий момент (2016 г.) нет сведений о преимуществе более жёсткого варианта, по сравнению с вариантом, где используется единственный для каждой сессии секретный ключ[4].

См. также[править | править вики-текст]

Примечания[править | править вики-текст]

Ссылки[править | править вики-текст]