Найти и обезвредить: CSRF-атака

В прошлых номерах КГ мы рассматривали самые разнообразные уязвимости интернет-ресурсов, такие как XSS, SQL-inj, drive-by атаки, man-in-the- middle и так далее. В этой статье я продолжу рассказ, а говорить буду об CSRF-атаке. А начнем мы, как обычно, с истории :).

Как оно было

Впервые о данном типе уязвимости заговорили в далеком 1988 году, когда Norm Hardy опубликовал документ под заголовком “The confused Deputy: (or why capabilities might have been invented)”, объясняющий подозрительное доверие веб-приложений к принимаемым данным, назвав это явление, как видно из названия заметки, «confused deputy». На практике примеры реализации атак подобного рода были приведены в bugtruck только в 2000-м, когда Jim Fulton написал статью “Client Side Trojan” на сайте zope.org. Сам термин "CSRF " был введен Питером Ваткинсоном в 2001 году, он использовался в его заметке под названием «The Dangers of Allowing Users to Post Images». Почитать оригинальную статью можно по адресу сайт , правда, это можно сделать только владея английским языком. Новая на то время уязвимость получила название Cross-Site Request Forgery (сокращенно CSRF или XSRF), что в переводе на русский означает «подделка межсайтовых запросов». Если вы где-нибудь увидите фразы типа «Session Riding» или «Confused Deputy Attack», не пугайтесь – это всего лишь еще несколько вариантов именования уязвимостей данного класса. Довольно опасным оказался взлом почтового сервиса Gmail в январе 2007-го. С помощью XSRF-атаки можно было украсть контактный список любого пользователя. А теперь представьте, скольким людям можно было разослать спам или вредоносное ПО! В 2008 году подобная уязвимость была обнаружена на сайте New York Times, в конце этого же года на сайте YouTube. Если же говорить простым и понятным всем языком, то CSRF - это вид атак на посетителей веб-сайтов, использующий недостатки протокола HTTP. Возьмем самый простой пример: жертва посещает сайт, созданный злоумышленником, и от ее лица скрытно отправляется запрос на другой сервер. В реальной жизни чаще всего это какие-нибудь платежные системы. В результате такого запроса может быть осуществлена скрытая транзакция ну или что-то в этом духе. Для осуществления данной атаки жертва должна быть авторизована на том сервере, на который отправляется запрос, и этот запрос не должен требовать какого-либо подтверждения со стороны пользователя, который не может быть проигнорирован или подделан атакующим скриптом. Многие ошибочно считают, что данный тип уязвимости тесно связан с Cross-Site Scripting атакой, но это лишь распространенное заблуждение. Единственное, в чем схожи CSRF и XSS, так это использование в качестве вектора атаки клиентов веб-приложений (так называемая Client-Side Attack). В реальной жизни CSRF-атака может эксплуатироваться как совместно с XSS, так и без нее – все же она представляет собой отдельный класс уязвимостей. Хотя вместе они дают более насыщенный функционал для злоумышленника.

Зачем оно надо и как это организовать?

Одно из применений XSRF — эксплуатация пассивных XSS, обнаруженных на другом сервере. Также возможны отправка спама от лица жертвы и изменение каких-либо настроек учетных записей на других сайтах (например, секретного вопроса для восстановления пароля или альтернативного e-mail). Достаточно вспомнить обнаруженный в 2008 году баг на чрезвычайно популярном российском ресурсе ВКонтакте. Используя CRSF-атаку, можно было подменить в любом профиле поле «Веб-сайт». Делалось это с использование скрипта, код которого можно увидеть на рисунке 1:

Если внимательно пересмотреть данный код, то можно заметить, что при запросе картинки по адресу
сайт браузер попытается обратиться к этому URL, в результате чего он непреднамеренно сменит в анкете значение поля «Веб-сайт» на « сайт (смотрим рисунок 2).

И так можно было сменить и другие поля. Вторым примером CSRF-атаки является давно известная (и уже устраненная админами) CSRF-уязвимость на первом почтовом сервисе России Mail.ru, датированная приблизительно 2004 годом. Дыра заключалась в следующем: хакер, будь то злоумышленник или простой пользователь, жаждущий почитать чужую почту, создает специальную web-страничку и размещает ее на каком-нибудь хостинге. Далее он создает письмо, где просит пользователя перейти по ссылке, ведущей на эту страничку, и отсылает его жертве. Последняя, в свою очередь, прочитав почту, наивно переходит по ссылке. В это время скрытый в недрах HTML-тегов скрипт осуществляет подмену альтернативного e-mail на указанный взломщиком. Эти данные передавались на URL сайт методом POST. Код скрипта формы указан на рисунке 3:

