Cross-Site Scripting (XSS)
Что такое XSS?
Cross-Site Scripting (также известный как XSS) — это уязвимость веб-безопасности, которая позволяет атакующему скомпрометировать взаимодействие пользователей с уязвимым приложением. Уязвимость XSS даёт атакующему возможность обходить same origin policy, предназначенную для изоляции разных сайтов друг от друга. Уязвимости XSS обычно позволяют атакующему выдавать себя за пользователя-жертву, выполнять любые действия, доступные пользователю, и получать доступ ко всем его данным. Если у жертвы есть расширенные привилегии в приложении, атакующий может получить полный контроль над всеми функциями и данными приложения.
Как работает XSS?
Cross-Site Scripting работает путём манипулирования уязвимым сайтом так, чтобы тот возвращал контролируемый JavaScript атакующего другим пользователям. Когда вредоносный код выполняется в браузере жертвы, атакующий может полностью скомпрометировать её взаимодействие с приложением.
Labs
Если вы уже знакомы с базовыми концепциями XSS-уязвимостей и хотите попрактиковаться в эксплуатации их на реалистичных специально уязвимых целях, вы можете получить доступ ко всем лабораторным заданиям по XSS по ссылке ниже.
XSS PoC
Вы можете подтвердить большинство видов XSS-уязвимостей, внедрив полезную нагрузку, которая заставляет ваш собственный браузер выполнить произвольный JavaScript. Давно принято использовать функцию alert(). Большинство лабораторных по XSS на PortSwigger можно решить, вызвав alert() в браузере имитируемой жертвы.
Поскольку имитируемая жертва в некоторых лабораторных заданиях использует Chrome, можно использовать альтернативу в виде print().
Какие бывают типы XSS-атак?
Существует три основных типа XSS-атак:
Reflected XSS — вредоносный скрипт приходит из текущего HTTP-запроса.
Stored XSS — вредоносный скрипт хранится в базе данных сайта.
DOM-based XSS — уязвимость существует в клиентском, а не серверном коде.
Reflected XSS
Это самый простой вариант XSS. Он появляется, когда приложение получает какие-либо данные в HTTP-запросе и включает их в непосредственный ответ небезопасным образом.
Пример простой Reflected XSS-уязвимости:
Приложение не обрабатывает данные дополнительно, поэтому атакующий может легко построить атаку:
Если пользователь перейдёт по такой ссылке, скрипт атакующего выполнится в его браузере, в контексте текущей сессии. Скрипт сможет выполнить любые действия и получить любые данные, доступные этому пользователю.
Stored XSS
Stored XSS (также известный как persistent или second-order XSS) возникает, когда приложение получает данные из недоверенного источника и включает их в свои последующие HTTP-ответы небезопасным образом.
Данные могут быть отправлены в приложение через HTTP-запросы, например, комментарии к посту, никнеймы пользователей в чате или контактные данные в заказе. В других случаях данные могут поступать из других недоверенных источников, например, почтовое веб-приложение, показывающее сообщения, маркетинговая программа, показывающая посты из соцсетей, или система мониторинга, отображающая сетевой трафик.
Пример сохранённой XSS — доска сообщений, где пользователь может отправить сообщение, отображаемое другим пользователям:
Приложение не обрабатывает данные, поэтому атакующий может отправить сообщение-атаку:
DOM-based XSS
DOM-based XSS (также известный как DOM XSS) возникает, когда приложение содержит клиентский JavaScript, который небезопасно обрабатывает данные из недоверенного источника, обычно записывая их обратно в DOM.
Пример: приложение с помощью JavaScript читает значение из поля ввода и записывает его в элемент HTML:
Если злоумышленник может контролировать значение поля ввода, он может создать вредоносное значение, вызывающее выполнение скрипта:
Обычно значение поля ввода задаётся частью HTTP-запроса, например, параметром строки запроса, что позволяет атакующему устроить атаку аналогично отражённому XSS.
Для чего используется XSS?
Атакующий, эксплуатирующий XSS-уязвимость, обычно может:
Выдавать себя или маскироваться под жертву-пользователя.
Выполнять любые действия, доступные пользователю.
Читать любые данные, доступные пользователю.
Перехватывать учётные данные пользователя.
Дефейс сайта.
Влияние XSS-уязвимостей
Конкретное влияние XSS зависит от природы приложения, его функциональности и данных, а также статуса скомпрометированного пользователя. Например:
В приложении, где все пользователи анонимны, а информация открыта, ущерб будет минимальным.
В приложении с чувствительными данными (банковские операции, почта, медкарты) ущерб будет, скорее всего, серьёзным.
Если скомпрометирован пользователь с расширенными привилегиями, ущерб обычно критичен: атакующий может захватить полный контроль над приложением и компрометировать всех пользователей и их данные.
Как находить и тестировать XSS-уязвимости
Подавляющее большинство XSS-уязвимостей можно быстро и надёжно найти с помощью веб-сканера уязвимостей Burp Suite.
Ручное тестирование отражённого и сохранённого XSS обычно включает в себя вставку уникального простого значения (например, короткой буквы/цифры) в каждую точку ввода приложения, поиск всех мест, где это значение возвращается в HTTP-ответах, и индивидуальное тестирование этих мест на возможность внедрения JavaScript. Так определяется контекст и подбирается подходящая нагрузка.
Ручное тестирование DOM-based XSS из URL-параметров аналогично: поместить уникальное значение в параметр, с помощью инструментов разработчика найти его в DOM и проверить, возможно ли внедрение. Другие виды DOM-XSS сложнее для выявления. Поиск уязвимостей в не-URL-вводе (например, document.cookie) или не-HTML-контекстах (например, setTimeout) возможен только через ревью JavaScript-кода, что крайне трудоёмко. Burp Suite объединяет статический и динамический анализ для автоматизации поиска DOM-уязвимостей.
Content security policy
Content Security Policy (CSP) — это механизм браузера, предназначенный снизить влияние XSS и других уязвимостей. Если приложение использующее CSP содержит уязвимость XSS, CSP может усложнить или предотвратить эксплуатацию уязвимости. Иногда бывает, что CSP можно обойти, чтобы использовать уязвимость.
Dangling Markup Injection
Dangling Markup Injection — техника, позволяющая собирать данные между доменами в ситуациях, когда полноценная XSS невозможна из-за фильтров или других защит. Её можно эксплуатировать для получения чувствительной информации, видимой другим пользователям, в том числе CSRF-токенов для получения несанкционированного доступа от имени другого пользователя.
Как предотвратить XSS-атаки
Исправление уязвимостей XSS может быть легким в некоторых случаях, но также может быть трудоемким занятием при высокой сложности приложения и специфике работы с пользовательскими данными.
Обычно эффективная защита от XSS включает совокупность следующих мер:
Фильтрация входных данных при получении — фильтруйте максимально строго на этапе получения данных, исходя из ожидаемого формата.
Кодирование данных на выходе — при выводе пользовательских данных в HTTP-ответ, кодируйте вывод так, чтобы он не воспринимался как активный контент. В зависимости от контекста это может требовать HTML-, URL-, JavaScript-, CSS-кодирования.
Установка корректных HTTP-заголовков — используйте
Content-TypeиX-Content-Type-Optionsдля предотвращения XSS в отзывах, не содержащих HTML/JavaScript, чтобы браузеры интерпретировали ответы так, как запланировано.Content Security Policy — используйте CSP как последний рубеж защиты для снижения серьёзности возможных XSS-уязвимостей.
Частые вопросы о XSS
Насколько часто встречаются XSS-уязвимости?
XSS-уязвимости очень распространены и, вероятно, встречаются чаще других веб-уязвимостей.
В чём разница между XSS и CSRF?
XSS — это возвращение сайтом вредоносного JavaScript, в то время как CSRF — это возможность выполнить определенное действие от имени другого пользователя.
В чём разница между XSS и SQL-инъекцией?
XSS — клиентская уязвимость, нацеленная на других пользователей, а SQL-инъекция — серверная уязвимость, нацеленная на базу данных приложения.
Как предотвратить XSS в PHP?
Фильтруйте вводимые данные, разрешая только определённые символы, используйте type hints или приведение типов. Экранируйте вывод через
htmlentitiesиENT_QUOTESдля HTML-контекста, или используйте JavaScript Unicode escapes для JavaScript-контекста.
Как предотвратить XSS в Java?
Фильтруйте ввод с помощью белого списка разрешённых символов и используйте библиотеку вроде Google Guava для HTML-кодирования вывода в HTML-контексте, либо применяйте JavaScript Unicode-экранирование для JavaScript-контекста.
Last updated