跨站脚本(Cross-Site Scripting,XSS)是一种经常出现在Web应用程序中的计算机安全漏洞,是由于Web应用程序对用户的输入过滤不足而产生的。攻击者利用网站漏洞把恶意的脚本代码(通常包括HTML代码和客户端Javascript脚本)注入到网页之中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害用户可能采取Cookie资料窃取、会话劫持、钓鱼欺骗等各种攻击。
XSS跨站脚本攻击本身对Web服务器没有直接危害,它借助网站进行传播,使网站的大量用户受到攻击。攻击者一般通过留言、电子邮件或其他途径向受害者发送一个精心构造的恶意URL,当受害者在Web浏览器中打开该URL的时侯,恶意脚本会在受害者的计算机上悄悄执行。
XSS可能造成的危害
(1)网络钓鱼,包括盗取各类用户账号;
(2)窃取用户cookies资料,从而获取用户隐私信息,或利用用户身份进一步对网站执行操作;
(3)劫持用户(浏览器)会话,从而执行任意操作,例如进行非法转账、强制发表日志、发送电子邮件等;
(4)传播跨站脚本蠕虫等;
(5)提升用户权限,包括进一步渗透网站;
(6)大量的客户端攻击,如DDoS攻击;
(7)获取客户端信息,例如用户的浏览历史、真实IP、开放端口等;
(8)控制受害者机器向其他网站发起攻击;
(9)结合其他漏洞,如CSRF漏洞,实施进一步作恶。
为什么XSS如此普遍和流行?
仅从技术上看该问题:
(1)Web浏览器本身的设计是不安全的。浏览器包含了解析和执行JavaScript等脚本语言的能力,这些语言可用来创建各种格式丰富的功能,而浏览器只会执行,不会判断数据和程序代码是否恶意。
(2)输入与输出是Web应用程序最基本的交互,在这过程之中若没做好安全防护,Web程序很容易会出现XSS漏洞。
一个JavaScripts脚本来举例说明:
<html>
<head>test</head>
<body>
<script>alert("XSS")</script>
</body>
</html>
把JavaScript加入到Web页面中非常简单,只要页面中包含一个 script 标记,就可以增加想要的JavaScript代码。HTML的script元素标记中间包含JavaScript,这使浏览器知道:当它遇到script 标记时,不将此标记内容处理成 HTML或XHTML,从这一点开始,对于内容的控制权已转移给另一个内置的浏览器代理——脚本引擎处理。
XSS攻击就是将非法的JavaScript、VBscript等脚本注入到用户浏览的网页上执行,而Web浏览器本身的设计是不安全的,它只负责解释和执行JavaScript等脚本语言,而不会判断代码本身是否对用户有害。
XSS的分类
XSS根据其特性和利用手法的不同,主要分成两大类型:一种是反射型跨站脚本;另一种是持久型跨站脚本。
反射型跨站脚本(Reflected Cross-site Scripting)也称作非持久型、参数型跨站脚本。这种类型的跨站脚本是最常见,也是使用最广的一种,主要用于将恶意脚本附加到URL地址的参数中。
反射型XSS的利用一般是攻击者通过特定手法(比如利用电子邮件),诱使用户去访问一个包含恶意代码的URL,当受害者单击这些专门设计的链接的时候,恶意JavaScript代码会直接在受害者主机上的浏览器执行。它的特点是只在用户单击时触发,而且只执行一次,非持久化,所以称为反射型跨站式脚本。
此类 XSS 通常出现在网站的搜索栏、用户登入口等地方,常用来窃取客户端 Cookies 或进行钓鱼欺骗。
反射型XSS的危害往往不如持久型,因为恶意代码暴露在URL参数中,只有用户单击方可触发,稍微有点安全意识的用户可以轻易看穿该链接是不可信任的。但一般URL转码后带有迷惑性,路边的URL不要随便采。
持久型跨站脚本(Persistent Cross-site Scripting)也等于存储型跨站脚本(Stored Cross-site Scripting),比反射型跨站脚本更具威胁性,并且可能影响到Web服务器自身的安全。此类XSS不需要用户单击特定URL就能执行跨站脚本,攻击者事先将恶意JavaScript代码上传或存储到漏洞服务器中,只要受害者浏览包含此恶意JavaScript代码的页面就会执行恶意代码。
持久型 XSS 一般出现在网站的留言、评论、博客日志等交互处,恶意脚本被存储到客户端或者服务器的数据库中,当其他用户浏览该网页时,站点即从数据库中读取恶意用户存入的非法数据,然后显示在页面中,即在受害者主机上的浏览器执行恶意代码。
测试的福音:XSS语句列表
XSS语句列表罗列了各种各样的XSS代码,这些XSS代码在不同的浏览器、不同的应用场景、不同的环境下均有跨站触发的可能。通常,此类列表被称为Cheat Sheet,即我们平时所指的备忘单。
国外著名安全工程师Rsnake是研究XSS方面的高手,他把自己对XSS的研究心得总结成Cheat Sheet,并在其个人主页分享了一份常见的XSS攻击脚本列表,可用来检测Web应用程序是否存在XSS 漏洞。
可以通过http://ha.ckers.org/xss.html 看到这份XSS Cheat Sheet。一些测试用例如下
表1 表2 表3开发编程注意
通常情况下,为了防御跨站脚本攻击,会在Web应用中设计一个XSS Filter,即跨站脚本过滤器,用于分析用户提交的输入,并消除潜在的跨站脚本攻击、恶意的HTML或简单的HTML格式错误等。XSS Filter一般是基于黑白名单的安全过滤策略,即把要处理的数据分成白名单和黑名单两大列表,白名单存放的是可信赖、对应用程序不构成威胁的数据列表,黑名单则相反。
(1)利用< >标记注射Html /Javascript。
如果用户可以随心所欲地引入< >等标记,那么他就能操作一个HTML标签,然后通过<scirpt>标签就能任意插入由JavaScript或Vbscript编写的恶意脚本代码,如:<script>alert('XSS'); </script>
因此,XSS Filter首当其冲要进行过滤和转义的就是“< >”或 “<script>” 等字符。
(2)利用HTML标签属性值执行XSS。
很多HTML标记中的属性都支持javascript:[code]伪协议的形式,这个特殊的协议类型声明了URL的主体是任意的JavaScript代码,由JavaScript的解释器运行。因为不是所有的Web浏览器都支持JavaScript伪协议,所以此类XSS攻击具有一定的局限性。
并不是所有标记的属性值都能产生XSS,通常只有引用文件的属性才能触发跨站脚本。
总而言之,要防御基于属性值的XSS,就要过滤JavaScript等关键字。并非所有嵌入到Web页面中的脚本都是JavaScript,还有其他允许值,比如Vbscript。
(3)空格回车Tab。
如果XSS Filter仅仅把敏感的输入字符列入黑名单处理,如对敏感字 javascript而言,用户可以利用空格、回车和Tab键绕过限制,请看下面的例子:<img src="javas cript:alert(/xss/)" width=100>,请注意javas和cript之间的间隔不是由空格键添加的,而是用【Tab】键添加的。
(4)对标签属性值转码。
对普通HTML标记的属性值进行过滤,用户可以通过编码处理来绕过,因为HTML中属性值本身支持ASCII码形式。举例把XSS代码:<img src="javascript:alert('XSS');"> 换成:<img src="javascript:alert(/XSS/);" >
(5)产生自己的事件。
假设用户不依靠属性值进行跨站,那还有没有其他方法?答案是肯定的,事件就是其中一种方法。JavaScript与HTML之间的交互是通过事件来实现的,事件就是用户或浏览器自身执行的某种动作,比如click、mouseover、load等,而响应事件的函数就叫做事件处理函数(或事件侦听器)。
(6)利用CSS跨站剖析。
XSS跨站脚本的另一个载体是CSS样式表,使用CSS样式表执行JavaScript具有隐蔽、灵活多变等特点,但是 CSS 样式表有一个很大的缺点:各浏览器之间不能通用,甚者可能同一浏览器不同版本之间都不能通用。使用CSS直接执行JavaScript代码的如下:
<div style="background-image:url(javascript:alert('XSS'))">
<style>
body {background-image: url("javascript:alert('XSS')");}
</style>
(7)扰乱过滤规则。
利用前面所述的各种技巧,包括 HTML 标签属性值、事件、CSS、编码技术等,用户能顺利绕过XSS Filter的重重过滤。
一个正常的XSS输入:<img src="javascript:alert(0);">
转换大小写后的XSS:<IMG SRC="javascript:alert(0);">
大小写混淆的XSS:<iMg sRC="jaVasCript:alert(0);">
不用双引号,而是使用单引号的XSS:<img src='javascript:alert(0);'>
不使用引号的XSS:<img src=javascript:alert(0);>
抛开正常的XSS测试用例,运用以上的任何一种示例都有可能绕过XSS Filter。
看完上边内容大致了解了:在什么环境下可以触发XSS,利用XSS漏洞可以做什么,如何防范此类攻击等。
网友评论