# Stored XSS

В этом разделе мы объясним, что такое Stored XSS, опишем последствия таких атак и расскажем, как находить уязвимости Stored XSS.

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

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

Предположим, что сайт позволяет пользователям оставлять комментарии к блог-постам, которые отображаются другим пользователям. Комментарии отправляются на сервер через HTTP-запрос такого вида:

```
POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Length: 100
postId=3&comment=This+post+was+extremely+helpful.&name=Carlos+Montoya&email=carlos%40normal-user.net
```

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

```html
<p>This post was extremely helpful.</p>
```

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

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

В теле HTTP-запроса этот комментарий будет закодирован, например:

```
comment=%3Cscript%3E%2F*%2BBad%2Bstuff%2Bhere...%2B*%2F%3C%2Fscript%3E
```

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

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

Таким образом, вредоносный скрипт, предоставленный атакующим, выполнится в браузере жертвы в контексте её сессии с приложением.

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

[**Stored XSS into HTML context with nothing encoded**](https://portswigger.net/web-security/cross-site-scripting/stored/lab-html-context-nothing-encoded)
{% endhint %}

## Влияние атак сохранённого XSS

Если атакующий может контролировать скрипт, исполняемый в браузере жертвы, обычно он может полностью скомпрометировать этого пользователя. Атакующий может выполнить любые действия из списка, свойственного атакам через [reflected xss](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/reflected-xss-otrazhennyi-mezhsaitovyi-skripting), включая кражу данных, выполнение действий от имени пользователя и так далее.

С точки зрения эксплуатации, ключевое отличие между Reflected и Stored XSS заключается в том, что Stored XSS позволяет осуществлять полностью самодостаточные атаки непосредственно через приложение. Атакующему не нужно находить внешний механизм, чтобы заставить других пользователей отправлять особый запрос с его эксплойтом. Вместо этого он помещает вредоносный код в само приложение и просто ждёт, пока пользователи его встретят.

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

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

## Stored XSS в различных контекстах

Существуют различные типы Stored XSS. Местоположение данных в ответе приложения определяет тип полезной нагрузки для эксплуатации уязвимости и может влиять на последствия.

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

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

* [Контексты Cross-Site Scripting](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/xss-contexts-konteksty-mezhsaitovogo-skriptinga)
  {% endhint %}

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

Ручное тестирование Stored XSS может быть затруднительным. Необходимо проверить все релевантные «входные точки», через которые данные, контролируемые атакующим, могут попасть в приложение, и все «выходные точки», где эти данные могут быть впоследствии выведены в ответах приложения.

Проверяем обязательно:

* Параметры или другие данные внутри строки запроса URL и тела запроса.
* Путь файла в URL.
* HTTP-заголовки (для которых Reflected XSS обычно невозможно эксплуатировать).
* Любые каналы (out-of-band routes), по которым атакующий может доставить данные в приложение. Конкретные каналы зависят исключительно от реализованного функционала приложения: например, веб-почтовое приложение будет обрабатывать данные из входящих писем; приложение, отображающее ленту Twitter, может обрабатывать данные, содержащиеся в твитах третьих лиц; а новостной агрегатор будет включать данные, поступающие с других веб-сайтов.

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

Первый шаг при тестировании — определить, где значения, отправленные во входные точки, попадают в выходные точки приложения. Это может быть сложно, потому что:

* Данные, отправляемые через любую входную точку, теоретически могут всплыть в любой выходной точке. Например, пользовательское отображаемое имя может появиться в каком-то скрытом административном логе.
* Данные, которые в настоящее время хранятся приложением, часто могут быть перезаписаны другими действиями (например, список последних поисков быстро переполняется по мере использования приложения).

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

Более практичная стратегия — поочерёдно проходить по точкам ввода данных, внося уникальное значение в каждую, и затем отслеживать ответы приложения. Особое внимание стоит уделять функционалу комментариев к блогам, форумам и другим областям, где предполагается публикация информации между пользователями. Когда отправленное значение появляется в ответе, необходимо убедиться, что данные действительно были сохранены и используются в разных запросах, а не только отражаются немедленно.

После выявления связи между точкой ввода и вывода для каждой такой пары нужно определить контекст появления данных в ответе и протестировать подходящие полезные нагрузки для этого контекста. На этом этапе методика тестирования аналогична поиску [reflected xss](https://wr3dmast3r.gitbook.io/portswiggerfundamental/client-side/xss/reflected-xss-otrazhennyi-mezhsaitovyi-skripting).
