# Cross-Site Scripting (XSS)

## Что такое XSS?

Cross-Site Scripting (также известный как XSS) — это уязвимость веб-безопасности, которая позволяет атакующему скомпрометировать взаимодействие пользователей с уязвимым приложением. Уязвимость XSS даёт атакующему возможность обходить [same origin policy](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/cors/politika-odnogo-istochnika-sop), предназначенную для изоляции разных сайтов друг от друга. Уязвимости XSS обычно позволяют атакующему выдавать себя за пользователя-жертву, выполнять любые действия, доступные пользователю, и получать доступ ко всем его данным. Если у жертвы есть расширенные привилегии в приложении, атакующий может получить полный контроль над всеми функциями и данными приложения.

{% hint style="info" %}
**Дополнительные материалы**

* [Знакомимся с уязвимостью XSS](https://wr3dmast3r.gitbook.io/client-side-fundamental/glava-1-nachalo-raboty-s-xss/publish-your-docs)
  {% endhint %}

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

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

{% hint style="success" %}
**Labs**

Если вы уже знакомы с базовыми концепциями XSS-уязвимостей и хотите попрактиковаться в эксплуатации их на реалистичных специально уязвимых целях, вы можете получить доступ ко всем лабораторным заданиям по XSS по ссылке ниже.

* [Посмотреть все лабораторные задания по XSS](https://portswigger.net/web-security/all-labs#cross-site-scripting)
  {% endhint %}

## XSS PoC

Вы можете подтвердить большинство видов XSS-уязвимостей, внедрив полезную нагрузку, которая заставляет ваш собственный браузер выполнить произвольный JavaScript. Давно принято использовать функцию `alert()`. Большинство лабораторных по XSS на PortSwigger можно решить, вызвав `alert()` в браузере имитируемой жертвы.

Поскольку имитируемая жертва в некоторых лабораторных заданиях использует Chrome, можно использовать альтернативу в виде `print()`.

## Какие бывают типы XSS-атак?

Существует три основных типа XSS-атак:

* [**Reflected XSS**](#otrazhyonnyi-xss-reflected-xss) — вредоносный скрипт приходит из текущего HTTP-запроса.
* [**Stored XSS**](#khranimyi-xss-stored-xss) — вредоносный скрипт хранится в базе данных сайта.
* [**DOM-based XSS**](#dom-based-xss) — уязвимость существует в клиентском, а не серверном коде.

## Reflected XSS

Это самый простой вариант XSS. Он появляется, когда приложение получает какие-либо данные в HTTP-запросе и включает их в непосредственный ответ небезопасным образом.

Пример простой Reflected XSS-уязвимости:

```html
https://insecure-website.com/status?message=All+is+well.

<p>Status: All is well.</p>
```

Приложение не обрабатывает данные дополнительно, поэтому атакующий может легко построить атаку:

```html
https://insecure-website.com/status?message=<script>/*+Bad+stuff+here...+*/</script>

<p>Status: <script>/* Bad stuff here... */</script></p>
```

Если пользователь перейдёт по такой ссылке, скрипт атакующего выполнится в его браузере, в контексте текущей сессии. Скрипт сможет выполнить любые действия и получить любые данные, доступные этому пользователю.

{% hint style="info" %}
**Подробнее**

* [Reflected XSS](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/reflected-xss-otrazhennyi-mezhsaitovyi-skripting)
* [Шпаргалка по XSS](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
  {% endhint %}

## Stored XSS

Stored XSS (также известный как persistent или second-order XSS) возникает, когда приложение получает данные из недоверенного источника и включает их в свои последующие HTTP-ответы небезопасным образом.

Данные могут быть отправлены в приложение через HTTP-запросы, например, комментарии к посту, никнеймы пользователей в чате или контактные данные в заказе. В других случаях данные могут поступать из других недоверенных источников, например, почтовое веб-приложение, показывающее сообщения, маркетинговая программа, показывающая посты из соцсетей, или система мониторинга, отображающая сетевой трафик.

Пример сохранённой XSS — доска сообщений, где пользователь может отправить сообщение, отображаемое другим пользователям:

```html
<p>Hello, this is my message!</p>
```

Приложение не обрабатывает данные, поэтому атакующий может отправить сообщение-атаку:

```html
<p><script>/* Bad stuff here... */</script></p>
```

{% hint style="info" %}
**Подробнее**

* [Stored XSS](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/stored-xss-khranimyi-mezhsaitovyi-skripting)
* [Шпаргалка по XSS](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
  {% endhint %}

## DOM-based XSS

DOM-based XSS (также известный как DOM XSS) возникает, когда приложение содержит клиентский JavaScript, который небезопасно обрабатывает данные из недоверенного источника, обычно записывая их обратно в DOM.

Пример: приложение с помощью JavaScript читает значение из поля ввода и записывает его в элемент HTML:

```javascript
var search = document.getElementById('search').value;
var results = document.getElementById('results');
results.innerHTML = 'You searched for: ' + search;
```

Если злоумышленник может контролировать значение поля ввода, он может создать вредоносное значение, вызывающее выполнение скрипта:

```html
You searched for: <img src=1 onerror='/* Bad stuff here... */'>
```

Обычно значение поля ввода задаётся частью HTTP-запроса, например, параметром строки запроса, что позволяет атакующему устроить атаку аналогично отражённому XSS.

{% hint style="info" %}
**Подробнее**

* [DOM-based XSS](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/dom-based-xss)
* [Осваиваем DOM Invader: ищем DOM XSS и Prototype Pollution на примере пяти лабораторных и одной уязвимости на Хабре](https://habr.com/ru/companies/jetinfosystems/articles/821451/)
  {% endhint %}

## Для чего используется XSS?

Атакующий, эксплуатирующий XSS-уязвимость, обычно может:

* Выдавать себя или маскироваться под жертву-пользователя.
* Выполнять любые действия, доступные пользователю.
* Читать любые данные, доступные пользователю.
* Перехватывать учётные данные пользователя.
* Дефейс сайта.

## Влияние XSS-уязвимостей

Конкретное влияние XSS зависит от природы приложения, его функциональности и данных, а также статуса скомпрометированного пользователя. Например:

* В приложении, где все пользователи анонимны, а информация открыта, ущерб будет минимальным.
* В приложении с чувствительными данными (банковские операции, почта, медкарты) ущерб будет, скорее всего, серьёзным.
* Если скомпрометирован пользователь с расширенными привилегиями, ущерб обычно критичен: атакующий может захватить полный контроль над приложением и компрометировать всех пользователей и их данные.

{% hint style="info" %}
**Подробнее**

* [Эксплуатация уязвимостей Cross-Site Scripting](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/ekspluataciya-uyazvimostei-mezhsaitovogo-skriptinga-xss)
  {% endhint %}

## Как находить и тестировать XSS-уязвимости

Подавляющее большинство XSS-уязвимостей можно быстро и надёжно найти с помощью веб-сканера уязвимостей Burp Suite.

Ручное тестирование отражённого и сохранённого XSS обычно включает в себя вставку уникального простого значения (например, короткой буквы/цифры) в каждую точку ввода приложения, поиск всех мест, где это значение возвращается в HTTP-ответах, и индивидуальное тестирование этих мест на возможность внедрения JavaScript. Так определяется [контекст](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/xss-contexts-konteksty-mezhsaitovogo-skriptinga) и подбирается подходящая нагрузка.

Ручное тестирование DOM-based XSS из URL-параметров аналогично: поместить уникальное значение в параметр, с помощью инструментов разработчика найти его в DOM и проверить, возможно ли внедрение. Другие виды DOM-XSS сложнее для выявления. Поиск уязвимостей в не-URL-вводе (например, `document.cookie`) или не-HTML-контекстах (например, `setTimeout`) возможен только через ревью JavaScript-кода, что крайне трудоёмко. Burp Suite объединяет статический и динамический анализ для автоматизации поиска DOM-уязвимостей.

{% hint style="info" %}
**Подробнее**

* [Контексты возникновения уязвимости Cross-Site Scripting](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/xss-contexts-konteksty-mezhsaitovogo-skriptinga)
* [Осваиваем DOM Invader: ищем DOM XSS и Prototype Pollution на примере пяти лабораторных и одной уязвимости на Хабре](https://habr.com/ru/companies/jetinfosystems/articles/821451/)
  {% endhint %}

## Content security policy

Content Security Policy (CSP) — это механизм браузера, предназначенный снизить влияние XSS и других уязвимостей. Если приложение использующее CSP содержит уязвимость XSS, CSP может усложнить или предотвратить эксплуатацию уязвимости. Иногда бывает, что CSP можно обойти, чтобы использовать уязвимость.

{% hint style="info" %}
**Подробнее**

* [Content Security Policy](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/csp-politika-bezopasnosti-kontenta)
  {% endhint %}

## Dangling Markup Injection

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

{% hint style="info" %}
**Подробнее**

* [Dangling Markup Injection](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/inekciya-visyashei-razmetki-dangling-markup)
  {% endhint %}

## Как предотвратить XSS-атаки

Исправление уязвимостей XSS может быть легким в некоторых случаях, но также может быть трудоемким занятием при высокой сложности приложения и специфике работы с пользовательскими данными.

Обычно эффективная защита от XSS включает совокупность следующих мер:

* Фильтрация входных данных при получении — фильтруйте максимально строго на этапе получения данных, исходя из ожидаемого формата.
* Кодирование данных на выходе — при выводе пользовательских данных в HTTP-ответ, кодируйте вывод так, чтобы он не воспринимался как активный контент. В зависимости от контекста это может требовать HTML-, URL-, JavaScript-, CSS-кодирования.
* Установка корректных HTTP-заголовков — используйте `Content-Type` и `X-Content-Type-Options` для предотвращения XSS в отзывах, не содержащих HTML/JavaScript, чтобы браузеры интерпретировали ответы так, как запланировано.
* Content Security Policy — используйте CSP как последний рубеж защиты для снижения серьёзности возможных XSS-уязвимостей.

{% hint style="info" %}
**Подробнее**

* [Как предотвратить XSS](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/kak-predotvratit-xss)
* [Find XSS vulnerabilities using Burp Suite's web vulnerability scanner](https://portswigger.net/burp/vulnerability-scanner)
  {% endhint %}

## Частые вопросы о 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-контекста.

{% hint style="info" %}
**Дополнительные материалы**

* [Знакомимся с уязвимостью XSS](https://wr3dmast3r.gitbook.io/client-side-fundamental/glava-1-nachalo-raboty-s-xss/publish-your-docs)
  {% endhint %}