Вторым способом смены альтернативного мыла на этом же сервисе является переход жертвы по ссылке, имеющей вид сайт bin/anketa?page=2&Email=test@sa-sec.org. Здесь идет эксплуатация метода GET, где в качестве параметра переменной Email указывается любой почтовый адрес (в нашем случае это test@sa-sec.org). А использовать этот способ можно так же, как и на сайте ВКонтакте. В этом и ранее указанном случаях злоумышленник может получить доступ к почтовому ящику пользователя, просто запросив пасс на страничке восстановления забытого пароля, указав в качестве дополнительного e-mail адрес test@sa-sec.org.

Вообще данный тип уязвимости тем и интересен, что он не является результатом ошибок программистов, а является нормальным поведением web-сервера и браузера. Поэтому ее довольно сложно обнаружить, но защититься все же можно. Как? Читаем дальше.

Организация защиты

Почему-то многие люди считают, что использование метода POST вместо GET поможет защитить веб-приложение от атак подобного рода, но приведенный мною выше пример получения доступа к мылу в пух и прах развевает это распространенное заблуждение. Второй способ – это реализация страниц подтверждения. На самом деле данный способ лишь немного затрудняет осуществление атаки тем, что необходимо делать два запроса вместо одного. Для качественной защиты от данного типа атак веб-сайты должны требовать подтверждения большинства действий пользователя и проверять поле HTTP referer, если оно указано в запросе.

Лучше всего использовать случайный идентификатор, именуемый маркером доступа (token), который генерируется для каждой операции и необходим для ее выполнения. Он помогает эффективно различать запросы, что защищает сайт от CSRF-атак. Код генерации (пишем его, естественно, на PHP) такого маркера выглядит примерно следующим образом:

<<
$token = md5(uniqid(mt_rand() . microtime()));

$_SESSION['token'] = $token;

?>>>

Случайный маркер в нашем случае создается на основе MD5 хешировании метки времени (функция microtime) и случайного числа (функция mt_rand), после чего записывается в массив $_SESSION. Далее в каждой форме на сайте добавляем hidden-поле с идентификатором:

<<>>

После чего в каждом запросе необходимо проверять корректность маркера доступа:

<<
$token = $_POST['token'];

if ($_SESSION['token'] == $token) {

$_SESSION['token'] = '';

/* Выполняем требуемые операции */

} else {

die("404 Not Found!");

}

?>>>

Анализируя код, мы видим, что изначально в переменную $token записывается значение маркера доступа. Далее идет сравнение его с оригиналом и в случае совпадения — выполнение требуемых действий. Если же наш токен оказался неверным (видимо, CSRF-атака), то прекращаем выполнение сценария и выдаем ошибку (функция die). Данный метод очень прост в реализации, но очень эффективен для защиты. Еще одно необходимое действие, которое необходимо провести, это хорошенько проверить сайт на наличие XSS-уязвимостей, ведь, как я говорил ранее, связка этих двух компонентов вполне реальна и довольна эффективна.

Насколько велика угроза?

Данные, полученные компанией Positive Technologies (я думаю, ее много кто знает хотя бы по программе XSpider) в ходе работ по тестированию на проникновение и оценки защищенности веб-приложений, показывают, что этой уязвимости подвержена большая часть веб-приложений. А что это может означать? То, что большая часть форумов, почтовых сервисов и подобных ресурсов не в состоянии удержать наши конфиденциальные данные от злоумышленников. Поэтому будьте бдительны, и если будете создавать свой сайт, не поленитесь защитить себя от XSRF-атак, ведь это несложно ;).

P.S.: Информация предоставлена исключительно для ознакомления и изучения. Автор не несет ответственности за использование данной информации в злонамеренных целях.

Никита Булай


Компьютерная газета. Статья была опубликована в номере 26 за 2009 год в рубрике безопасность

©1997-2022 Компьютерная газета
oJnWE3?=нD}{DfHM=|]| ,Rh٣ <Ļi՛)^l`6=Rep9oyB~{<@- $ 3?:͜i*Ifgf$;9'yUw9Z.N#ҧcxS`np^i㺔o; :_].mC[tTbH)n̳\jzskV[CMͿ v}\I?lI_ }:7„CzhrE