跨站脚本攻击 ,英文全称是 Cross Site Script,本来缩写是 CS S,但是为了和层叠样式表(Cascading Style Sheet,CSS)有所区别,所以在安全领域叫做“XSS”。
XSS攻击,通常指黑客通过“HTML注入”篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。在一开始,这种攻击的演示案例是跨域的,所以叫做“跨站脚本”。但是发展到今天,由于JavaScript的强大功能以及网站前端应用的复杂化,是否跨域已经不再重要。但是由于历史原因,XSS这个名字却一直保留下来。
XSS长期以来被列为客户端Web安全中的头号大敌。因为XSS破坏力强大,且产生的场景复杂,难以一次性解决。现在业内达成的共识是:针对各种不同场景产生的XSS,需要区分情景对待。即便如此,复杂的应用环境仍然是XSS滋生的温床。
那么,什么是XSS呢?看看下面的例子。
假设一个页面把用户输入的参数直接输出到页面上:
在正常情况下,用户向param提交的数据会展示到页面中,比如提交:
会得到如下结果:
正常的用户请求
此时查看页面源代码,可以看到:
但是如果提交一段HTML代码:
会发现,alert(/xss/)在当前页面执行了:
包含了XSS攻击的用户请求结果
再查看源代码:
用户输入的Script脚本,已经被写入页面中,而这显然是开发者所不希望看到的。
上面这个例子,就是XSS的第一种类型:反射型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。单独划分出来,是因为DOM Based XSS的形成原因比较特别,发现它的安全专家专门提出了这种类型的XSS。出于历史原因,也就把它单独作为一个分类了。
通过修改页面的DOM节点形成的XSS,称之为DOM Based XSS。
看如下代码:
点击“write”按钮后,会在当前页面插入一个超链接,其地址为文本框的内容:
在这里,“write”按钮的onclick事件调用了test()函数。而在test()函数中,修改了页面的DOM节点,通过innerHTML把一段用户数据当做HTML写入到页面中,这就造成了DOM based XSS。
构造如下数据:
输入后,页面代码就变成了:
首先用一个单引号闭合掉href的第一个单引号,然后插入一个onclick事件,最后再用注释符“//”注释掉第二个单引号。
点击这个新生成的链接,脚本将被执行:
恶意脚本被执行
实际上,这里还有另外一种利用方式——除了构造一个新事件外,还可以选择闭合掉<a>标签,并插入一个新的HTML标签。尝试如下输入:
页面代码变成了:
脚本被执行:
恶意脚本被执行