13.03.2007

Cross-Site Request Forgery – много шума из-за ничего

image

В последнее время в сообществе специалистов по безопасности Web-приложений широко обсуждается «новый» тип уязвимостей, получивший название Cross-Site Request Forgery (CSRF или XSRF). Предлагаемая вниманию читателя статья содержит описание этого типа уязвимостей, методов его использования и основные походы к защите.

Сергей Гордейчик

gоrdey @ ptsеcurity com

В последнее время в сообществе специалистов по безопасности Web-приложений широко обсуждается «новый» тип уязвимостей, получивший название Cross-Site Request Forgery (CSRF или XSRF). Предлагаемая вниманию читателя статья содержит описание этого типа уязвимостей, методов его использования и основные походы к защите. Общепринятый русский термин для обозначения Cross-Site Request Forgery ещё не устоялся, в связи с чем автор предлагает использовать вариант «Подделка HTTP-запросов».

Лирическое отступление

Прежде всего, хотелось бы остановиться на основных заблуждениях связанных с CSRF:

1. Подделка HTTP-запросов – новый тип уязвимостей.

Это далеко не так. Теоретические размышления на тему подделки источника сообщений датированы 1988 годом (http://www.cis.upenn.edu/~KeyKOS/ConfusedDeputy.html), а практические примеры уязвимостей обсуждаются в Bugtraq как минимум с 2000 года (http://www.zope.org/Members/jim/ZopeSecurity/ClientSideTrojan). Сам термин введен Peter Watkins (http://www.securiteam.com/securitynews/5FP0C204KE.html) в 2001 году.

2. CSRF – это вариант Межсайтового выполнения сценариев (XSS).

Единственное сходство между CSRF и XSS, это использование в качестве вектора атаки клиентов Web-приложений (Client-Side Attack в терминологии WASC http://www.webappsec.org/projects/threat/). Уязвимости типа CSRF могут эксплуатироваться совместно с XSS или «редиректорами» (http://www.securitylab.ru/analytics/283136.php), но представляют собой отдельный класс уязвимостей.

3. Уязвимость CSRF мало распространена и достаточно сложна в использовании.

Данные, полученные компанией Positive Technologies в ходе работ по тестированию на проникновение и оценки защищенности Web-приложений показывают, что этой уязвимости подвержена большая часть Web-приложений. В отличие от других уязвимостей CSRF возникает не в результате ошибок программирования, а является нормальным поведением Web-сервера и браузера. Т.е. большинство сайтов, использующих стандартную архитектуру уязвимы «по умолчанию».

Пример использования

Давайте рассмотрим использование CSRF на примере. Предположим, существует некое Web-приложение, отправляющее сообщения электронной почты. Пользователь указывает адрес электронной почты и текст сообщения, нажимает кнопку Submit и сообщение от его адреса передается получателю.



Рис. 1. Отправка сообщения

Схема знакома по множеству сайтов и не вызывает никаких возражений. Однако указанное приложение с большой вероятности уязвимо для атак «Подделка HTTP-запроса». Для эксплуатации уязвимости злоумышленник может создать на своем сайте страницу содержащую ссылку на «изображение», после чего заставить пользователя перейти по ссылке на свой сайт (например, http://bh.ptsecurity.ru/xcheck/csrf.htm). <img src="http://test.ptsecurity.ru/xcheck/send.asp?to=user@example.com&mess=Spam+The">

При обращении к странице браузер пользователя пытается загрузить изображение, для чего обращается к уязвимому приложению, т.е. оправляет сообщение электронной почты адресату, указанному в поле «to» запроса.



Рис. 2. Атака CSRF

Обратите внимание, что браузер пользователя отправит сайту значение Cookie, т.е. запрос будет воспринят как исходящий от аутентифицированного пользователя. Для того чтобы заставить пользователя загрузить страницу, отправляющую запрос к уязвимому серверу, злоумышленник может использовать методы социальной инженерии, а также технические уязвимости, такие как XSS и ошибки в реализации функции перенаправления.



Рис. 3. Логика работы CSRF

Таким образом, атака с использованием CSRF заключается в использовании браузера пользователя для передачи HTTP-запросов произвольным сайтам, а уязвимость – в отсутствии проверки источника HTTP-запроса. Приведенное в примере приложение использует HTTP-метод GET для передачи параметров, что упрощает жизнь злоумышленнику. Однако не стоит думать, что использование метода POST автоматически устраняет возможность проведения атак с подделкой HTTP-запроса. Страница на сервере злоумышленника может содержать готовую HTML-форму, автоматически отправляемую при просмотре страницы. <html> <body> <form method=POST action="http://test.ptsecurity.ru/xcheck/postsend.asp"> Mail to:<br><br><input type=text name=to value="user2spam@example.com"><br><br> Message:<br><br> <textarea width=20 name=mess>Spam The</textarea><br><br> <input type=submit id=doit> </form> <script> document.getElementById("doit").click(); </script> </body> </html>

Для эксплуатации CSRF злоумышленнику совсем не обязательно иметь свой Web-сервер. Страница, инициирующая запрос может быть передана по электронной почте или другим способом.

В обзоре Billy Hoffman приведены различные методы сетевого взаимодействия с помощью Javascript. Все они, включая XmlHttxmpquest (в некоторых ситуациях), могут быть задействованы для реализации атак CSRF.

Надеюсь, что сейчас читателю уже понятно основное отличие CSRF от XSS. В случае с XSS злоумышленник получает возможность доступа к DOM (Document Object Model) уязвимой страницы, как на чтение, так и на запись. При выполнении CSRF атакущий имеет возможность передать запрос серверу с помощью браузера пользователя, но получить и проанализировать ответ сервера, а тем более его заголовок (например, Cookie) уже не сможет. Соответственно, «Подделка HTTP-запросов» позволяет работать с приложением в режиме «только на запись», чего впрочем, вполне достаточно для выполнения реальных атак.

Основными целями CSRF-атак являются различные интерактивные Web-приложения, например системы электронной почты, форумы, CMS, интерфейсы удаленного управления сетевым оборудованием. Например, злоумышленник может отправлять сообщения от имени других пользователей, добавлять новые учетные записи, или изменять настройки маршрутизатора через Web-интерфейс.



Рис. 4. Пример эксплуатации CSRF в форуме

Остановимся подробнее на последнем – изменении настроек сетевых устройств. Автор уже упоминал об этой возможности по отношению к системам обнаружения беспроводных атак, но естественно, ими дело не ограничивается.

Пробиваем периметр

В декабре прошлого года компания Symantec опубликовала отчет о «новой» атаке, под называнием «Drive-By Pharming», которая, по сути, является вариантом эксплуатации CSRF. Злоумышленник выполняет в браузере пользователя некий «волшебный» JavaScript, изменяющий настройки маршрутизатора, например устанавливающего новое значение DNS-сервера. Для выполнения этой атаки необходимо решить следующие задачи:

- сканирование портов с помощью JavaScript;

- определение типа Web-приложения (fingerprint);

- подбор пароля и аутентификация с помощью CSRF;

- изменение настроек узла с помощью атаки CSRF.

Техника сканирования определения доступности Web-сервера и его типа по с помощью JavaScript проработана достаточно хорошо и сводится к динамическому созданию HTML-объектов (например, img src=), указывающие на различные внутренние URL (например, http://192.168.0.1/pageerror.gif). Если «картинка» была успешно загружена, то по тестируемому адресу расположен Web-сервер на базе Microsoft IIS. Если в ответ было получена ошибка 404, то порт открыт и на нем работает Web-сервер. В случае если был превышен таймаут – сервер отсутствует в сети или порт заблокирован на межсетевом экране. Ну и в остальных ситуациях – порт закрыт, но хост доступен (сервер вернул RST-пакет и браузер вернул ошибку до истечения таймаута). В некоторых ситуациях подобное сканирование портов из браузера пользователя может проводиться без использования JavaScript (http://jeremiahgrossman.blogspot.com/2006/11/browser-port-scanning-without.html).

После определения типа устройства злоумышленник может попробовать заставить браузер пользователя сразу послать запрос на изменение настроек. Но такой запрос будет успешен только в случае, если браузер пользователя уже имеет активную аутентифицированную сессию с устройства. Иметь под рукой открытую страницу управления маршрутизатором - дурная привычка многих «продвинутых» пользователей.

Если же активной сессии с интерфейсом управления нет, злоумышленнику необходимо пройти аутентификацию. В случае если в устройстве реализована аутентификация на основе форм, никаких проблем не возникает. Используя CSRF в POST, серверу отправляются запрос на авторизацию, после чего с него загружается изображение (или страница) доступная только аутентифицированным пользователям. Если изображение было получено, то аутентификация прошла успешно, и можно приступать к дальнейшим действиям, в обратном случае – пробуем другой пароль.

В случае если в атакуемом устройстве реализована аутентификация по методу Basic, задача усложняется. Браузер Internet Explorer не поддерживает возможность указать имя пользователя и пароль в URL (например, http://user:pass@test.ptsecurity.ru). В связи с этим для выполнения Basic-аутентификации может использоваться метод с добавлением HTTP-заголовков с помощью Flash, описанный в статье Amit Clein. Однако этот метод подходит только для старых версий Flash, которые встречаются все реже и реже.

Но другие брузеры, например Firefox дают возможность указать имя пользователя и пароль в URL, и могут быть использованы для аутентификации на любом сервере, причем это можно сделать без генерации сообщения об ошибке в случае выбора неверного пароля.

Пример сценария для «тихой» аутентификации по методу Basic, из блога Stefan Esser приведен ниже.

<html> <head> <title>Firefox HTTP Auth Bruteforcing</title> <script> function okPW() { alert("User/Password Combination correct"); } function wrongPW() { alert("User/Password Combination is wrong"); } </script> <link rel="shortcut icon" href="http://user:pass@URL" type="image/x-icon"> </head> <body> <img src="http://www.securitylab.ru/_article_images/2007/03/http://user:pass@URL" onLoad="okPW()" onError="wrongPW()"> </body> </html>



Рис. 5. Аутентификация Basic в Firefox

В корпоративной среде, где зачастую используются механизмы SSO, например, на базе домена Active Directory и протоколов Kerberos и NTLM эксплуатация CSRF не требует дополнительных усилий. Браузер автоматически пройдет аутентификацию в контексте безопасности текущего пользователя.

После того как аутентификация была пройдена, злоумышленник с помощью JavaScript передать запрос, изменяющий произвольные настройки маршрутизатора, например адрес DNS-сервера.

Методы защиты

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

Однако этот механизм имеет ряд недостатков. Во-первых – перед разработчиком встает вопрос об обработке запросов, не имеющих заголовка Referer как такового. Многие из персональных межсетевых экранов и анонимизирующих proxy-серверов вырезают Referer, как потенциально небезопасный заголовок. Соответственно, если сервер будет игнорировать подобные запросы, группа наиболее «параноидально» настроенных граждан не смогут с ним работать.

Во-вторых, в некоторых ситуациях заголовок Referer может быть подделан, например, с помощью уже упоминавшегося трюка с Flash. Если пользователь применяет IE 6.0, то содержимое заголовка запроса может быть модифицировано c использованием ошибки в реализации XmlHttxmpquest. Уязвимость заключается в возможности использования символов перевода строки в имени HTTP-метода, что позволяет изменять заголовки и даже внедрять дополнительный запрос. Эта уязвимость была обнаружена Amit Clein () в 2005 году и снова открыта в 2007. Ограничением этого метода является то, что он работает только в случае наличия между пользователем и сервером HTTP-Proxy или размещения серверов на одном IP-адресе, но с разными доменными именами.

Другой распространенный метод – добавление уникального параметра к каждому запросу, который затем проверяется сервером. Параметр может добавляться к URL при использовании GET запроса как например, в
Google Desktop или в виде спрятанного параметра формы, при использовании POST. Значение параметра может быть произвольным, главное, чтобы злоумышленник не мог его предсказать, например – значение сессии пользователя.



Рис. 6. Защита от CSRF в Bitrix

Для быстрого добавления функции проверки CSRF в свое приложение можно воспользоваться следующим подходом:

1. Добавлять в каждую генерируемую страницу небольшой JavaScript, дописывающий во все формы дополнительный скрытый параметр, которому присваивается значение Cookie.

2. Проверять на сервере, что переданные клиентом с помощью метода POST данные содержат значение, равное текущему значению Cookie.

Пример подобного клиентского сценария приведен ниже:

<script> strCookie = document.cookie; for (i=0;i<document.forms.length;i++) { var newTextField = document.createElement('input'); newTextField.setAttribute('type','hidden'); newTextField.setAttribute('name','session'); newTextField.value=strCookie; document.forms[i].appendChild(newTextField); } </script>

Дальнейшим развитием этого подхода является сохранение идентификатора сессии не в Cookie, а в качестве скрытого параметра формы (например, VIEWSTATE).

В качестве метода противодействия CSRF могут использоваться различные варианты тестов Тьюринга, например, хорошо известные всем изображения - CAPTCHA. Другим популярным вариантом является необходимость ввода пользовательского пароля при изменении критичных настроек.



Рис. 7. Защита от CSRF в mail.ru

Таким образом, Cross-Site Request Forgery являются атакой, направленной на клиента Web-приложения и использующей недостаточную проверку источника HTTP-запроса. Для защиты от подобных атак может использоваться дополнительный контроль источника запроса на основе заголовка Referer или дополнительного «случайного» параметра.

Сергей Гордейчик работает системным архитектором компании Positive Technologies, где он специализируется в вопросах безопасности приложений, безопасности беспроводных и мобильных технологий. Автор также является ведущим разработчиком курсов «Безопасность беспроводных сетей», «Анализ и оценка защищенности Web-приложений» учебного центра «Информзащита» . Опубликовал несколько десятков статей в “Windows IT Pro/RE”, SecurityLab и других изданиях. Является участником проектов Web Application Security Consortium (WASC).

или введите имя

CAPTCHA
Страницы: 1  2  3  
1
10-04-2007 10:56:32
Хе, пишут что post можно обойти, сославшись на страничу с формой и скриптом, который ее отправляет. Только если указан тег <img src> то адрес, написанный в src будет восприниматься браузером как картинка, соответсвенно никакие джава скрипты по этому адресу исполняться не будут.
0 |
1
21-06-2007 14:16:22
Хм, а это проверено, что не будут?
0 |
1
05-07-2007 06:07:51
епта, а так не понятно? имхо отключайте дружно работу через get-запросы, и будет щастье, javascript это уже xss ломал самописный движок именно таким способом, вот уж не думал, что у этой уязвимости такое умное название
0 |
Андрей
06-12-2010 23:34:26
Бред. <img src> находится на странице злоумышленника, которая открывается у жертвы, следовательно, там может быть и форма с яваскриптом.
0 |
Сергей
30-10-2012 14:28:03
Бред, <img src=""> делает запрос на получение контента картинки, в браузере эта страница не открывается и JavaScript не выполняется.
0 |
1
03-08-2007 01:20:26
Забавная фраза: >При выполнении CSRF атакущий имеет возможность передать запрос серверу с помощью браузера >пользователя, но получить и проанализировать ответ сервера, а тем более его заголовок (например, >Cookie) уже не сможет. Как это не может?? Если запрос отправляется с помощью XMLHttpRequest то есть возможность прочитать абсолютно все заголовки и уж тем более сам ответа.
0 |
1
15-08-2007 09:05:52
>Если запрос отправляется с помощью XMLHttpReques Это если только сайт в том же домене, что и сервер где скрипт
0 |
13-11-2007 12:22:02
НУ а что мешает сочетать XSS и XSRF? тогда можно прочитать ответ.
0 |
19-05-2008 23:44:08
красиво.
0 |
SagePtr
06-05-2010 18:05:42
А можно просто добавлять в каждую отправляемую форму поле, которое генерить как md5 от различных данных - ид сесии, user-agent, логин пользователя если есть, нервые несколько цифр ip-адреса, и так далее (ну разумеется не забыв там же использовать соль, которая для каждой установленной копии скрипта различна, чтобы злоумышленник не сконструировал хэш, зная алгоритм его генерации и данные о жертве). Тогда XSRF идет лесом, разве что в случае XSS может быть осуществлена, но иначе только капча защитит, которая не вариант ибо пользователи озвереют постоянно ее вводить.
0 |
ЯR - Felinta.ru
08-06-2010 17:14:19
Первый раз нужно в "белую" попробывать промонитроить куда это всё идет. Во-второй, через iframe фигарить заранее подготовленную страницу (с готовой копией salt от md5). Большинство php-"писателей" забивают на тюнинг post(или get) форм - и зря! В это наше счастье!
0 |
Роман
10-04-2013 19:33:18
Браузер не позволит.
0 |
Страницы: 1  2  3