1.   XSS简介

跨站脚本攻击,英文全称是Cross Site Script,本来缩写是CSS,但是为了和层叠样式(Cascading Style Sheet,CSS)有所区别,所以在安全领域叫做“XSS”。

XSS攻击,通常是指黑客通过“HTML注入”篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。在一开始,这种攻击的演示案例是跨域的,所以叫做“跨站脚本”

XSS长期以来被列为客户端Web安全中的头号大敌。因为XSS破坏力强大,且产生的场景发杂,难以一次性解决。现在业内达成的共识是:针对各种不同场景产生的XSS,需要区分情景对待。

第一种类型:反射型XSS

反射型XSS只是简单地把用户输入的数据“反射”给浏览器。也就是说,黑客往往需要诱使用户“点击”一个恶意链接,才能攻击成功。反射型XSS也叫做“非持久型XSS”(Non-persistent XSS)

第二种类型:存储型XSS

存储型XSS会把用户输入的数据“存储”在服务器端。这种XSS具有很强的稳定性。

比较常见的场景就是,黑客写下一篇包含有恶意JavaScript代码的博客文章,文章表达后,所有访问该博客文章的用户,都会在他们的浏览器中执行这段恶意的JavaScript代码。黑客把恶意的脚本保存到服务器端,所以这种XSS攻击叫做“存储型XSS”。

存储型XSS通常也叫做“持久型XSS”(Persistent XSS),因为从效果上来说,它存在的时间比较长的。

第三种类型:DOM Based XSS

这种类型的XSS并非按照“数据收费保存在服务器端”来划分,DOM Based XSS从效果上来说也是反射型XSS。

XSS的防御

XSS的防御是复杂的。

流行的浏览器都内置了一些对抗XSS的措施,比如Firefox的CSP、Noscript扩展,IE 8内置的XSS Filter等。对于网站来说,也应该寻找优秀的解决方案,保护用户不被XSS攻击。

2.1  HttpOnly

HttpOnly最早是由微软提出,并在IE 6中实现的,至今已经逐渐成为一个标准。浏览器将静止页面的JavaScript访问带有HttpOnly属性的Cookie。

严格地来说,HttpOnly并非为了对抗XSS——HttpOnly解决的是XSS后的Cookie劫持。

2.3 正确地防御XSS

为了更好地设计XSS防御方案,需要认清XSS产生的本质原因。

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

如果网站使用了MVC架构,那么XSS就发生在View层——在应用拼接变量到HTML页面时产生。所以在用户提交数据处进行输入检查的方案,其实并不是在真正发生攻击的地方做防御。

想要根治XSS问题,可以列出所有XSS可能发生的场景,再一一解决。

换个角度看XSS的风险

前文谈到的所有XSS攻击,都是从漏洞形成的原理上看的。如果从业务风险的角度来看,则会有不同的观点。

一般来说,存储型XSS的风险会高于反射型XSS。因为存储型XSS会保存在服务器上,有可能会跨页面存在。它不改变页面URL的原有结构,因此有时候还能逃过一些IDS的检测。比如IE 8的XSS Filter和Firefox的Noscript Extension,都会检查地址栏中的地址是否包含XSS脚本。而跨页面的存储型XSS可能会绕过这些检测工具。

从攻击过程来说,反射型XSS,一般要求攻击者诱使用户点击一个包含XSS代码的URL链接;而存储型XSS,则只需要让用户查看一个正常的URL链接。比如一个Web邮箱的邮件正文页面存在一个存储型的XSS漏洞,当用户打开一封新邮件时,XSS Payload会被执行。这样的漏洞极其隐蔽,且埋伏在用户的正常业务中,风险颇高。

从风险的角度看,用户之间有互通的页面,是可能发起XSS Worm攻击的地方。而根据不同页面的PageView高低,也可以分析出哪些页面受XSS攻击后的影响会更大。比如在网站首页发生的XSS攻击,肯定比网站合作伙伴页面的XSS攻击严重得多。

在修补XSS漏洞时遇到的最大挑战之一是漏洞数量太多,因此开发者可能来不及,也不愿意修补这些漏洞。从业务风险的角度来重新定位每个XSS漏洞,就具有了重要的意义。