# 反射型XSS

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

## 什么是反射型跨站脚本？

当应用程序接收HTTP请求中的数据，并以不安全的方式将该数据包含在紧接着的响应中时，就会出现反射型跨站脚本（XSS）。

假设一个网站有一个搜索功能，该功能接收URL参数中用户提供的搜索词：

```
https://insecure-website.com/search?term=gift
```

应用程序在对这个URL的响应中，回显用户提供的搜索词：

```html
<p>You searched for: gift</p>
```

假设应用程序不对数据进行任何其他处理，攻击者就可以构造如下的攻击：

```
https://insecure-website.com/search?term=<script>/*+Bad+stuff+here...+*/</script>
```

如上URL会导致如下响应：

```html
<p>You searched for: <script>/* Bad stuff here... */</script></p>
```

如果应用程序的其他用户请求攻击者的URL，那么攻击者提供的脚本就会在受害用户的浏览器中，在其与应用程序的会话环境中执行。

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

## 反射型XSS攻击的影响

如果攻击者能够控制受害者浏览器中执行的脚本，那么他们通常就可以完全控制该用户。其中，攻击者可以：

* 执行应用程序内用户可以执行的任何操作。
* 查看用户可以查看的任何信息。
* 修改用户可以修改的任何信息。
* 发起与其他应用程序用户的交互，包括恶意攻击，而这些攻击看起来是来自最初的受害用户。

攻击者可以通过各种手段诱使受害用户发起一个受攻击者控制的请求，从而实施反射型XSS攻击。这些手段包括在攻击者控制的网站上或在允许生成内容的其他网站上放置链接，在电子邮件、推文或其他消息中发送一条链接。攻击可以直接针对已知用户，也可以是针对应用程序任何用户的无差别攻击。

由于攻击需要外部传递机制，意味着反射型XSS的影响通常不如存储型XSS严重，因为后者在易受攻击的应用程序内部就可以传递自包含的攻击。

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

## 不同上下文中的反射型XSS

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

此外，如果应用程序在反射之前，对所提交的数据进行了任何验证或其他处理，通常会影响所需的XSS载荷类型。

> **阅读更多**
>
> [跨站脚本上下文](https://web-sec.gitbook.io/wsa/client-side/cross-site-scripting/contexts)

## 如何发现和测试反射型XSS漏洞

使用Burp Suite的Web漏洞扫描器可以快速可靠地发现绝大多数反射型跨站脚本漏洞。

手动测试反射型XSS漏洞涉及以下步骤：

* **测试每一个入口点。** 独立测试应用程序HTTP请求中数据的每个入口点。包括URL查询字符串和消息正文中的参数或其他数据，以及URL文件路径。它还包括HTTP标头，尽管只能通过某些HTTP标头触发的类似XSS的行为在实践中可能无法利用。
* **提交随机字母数字值。** 对于每个入口点，提交一个唯一的随机值，确定该值是否反射在响应中。该值应设计为能够通过大多数输入验证，因此需要相当短并且只包含字母数字字符。但它也需要足够长，以确保响应中出现意外匹配的可能性极小。大约8个字符的随机字母数字值通常是理想的。你可以使用Burp Intruder的[`number payloads`](https://portswigger.net/burp/documentation/desktop/tools/intruder/payloads/types#numbers)与随机生成的十六进制值来生成合适的随机值。还可以使用Burp Intruder的[`grep payloads settings`](https://portswigger.net/burp/documentation/desktop/tools/intruder/configure-attack/settings#grep-payloads)来自动标记包含提交值的响应。
* **确定反射上下文。** 对于响应中反射随机值的每个位置，确定其上下文。可能是HTML标签之间的文本、可能被引用的标签属性内、JavaScript字符串内等。
* **测试候选有效载荷。** 根据反射的上下文，测试一个初始的候选XSS载荷，如果它在响应中未被修改地反射，则该有效载荷将触发JavaScript执行。测试有效载荷最简单方式是将请求发送到Burp Repeater，修改请求以插入候选的有效载荷，发出请求，随后检查响应以查看有效载荷是否有效。一种高效的工作方式是将原始随机值保留在请求中，并在其前后放置候选的XSS载荷。然后将随机值设置为Burp Repeater响应视图中的搜索词。Burp将高亮显示搜索词出现的每个位置，让你快速定位反射。
* **测试备选有效载荷。** 如果候选的XSS载荷被应用程序修改或完全屏蔽，那么你需要测试基于反射的上下文和正在执行的输入验证类型，传递有效XSS攻击的备选有效载荷和技术。有关更多详细信息，请参阅[跨站脚本上下文](https://web-sec.gitbook.io/wsa/client-side/cross-site-scripting/contexts)。
* **在浏览器中测试攻击。** 最后，如果你在Burp Repeater中找到了一个看似有效的载荷，请将攻击转移到真实的浏览器中（通过将URL粘贴到地址栏，或通过在Burp Proxy的intercept视图中修改请求），并查看注入的JavaScript是否真的被执行。通常，最好执行一些简单的JavaScript，如`alert(document.domain)`，如果攻击成功，将在浏览器中触发一个可见的弹窗。

## 有关反射型跨站脚本的常见问题

**反射型XSS和存储型XSS之间的区别？** 反射型XSS出现在当应用程序从HTTP请求中获取某些输入，并以不安全的方式将该输入嵌入到紧接着的响应中时。对于存储型XSS，应用程序会将输入存储起来，并以不安全的方式将其嵌入到后续的响应中。

**反射型XSS和自XSS之间的区别？** 自XSS包含与常规反射型XSS类似的应用程序行为，但它无法通过一条精心制作的URL或一个跨域请求的正常方式来触发。相反，只有当受害者自己从他们的浏览器提交XSS载荷时，才会触发漏洞。实施自XSS攻击通常涉及到社会工程学欺骗受害者将攻击者提供的一些输入粘贴到他们的浏览器中。因此，自XSS一般被认为是一个蹩脚的、影响较小的问题。
