Cross-Site Scripting (XSS)

Что такое XSS?

Cross-Site Scripting (также известный как XSS) — это уязвимость веб-безопасности, которая позволяет атакующему скомпрометировать взаимодействие пользователей с уязвимым приложением. Уязвимость XSS даёт атакующему возможность обходить same origin policy, предназначенную для изоляции разных сайтов друг от друга. Уязвимости XSS обычно позволяют атакующему выдавать себя за пользователя-жертву, выполнять любые действия, доступные пользователю, и получать доступ ко всем его данным. Если у жертвы есть расширенные привилегии в приложении, атакующий может получить полный контроль над всеми функциями и данными приложения.

circle-info

Дополнительные материалы

Как работает XSS?

Cross-Site Scripting работает путём манипулирования уязвимым сайтом так, чтобы тот возвращал контролируемый JavaScript атакующего другим пользователям. Когда вредоносный код выполняется в браузере жертвы, атакующий может полностью скомпрометировать её взаимодействие с приложением.

circle-check

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 можно обойти, чтобы использовать уязвимость.

circle-info

Подробнее

Dangling Markup Injection

Dangling Markup Injection — техника, позволяющая собирать данные между доменами в ситуациях, когда полноценная XSS невозможна из-за фильтров или других защит. Её можно эксплуатировать для получения чувствительной информации, видимой другим пользователям, в том числе CSRF-токенов для получения несанкционированного доступа от имени другого пользователя.

circle-info

Подробнее

Как предотвратить 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-контекста.

circle-info

Дополнительные материалы

Last updated