跨站脚本(XSS)
翻译
原文:https://portswigger.net/web-security/cross-site-scripting
- name: 翻译
desc: 原文:https://portswigger.net/web-security/cross-site-scripting
bgColor: '#F0DFB1'
textColor: 'green'
2
3
4
简而言之,XSS 是最重要的漏洞之一。它既常见、又非常强大,特别是它被用作 广大漏洞利用链 的一部分时。
这是一个巨大的主题,为初学者和经验丰富的专业人士提供了大量的实验室。
访问官方链接 (opens new window)学习跨站脚本(XSS)。
# 0跨站脚本(XSS)
在本节中,我们将解释什么是跨站脚本,描述不同种类的跨站脚本漏洞,并详细说明如何发现和防范跨站脚本。
# 1什么是跨站脚本(XSS)?
跨站脚本(也称为 XSS)是一个 Web 安全漏洞,允许攻击者破坏用户与应用程序之间的交互。它允许攻击者绕过同源策略,该策略旨在将不同的网站相互隔离。
跨站脚本漏洞通常允许攻击者伪装成受害用户、执行用户能够执行的任何操作、以及访问用户的任何数据。如果受害用户在应用程序中拥有特权访问权限,则攻击者可能完全控制应用程序的所有功能和数据。
# 2XSS 是如何工作的?
跨站脚本的工作原理是:操纵易受攻击的网站,以便将恶意 JavaScript 返回给用户。当恶意代码在受害者的浏览器中执行时,攻击者可以完全破坏他们与应用程序的交互。
实验室
如果您已经熟悉 XSS 漏洞背后的基本概念,并且只想在一些实际的、易受攻击的目标上练习和利用它们,那么您可以从下面的链接访问本主题中的所有实验室。
# 3XSS 概念验证
你可以通过注入一个有效负载,来确认大多数类型的 XSS 漏洞,该负载会导致你自己的浏览器执行某些任意的 JavaScript 代码。长期以来,使用alert()
函数来实现此目的一直是常见的做法,因为它简短、无害,并且在成功调用时很难被忽略。在我们的实验室中,你可以通过在模拟受害者的浏览器中调用alert()
,从而解决大多数 XSS 实验。
不幸的是,如果你使用 Chrome 浏览器,则会出现一个小问题。从 92 版本开始(2021年7月20日),跨域 iframe 被禁止调用alert()
。出于这个原因,有时需要构建一些更高级的 XSS 攻击,例如使用替代 PoC 有效负载。在这种情况下,我们建议使用print()
函数。如果你有兴趣,想了解更多关于此变化的信息,以及我们为什么喜欢print()
,请查看我们关于该主题的博客文章 (opens new window)。
由于我们实验室中的模拟受害者使用 Chrome,因此我们修改了受影响的实验室,以便它们也可以使用print()
来通关。我们已经在相关的说明中指出了这一点。
# 4XSS 攻击有哪些类型?
XSS 攻击主要有三种类型。分别是:
- 反射型XSS (opens new window),恶意脚本来自当前 HTTP 请求。
- 存储型XSS (opens new window),恶意脚本来自网站的数据库。
- 基于DOM的XSS (opens new window),漏洞存在于客户端代码中,而不是服务器端代码。
# 5反射型跨站脚本
反射型XSS (opens new window)是最简单的跨站脚本。当应用程序在 HTTP 请求中接收数据,并以不安全的方式 将该数据包含在即时响应中时,就会出现此问题。
下面是一个反射型 XSS 漏洞的简单示例:
https://insecure-website.com/status?message=All+is+well.
<p>Status: All is well.</p>
2
应用程序不会对数据进行任何其他处理,因此攻击者可以轻松构建如下攻击:
https://insecure-website.com/status?message=<script>/*+Bad+stuff+here...+*/</script>
<p>Status: <script>/* Bad stuff here... */</script></p>
2
如果用户访问攻击者构造的 URL,在该用户与应用程序会话的上下文中,攻击者的脚本将在该用户的浏览器中执行。此时,脚本可以执行该用户有权访问的任何操作,并检索任何数据。
# 6存储型跨站脚本
存储型XSS (opens new window)(也称为持久性或二阶XSS)。当应用程序从不受信任的来源接收数据,并以不安全的方式将该数据包含在其之后的 HTTP 响应中时,就会出现此问题。
有问题的数据可能通过 HTTP 请求提交给应用程序;例如,博客文章的评论、聊天室中的用户昵称 或客户订单中的联系人详细信息。在某些情况下,数据可能来自其他不受信任的来源;例如,显示 SMTP 消息的 Web 邮件应用、显示社交媒体帖子的营销应用、或显示来自网络流量分组数据的网络监视应用。
下面是一个存储型 XSS 漏洞的简单示例。留言板应用程序允许用户提交消息,这些消息将显示给其他用户:
<p>Hello, this is my message!</p>
该应用程序不对数据进行任何其他处理,因此攻击者可以轻松地 向其他用户发送恶意消息:
<p><script>/* Bad stuff here... */</script></p>
# 7基于DOM的跨站脚本
基于DOM的XSS (opens new window)(也称为DOM型XSS (opens new window))出现在应用程序包含一些客户端 JavaScript 时,这些 JavaScript 以不安全的方式 处理来自不受信任源的数据,通常是将数据写回 DOM 中。
在下面的示例中,应用程序使用一些 JavaScript 从输入字段读取值,并将该值写入 HTML 中的元素:
var search = document.getElementById('search').value;
var results = document.getElementById('results');
results.innerHTML = 'You searched for: ' + search;
2
3
如果攻击者可以控制输入字段的值,他们就可以轻松构造一个恶意值,从而执行他们自己的脚本:
You searched for: <img src=1 onerror='/* Bad stuff here... */'>
在典型情况下,输入字段将从 HTTP 请求的一部分填充,例如 URL 查询字符串的参数。这允许攻击者使用恶意 URL,并通过与反射型 XSS 相同的方式来传递攻击。
# 8XSS可以用来做什么?
利用跨站脚本漏洞的攻击者通常能够:
- 冒充或伪装成受害用户。
- 执行用户能够执行的任何操作。
- 读取用户能够访问的任何数据。
- 捕获用户的登录凭据。
- 对网站进行虚拟污损。
- 将特洛伊木马功能程序注入网站。
(译者加:“虚拟污损” 又被称为 “内容欺骗” 或 “内容注入”,详细信息可参考OWASP文章 (opens new window))
# 9XSS漏洞的影响
XSS 攻击的实际影响,通常取决于应用程序的性质、功能和数据 以及受影响用户的状态。例如:
- 在宣传类的软件应用程序中,所有用户都是匿名的,所有信息都是公开的,影响通常很小。
- 在保存敏感数据(如银行交易、电子邮件或医疗记录)的应用程序中,影响通常会很严重。
- 如果受影响的用户 在应用程序中具有更高的权限,则影响通常很严重,这允许攻击者完全控制易受攻击的应用程序,并危害所有用户及其数据。
# 10如何查找和测试 XSS 漏洞
使用 Burp Suite 的Web漏洞扫描程序 (opens new window)可以快速可靠地发现绝大多数 XSS 漏洞。
手动测试反射型和存储型 XSS 通常涉及:将一些简单的唯一输入(例如短的字母数字字符串)提交到应用程序中的每个入口点,识别 HTTP 响应中返回所提交输入的每个位置,并单独测试每个位置,以确定是否可以构造适当的输入,来执行任意 JavaScript。通过这种方式,你可以确定 XSS 发生的上下文 (opens new window),并选择合适的有效负载来利用它。
手动测试由 URL 参数产生的 DOM XSS 涉及类似的过程:在参数中放置一些简单的唯一输入,使用浏览器的开发人员工具在 DOM 中搜索此输入,并测试每个位置 以确定它是否可利用。但是,某些类型的 DOM XSS 更难检测。要在非基于 URL 的输入(如document.cookie
)或非基于 HTML 的接收器(如setTimeout
)中查找基于 DOM 的漏洞,审查 JavaScript 代码是无可替代的,这可能非常耗时。Burp Suite 的 Web 漏洞扫描程序结合了 JavaScript 的静态和动态分析,能够可靠地自动检测基于 DOM 的漏洞。
# 11内容安全策略(CSP)
内容安全策略(CSP)是一种浏览器机制,旨在减轻跨站脚本和一些其他漏洞的影响。如果使用 CSP 的应用程序包含类似 XSS 的行为,则 CSP 可能会阻碍或阻止利用此漏洞。通常,可以绕过 CSP 以利用潜在的漏洞。
# 12悬挂标记注入
悬挂标记注入是一种技术,可用于 由于输入过滤器或其他防御,而无法完整利用跨站脚本漏洞的情况下,进行跨域捕获数据。它通常可以用来 捕获其他用户可见的敏感信息,包括 用来代表用户执行未授权操作的 CSRF 令牌。
# 13如何防范XSS攻击
在某些情况下,防范跨站脚本是很简单的,但根据应用程序的复杂性、及其处理用户可控数据的方式,这可能会变得困难很多。
通常,XSS 漏洞的有效防范 可能涉及以下措施的组合:
- 在接收时过滤输入。在接收到用户输入时,根据预期输入 或 有效输入,尽可能严格地进行筛选。
- 在输出时对数据进行编码。在 HTTP 响应中输出用户可控数据的点,对输出进行编码,以防止将其被解释为有效内容。根据输出上下文,这可能需要应用 HTML、URL、JavaScript 和 CSS 编码的组合。
- 使用适当的响应标头。若要防止 HTTP 响应中的 XSS 包含任何 HTML 或 JavaScript,可以使用
Content-Type
和X-Content-Type-Options
标头来确保 浏览器以预期的方式解释响应。 - 内容安全政策。作为最后一道防线,你可以使用内容安全策略(CSP)降低未来发生的任何 XSS 漏洞的严重性。
# 14有关跨站脚本的常见问题
XSS 漏洞有多常见?XSS 漏洞非常常见,XSS 可能是最常出现的 Web 安全漏洞。
XSS 攻击有多常见?很难在现实中获得有关 XSS 攻击的可靠数据,但它被利用的频率可能低于其他漏洞。
XSS 和 CSRF 有什么区别?XSS 导致网站返回恶意 JavaScript,而 CSRF 诱使受害用户执行他们不打算执行的操作。
XSS 和 SQL 注入有什么区别?XSS 是针对其他应用程序用户的客户端漏洞,而 SQL 注入是针对应用程序数据库的服务器端漏洞。
如何在 PHP 中防范 XSS?使用允许字符的白名单过滤输入,并使用类型提示或类型转换。使用htmlentity
和ENT_QUOTES
对 HTML 上下文进行转义输出,对 JavaScript 上下文进行 Unicode 转义。
如何在 Java 中防范 XSS?使用允许字符的白名单过滤输入,并使用 Google Guava 等库对 HTML 上下文的输出进行 HTML 编码,对 JavaScript 上下文进行 Unicode 转义。