> For the complete documentation index, see [llms.txt](https://web-sec.gitbook.io/wsa/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://web-sec.gitbook.io/wsa/client-side/cross-site-scripting/stored.md).

# 存储型XSS

在本节中，我们将讲解存储型跨站脚本，描述存储型XSS攻击的影响，并阐明如何发现存储型XSS漏洞。

## 什么是存储型跨站脚本？

存储型跨站脚本（又称为二阶或持久型XSS）发生在当应用程序从不可信的来源接收数据，并以不安全的方式将这些数据包含在其后续的HTTP响应中时。

假设一个网站允许用户在博客文章上提交评论，而这些评论会显示给其他用户。用户使用类似如下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>
```

在攻击者的请求中，此评论将被URL编码为：

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

现在，任何访问该博客文章的用户都会在应用程序的响应中收到以下内容：

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

然后，攻击者提供的脚本就会在受害用户的浏览器中，在其与应用程序的会话环境中执行。

> **LAB**
>
> [存储型XSS到无任何编码的HTML上下文](https://portswigger.net/web-security/cross-site-scripting/stored/lab-html-context-nothing-encoded)

## 存储型XSS攻击的影响

如果攻击者能够控制受害者浏览器中执行的脚本，那么通常他们就可以完全控制该用户。攻击者可以执行任何适用于反射型XSS漏洞影响的操作。

就可利用性而言，反射型和存储型XSS之间关键的区别在于，存储型XSS漏洞使得攻击在应用程序内部自包含。攻击者无需寻找外部方式来诱导其他用户发起包含攻击者利用代码的特定请求。相反，攻击者将他们的利用代码放入应用程序本身中，然后等待用户遭遇到它。

在当XSS漏洞只影响当前已登录应用程序的用户的情况下，存储型跨站脚本攻击的自包含性就显得尤为重要。如果XSS是反射型的，那么攻击必须有幸运的时机：如果用户在未登录时被诱导发起攻击者的请求，他们将不会受到攻击。相比之下，如果XSS是存储型的，那么用户在遭遇到利用代码时肯定是已经登录了的。

> **阅读更多**
>
> [利用跨站脚本漏洞](/wsa/client-side/cross-site-scripting/exploiting.md)

## 不同上下文中的存储型XSS

存储型跨站脚本有许多不同的类型。被存储的数据在应用程序响应中的位置，决定了利用它所需的有效载荷类型，并且还可能影响漏洞的影响。

此外，如果应用程序在数据存储之前或在将存储的数据合并到响应中时，对数据进行了任何验证或其他处理，通常会影响所需的XSS载荷类型。

> **阅读更多**
>
> [跨站脚本上下文](/wsa/client-side/cross-site-scripting/contexts.md)

## 如何发现和测试存储型XSS漏洞

使用Burp Suite的Web漏洞扫描器可以发现许多存储型XSS漏洞。

手动测试存储型XSS漏洞可能具有挑战性。你需要测试所有相关的**入口点**（攻击者可控的数据可通过这些点进入应用程序的处理）以及所有的**出口点**（在这些点，数据可能出现在应用程序的响应中）。

进入应用程序处理的入口点包括：

* URL查询字符串和消息正文中的参数或其他数据。
* URL文件路径。
* 在反射型XSS中可能无法利用的HTTP请求标头。
* 任何攻击者可通过非常规通信渠道向应用程序传递数据的途径。存在的途径完全取决于应用程序实现的功能：一个电子邮件应用程序会处理邮件中收到的数据；一个显示Twitter信息流的应用程序可能会处理第三方推文中包含的数据；一个新闻聚合器会包含来自其他网站上的数据。

存储型XSS攻击的出口点是指，在任何情况下返回给所有应用程序用户的所有可能的HTTP响应。

测试存储型XSS漏洞的第一步是找到入口点和出口点之间的连接，通过这种连接，提交到入口点的数据从出口点发出。之所以说这具有挑战性，原因在于：

* 原则上，提交到任何入口点的数据都可能从任何出口点发出。例如，用户提供的显示名称可能出现在一个只对某些应用程序用户可见的晦涩难懂的审计日志中。
* 当前应用程序存储的数据往往容易因应用程序中执行的其他操作而被覆盖。例如，搜索功能可能会显示一系列最近的搜索，这些搜索很快就会被用户进行的其他搜索而替换。

要全面地识别入口点和出口点之间的连接，需要分别测试每种排列组合，将特定值提交到入口点，直接导航到出口点，并确定该值是否出现在那里。然而，对于不止几个页面的应用程序，这种方法并不切实际。

相反，更现实的方法是系统地遍历数据入口点，向每一个入口点提交一个特定值，并监控应用程序的响应，以检测提交的值出现的情况。可以特别关注应用程序相关的功能，如博客文章的评论。当在响应中观察到提交的值时，你需要确定数据是否确实被存储在不同的请求中，而不仅仅是简单反射在紧接着的响应中。

在确定了应用程序处理过程中入口点和出口点之间的连接后，需要对每个连接进行特定的测试，以检测是否存在存储型XSS漏洞。这涉及到确定响应中存储数据出现的上下文，并测试适用于该上下文的合适候选XSS载荷。在这一点上，测试方法与发现反射型XSS漏洞的方法基本相同。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://web-sec.gitbook.io/wsa/client-side/cross-site-scripting/stored.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
