跨站脚本攻击,英文全称是 Cross Site Script,本来缩写是 CSS,但是为了和层叠样式表(Cascading Style Sheet,CSS )有所区别,所以在安全领域叫做“XSS”。
XSS 攻击,通常指黑客通过“ HTML 注入”篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。
在一开始,这种攻击的演示案例是跨域的,所以叫做“跨站脚本”。
针对各种不同场景长生的XSS,需要区分情景对待。
XSS 根据效果的不同可以分成如下几类:
XSS Payload 实际上就是 JavaScript 脚本(还可以是 Flash 或其他富客户端的脚本)
,所以任何 JavaScript 脚本能实现的功能,XSS Payload 都能做到。
一个常见的 XSS Payload ,就是通过读取浏览器的 Cookie 对象,从而发起“ Cookie 劫持”攻击。
Cookie 中一般加密保存了当前用户的登录凭证。Cookie如果丢失,往往意味着用户的登录凭证丢失。换句话说,攻击者可以不通过密码,而直接登录金用户的账户。
如下所示,攻击者先加载一个远程脚本。
http://www.a.com/test.htm?abc=''>
真正的 XSS Payload 写在这个远程脚本中,避免直接在 URL 的参数里写入大量的 JavaScript 代码。
在 evil.js 中,可以通过代码窃取 Cookie,如获取当前页面的 document.cookie 对象作为参数发送至远程服务器,这就是一个最简单的窃取 Cookie 的 XSS Payload。
如何利用窃取的 Cookie 登录目标用户的账户呢?这和“利用自定义 Cookie 访问网站”过程是一样的,在 Firefox 中访问网站( www.a.com
),查看当前的 Cookie 并复制,再打开 IE 浏览器把 Firefox 复制好的 Cookie 替换当前 IE 中的 Cookie。 重新发送这个包即可。
Cookie 的“ HttpOnly ”标识可以防止“ Cookie 劫持”。
“ Cookie 劫持”并非所有的时候都有效。有的网站可能会在 Set-Cookie 时给关键 Cookie 植入 HttpOnly 标识;有的网站则可能会把 Cookie 与客户端 IP 绑定,从而使得 XSS 窃取的 Cookie 失去意义。
XSS 攻击后,攻击者除了可以实施“ Cookie 劫持” 外,还能够通过模拟 GET、POST请求操作用户的浏览器。这在某些隔离环境中会非常有用,比如“ Cookie 劫持 ” 失效时, 或者目标用户的网络不能访问互联网等情况。
浏览器的 UserAgent 可以伪造。
JavaScript 本身并没有提供获取本地 IP 地址的能力,XSS 攻击者需要借助第三方软件来完成。
常见的 XSS 攻击平台
以往的蠕虫是利用服务器端软件漏洞进行传播的。
XSS Worm 是 XSS 的一种终极利用方式,它的破坏力和影响力是巨大的。但是发起 XSS Worm 攻击也有一定的条件。
一般来说,用户之间发生交互行为的页面,如果存在存储型 XSS,则比较容易发起 XSS Worm 攻击。
常用的调试 JavaScript 工具:
在某些环境下,可以 利用注释符绕过长度限制。
比如我们能控制两个文本框,第二个文本框允许写入更多的字节。此时可以利用 HTML 的“注释符号”,把两个文本框之间的 HTML 代码全部注释掉,从而“打通”两个 标签。
需要特别注意地是,在有的技术文档中,提到 标签只能用于 标签之内,其实这是不对的。 标签可以出现在页面的任何地方,并作用于位于该标签之后的所有标签。
攻击者如果在页面中插入了 标签,就可以通过在远程服务器上伪造图片、链接或脚本,劫持当前页面中的所有使用“相对路径”的标签。
在设计 XSS 安全方案时,一定要过滤掉这个非常危险的标签。
window.name 对象是一个很神奇的东西。对当前窗口的 window.name 对象赋值,没有特殊字符的限制。因为 window 对象是浏览器的窗体,而并非 document 对象,因此很多时候 window 对象不受同源策略的限制。攻击者利用这个对象,可以实现跨域、跨页面传递数据。在某些环境下,这种特性将变得非常有用。
从 XSS 漏洞利用的角度来看,存储型 XSS 对攻击者的用处比反射型 XSS 要大。因为存储型 XSS 在用户访问正常 URL 时会自动触发;而反射型 XSS 会修改一个正常的 URL,一般要求攻击者将 XSS URL 发送给用户点击,无形中提高了攻击的门槛。
反射型 XSS 也有可能像存储型 XSS 一样利用:将要利用的反射型 XSS 嵌入一个存储型 XSS 中。
因为浏览器同源策略的原因,XSS 也受到同源策略的限制----发生在 A 域上的 XSS 很难影响到 B 域的用户。
回旋镖的思路就是:如果在 B 域上存在一个反射型 “ XSS_B ”,在 A 域上存在一个存储型“ XSS_A ”,当用户访问 A 域上的“ XSS_A ”时,同时嵌入 B 域上的“ XSS_B ”,则可以达到在 A 域的 XSS 攻击 B 域用户的目的。
XSS 漏洞是一个 Web 安全问题,不能因为它的利用难易程度而决定是否应该修补。随着技术的发展,某些难以利用的漏洞,也许不再是难题。
前文讲到的 XSS 攻击都是基于 HTML 的,其实在 Flash 中同样也有可能造成 XSS 攻击。
在 Flash 中是可以嵌入 ActionScript 脚本。一个最常见的 Flash XSS 可以这样写:
getURL ("javascript:alert(document.cookie)")
ActionScript 是一种非常强大和灵活的脚本,甚至可以使用它发起网络连接,因此应该尽可能禁止用户能够上传或加载自定义的 Flash 文件。
由于 Flash 文件如此危险,所以在实现 XSS Filter 时,一般都会禁用 、等标签。
XSS 的防御是复杂的。
HttpOnly 最早是由微软提出,并在 IE 6 中实现的,至今已经逐渐成为一个标准。浏览器将禁止页面的 JavaScript 访问带有 HttpOnly 属性的 Cookie 。
严格的说,HttpOnly 并非为了对抗 XSS ---- HttpOnly 解决的是 XSS 后的 Cookie劫持攻击。
使用 HttpOnly 有助于缓解 XSS 攻击,但仍然需要其他能够解决 XSS 漏洞的方案。
常见的 Web 漏洞如 XSS、SQL Injection 等,都要求攻击者构造一些特殊字符,这些特殊字符可能是正常用户不会用到的,所以输入检查就有存在的必要了。
在 XSS 的防御上,输入检查一般是检查用户输入的数据中是否包含一些特殊字符,如 <、>、’ 、" 等。如果发现存在特殊字符,则将这些字符过滤或者编码。
一般来说,除了富文本的输出外,在变量输出到 HTML 页面时,可以使用编码或转义的方式来防御 XSS 攻击。
XSS 的本质还是一种“ HTML 注入”,用户的数据被当成了 HTML 代码一部分来执行,从而混淆了原本的语义,产生了新的语义。
在过滤富文本时,“事件”应该被严格禁止,因为“富文本”的展示需求里不应该包括“事件”这种动态效果。而一些危险的标签,比如 、
、
、 等,也是应该严格禁止的。
在标签的选择上,应该使用白名单,避免使用黑名单。 比如,只允许 “白名单原则”不仅仅用于标签的选择,同样应该用于属性与事件的选择。 在富文本过滤中,处理 CSS 也是一样麻烦的事情。如果允许用户自定义 CSS、style,则也可能导致 XSS 攻击。因此尽可能地禁止用户自定义 CSS 与 style 。 DOM Based XSS 是一种比较特别的 XSS 漏洞。 DOM Based XSS 是从 JavaScript 中输出数据到 HTML 页面里。 一般来说,存储型 XSS 的风险会高于反射型 XSS 。因为存储型 XSS 会保存在服务器上,有可能会跨页面存在。它不改变页面 URL 的原有结构,因此有时候还能逃过一些 IDS 的监测。比如 IE 8 的 XSS Filter 和 Firefox 的 Noscript Extension ,都会检查地址栏中的地址是否包含 XSS 脚本。而跨页面的存储型 XSS 可能会绕过这些检测工具。 从攻击过程来说,反射型 XSS,一般要求攻击者诱使用户点击一个包含 XSS 代码的 URL 链接;而存储型 XSS,则只需要让用户查看一个正常的 URL 链接。 从风险的角度看,用户之间有互动的页面,是可能发起 XSS Worm 攻击的地方。而根据不同页面的 PageView 高低,也可以分析出哪些页面受 XSS 攻击后的影响会更大。比如在网站首页发生的 XSS 攻击,肯定比网站合作伙伴页面的 XSS 攻击要严重得多。、
、
3.3.6 防御 DOM Based XSS
3.3.7 换个角度看 XSS 的风险