XSS: Межсайтовые сценарии
Что такое межсайтовые сценарии (XSS)
Cross-site scripting/Межсайтовые сценарии (также известная как XSS) — уязвимость веб-безопасности позволяющая злоумышленнику скомпрометировать взаимодействие пользователей с уязвимым приложением. Это позволяет злоумышленнику обойти политику одинакового источника (same-origin policy) предназначенную для отделения разных веб-сайтов друг от друга. Уязвимость межсайтовых сценариев (XSS) позволяет злоумышленнику замаскироваться под пользователя-жертву, выполнять любые действия, которые может выполнить пользователь, и получать доступ к любы данным пользователя. Если пользователь-жертва имеет привилегированный доступ к приложению, злоумышленник может получить полный контроль над всеми функциями и данными приложения.
Как работает XSS/межсайтовые сценарии
Межсайтовые сценарии работают манипулируя уязвимым веб-сайтом, чтобы он возвращал пользователям вредоносный JavaScript. Когда вредоносный код выполняется в браузере жертвы, злоумышленник может полностью скомпрометировать его (жертвы) взаимодействие с приложением.
Подтверждение концепции XSS
Большинство уязвимостей XSS можно подтвердить внедрив полезную нагрузку, которая заставит ваш собственный браузер выполнять произвольный JavaScript код. Давно стало обычной практикой использовать для этой цели alert()
, потому что это короткая и безвредная команда, и её сложно не заметить при успешном вызове.
К сожалению, есть небольшая заминка, если вы используете Chrome. Начиная с версии 92 (от 20 июля 2021 г.) фреймы из разных источников не могут вызывать alert()
. Поскольку они используются для создания более продвинутых XSS атак, вам нужно использовать альтернативную полезную нагрузку. В этом случае мы рекомендуем функцию print()
. Если вам интересно узнать больше об этом изменении и о том почему нам нравится print()
, прочитайте статью на эту тему alert() is dead, long live print()
.
Какие типы XSS атак существуют
Существует три основных типа XSS атак. Это:
- Reflected XSS — Отражённый XSS, где вредоносный скрипт исходит из текущего HTTP-запроса.
- Stored XSS — Сохранённый XSS, где вредоносный тип берётся из базы данных сайта.
- DOM-based XSS — XSS на основе DOM, где уязвимость существует в коде на стороне клиента, а не в коде на стороне сервера.
Отражённый межсайтовый сценарий / Reflected XSS
Отражённый XSS — простейшая разновидность межсайтовых сценариев. Он возникает, когда приложение получает данные в HTTP-запросе и включает эти данные в немедленный ответ небезопасным способом.
Вот простейший пример Отражённой XSS уязвимости:
https://insecure-website.com/status?message=All+is+well.
<p>Status: All is well.</p>
Приложение не выполняет никакой обработки данных, поэтому злоумышленник может легко построить атаку следующим образом:
https://insecure-website.com/status?message=<script>/*+Bad+stuff+here...+*/</script>
<p>Status: <script>/* Bad stuff here... */</script></p>
Если пользователь посещает URL-адрес созданный злоумышленником, сценарий злоумышленника выполняется в браузере пользователя в контексте сеанса этого пользователя с приложением. В этот момент сценарий может выполнять любые действия и извлекать любые данные, к которым у пользователя есть доступ.
Сохранённый межсайтовый сценарий / Stored XSS
Сохранённый XSS (также известный как постоянный или XSS второго порядка) возникает, когда приложение получает данные из ненадёжного источника и включает эти данные в свои более поздние HTTP-ответы небезопасным способом.
Рассматриваемые данные могут быть отправлены в приложение через HTTP-запросы; например, комментарии к сообщению в блоге, псевдонимы пользователей в чате или контактные данные в заказе клиента. В других случаях данные могут поступать из других ненадёжных источников; например, приложение веб-почты, отображающее сообщения полученные по SMTP, маркетинговое приложение, отображающее сообщения из соцсетей, или приложение для мониторинга сет, отображающее пакетные данные из сетевого трафика.
Простой пример Сохранённой XSS-уязвимости. Приложение доски объявлений позволяет пользователям отправлять сообщения отображаемые для других пользователей:
<p>Hello, this is my message!</p>
Приложение не выполняет никакой обработки данных, поэтому злоумышленник может легко отправить сообщение атакующее других пользователей:
<p><script>/* Bad stuff here... */</script></p>
Межсайтовые сценарии на основе DOM / DOM-based XSS
Межсайтовые сценарии на основе DOM (также известны как DOM XSS) возникают, когда приложение содержит некоторый клиентский JavaScript, обрабатывающий данные из ненадёжного источника небезопасным образом, обычно путём записи данных обратно в DOM.
В следующем примере приложение использует JavaScript для чтения значения из полей ввода и записи этого значения в HTML элемент:
var search = document.getElementById('search').value;
var results = document.getElementById('results');
results.innerHTML = 'You searched for: ' + search;
Если злоумышленник может контролировать значение поля ввода, он может создать вредоносное значение приводящее к выполнению его собственного сценария:
You searched for: <img src=1 onerror='/* Bad stuff here... */'>
В типичном случае поле ввода заполняется частью HTTP-запроса, например параметром строки запроса URL-адреса, что позволяет злоумышленнику осуществить атаку с использованием вредоносного URL-адреса таким же образом, как и Отражённый XSS.
Для чего используется XSS
Злоумышленник использующий уязвимость межсайтовых сценариев, обычно может:
- Выдавать себя за пользователя-жертву или маскироваться под него.
- Выполнить любое действие, которое может выполнить пользователь.
- Читать любы данные, к которым пользователь может получить доступ.
- Захватить учётную запись пользователя.
- Выполнить виртуальный дефейс веб-сайта.
- Внедрить троянские функции на веб-сайт.
Влияние XSS-уязвимостей
Фактическое воздействие XSS-атаки обычно зависит от характера приложения, его функционала и данных, а также статуса скомпрометированного пользователя. Например:
- В приложении, где все пользователи анонимны, а вся информация общедоступна, влияние зачастую будет минимальным.
- В приложение, хранящем конфиденциальные данные, такие как банковские транзакции, электронные письма или медицинские записи, воздействие будет очень серьёзным.
- Если скомпрометированный пользователь имеет повышенные привилегии в приложении, то воздействие, как правило, будет критическим. Позволяя злоумышленнику получить контроль над уязвимым приложение и скомпрометировать всех пользователей и их данные.
Как найти и протестировать XSS уязвимости
Подавляющее большинство уязвимостей можно найти с помощью веб-сканера уязвимостей.
Ручное тестирование Отражённых и Сохранённых XSS обычно включает отправку некоторого простого уникального ввода (например, короткой буквенно-цифровой строки) в каждую точку входа в приложении, идентификацию каждого места, где отправленные данные возвращаются в HTTP-ответах, и тестирование каждого местоположения по отдельности для определения можно ли использовать правильно сформированный ввод для выполнения произвольного JavaScript. Таким образом, вы можете определить контекст, в котором происходит XSS, и выбрать подходящую полезную нагрузку для его использования.
Ручное тестирование XSS на основе DOM, возникающее из параметров URL, включает аналогичный процесс: помещение некоторого простого уникального ввода в параметр, использование инструментов разработчика браузера для поиска этих данных в DOM и проверка каждого местоположения для определения возможности его использования. Однако другие типы DOM XSS сложнее обнаружить. Для поиска уязвимости на основе DOM во входных данных, не основанных на URL (например document.cookie
) или приёмниках не основанных на HTML (например, setTimeout
), ничто не заменит просмотра JavaScript кода, который может занять очень много времени. Сканеры веб-уязвимостей сочетают в себе статический и динамический анализ JavaScript для надёжной автоматизации уязвимостей на основе DOM.
Политика безопасности контента / Content security policy
Политика безопасности контента (CSP) — механизм браузера, цель которого смягчение воздействия межсайтовых сценариев и некоторых других уязвимостей. Если приложение, использующее CSP, ведёт себя как XSS, то CSP может затруднить или предотвратить использование уязвимости. Часто CSP можно обойти, чтобы использовать основную уязвимость.
Внедрение висячей разметки / Dangling markup injection
Внедрение висячей разметки — метод который можно использовать для захвата данных между доменами в ситуации, когда полноценный эксплойт межсайтового сценария не возможен из-за входных фильтров или других средств защиты. Его часто можно использовать для сбора конфиденциальной информации доступной другим пользователям, включая CSRF токены, которые можно использовать для выполнения несанкционированных действий от имени пользователя.
Как предотвратить XSS атаки
Предотвращение межсайтовых сценариев в некоторых случаях тривиально, но может быть намного сложнее в зависимости от сложности приложения и способов, которыми оно обрабатывает данные контролируемые пользователем.
В целом, эффективное предотвращение XSS-уязвимостей, вероятно, будет включать в себя сочетание следующих мер:
- Фильтровать входящие данные. В момент получения пользовательских данных фильтруйте как можно боле строго на основе ожидаемого или валидного ввода.
- Кодирование данных на выходе. В момент, когда управляемые пользователем данные выводятся в HTTP-ответах, кодируйте выходные данные, чтобы предотвратить их интерпретацию как активное содержимое. В зависимости от контекста вывода может потребоваться комбинация HTML, URL, JavaScript и CSS кодирования.
- Используйте соответствующие заголовки ответов. Для предотвращения XSS в HTTP-ответах, которые не должны содержать какой-либо HTML или JavaScript, вы можете использовать заголовки
Content-Type
иX-Content-Type-Options
для гарантии, что браузер интерпретирует ответы так, как вы задумали. - Политика безопасности контента. В качестве последней линии защиты вы можете использовать политику безопасности контента (CSP), для уменьшения серьёзности любых XSS-уязвимостей, которые всё ещё встречаются.
Общие вопросы о межсайтовых сценариях
Насколько распространены XSS уязвимости?
XSS-уязвимости очень сильно распространены, и XSS, вероятно, является наиболее часто встречающейся уязвимостью веб-безопасности.
Насколько распространены XSS атаки?
Трудно получить надёжные данные о реальных XSS-атаках, но, вероятно, они используются реже, чем другие уязвимости.
В чём разница между XSS и CSRF?
XSS заставляет веб-сайт возвращать вредоносный код JavaScript, а [CSRF](/articles/security/csrf/) побуждает пользователя-жертву выполнять действия, которые он не намеревался совершать.
В чём разница между XSS и SQL-инъекцией?
XSS — уязвимость на стороне клиента, нацеленная на других пользователей приложения, а внедрение SQL — уязвимость на стороне сервера, нацеленная на базу данных приложения.
Как предотвратить XSS в PHP?
Фильтруйте вводимые данные с помощью белого списка разрешённых символов и используйте подсказки типов или приведение типов. Экранируйте входящие данные с htmlentities
и ENT_QUOTES
для HTML контекстов или экранирование JavaScript Unicode для контекста JavaScript.
Как предотвратить XSS в Java?
Фильтруйте вводимые данные с помощью белого списка разрешённых символов и используйте библиотеку, например Google Guava
для HTML-кодирования выходных данных для HTML контекста или используйте escape-последовательности JavaScript Unicode для JavaScript контекста.