XSS又叫CSS(Cross Site Scripting:跨站脚本攻击),是最常见的Web应用程序安全漏洞之一,在2013年度Owasp top 10 中排名第三。
一、XSS原理解析
XSS是在网页中嵌入客户端恶意脚本代码,通常是JavaScript编写的恶意代码,当用户使用浏览器浏览被嵌入恶意代码的网页时,恶意代码将会在用户的浏览器上执行。
JavaScript可以用来获取用户的Cookie、改变网页内容、URL跳转,即存在XSS漏洞的网站,就可以盗取用户Cookie、黑掉页面、导航到恶意网站,而攻击者需要做的仅仅是向Web页面中注入JavaScript代码。
二、XSS类型
XSS主要被分为三类,分别是:反射型、存储型和DOM型。
1. 反射型XSS
反射型XSS也被称为非持久性XSS,是现在最容易出现的一种XSS漏洞。当用户访问一个带有XSS代码的URL请求时,服务器端接收数据后处理,然后把带有XSS代码的数据发送到浏览器,浏览器解析这段带有XSS代码的数据后,最终造成XSS漏洞,这个过程就像一次反射,故称为反射型XSS。
(1)第一步:要有URL请求localhost:3000/?xss=<img src='null' onerror='alert(1)'/>
;
(2)第二步:服务器端接收数据解析并响应;
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
res.set('X-XSS-Protection', 0); // 关闭浏览器对xss的拦截
res.render('index', { title: 'Express', xss: req.query.xss });
});
(3)XSS代码随响应内容一起传回浏览器,浏览器页面获取数据并显示;
// 使用的ejs
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<!-- 要不要对html进行转译,‘-’号:表示不需要进行转译 -->
<%- xss %>
</body>
这个阶段,攻击已经生效了,举以下两种类型:
自动触发型:这是最简单的植入广告的方式
引诱触发型:
总结:
反射型,需要四处散发这个有XSS漏洞的地址,否则就是自己玩,散发出去才能攻击更多的网页,获取更多的用户信息,XSS主要存在URL上。
2. 存储型XSS
存储型XSS又被称为持久性XSS,存储型XSS是最危险的一种跨站脚本。
允许用户存储数据的Web应用程序都可能会出现存储型XSS漏洞,当攻击者提交一段XSS代码后,被服务器接收并存储,当攻击者再次访问某个页面时,这段代码被程序读出来响应给浏览器,造成XSS跨站攻击,这就是存储型XSS。
和反射型XSS的差别在于,不依靠用户手动去触发,具有更高的隐蔽性,危害性更大。
如果不对用户的输入做任何的防御,浏览器就会把XSS代码认为是正常的JavaScript代码来执行,这是很危险的。
3. DOM XSS
基于DOM型的XSS是不需要与服务器端交互的,它只发生在客户端处理数据阶段。
获取URL中参数的值,并且显示在浏览器上,从而给攻击者提供攻击的机会,攻击者可以随意在浏览器URL上输入任意XSS代码,如果不加以防范,不做任何过滤,后果会很严重。
例如:http://www.com?content=<script>alert(/xss)</script>
客户端代码:
<script>
var temp = document.URL; // 获取URL
var index = document.URL.indexOf('content=') + 4;
var par = temp.substring(index);
document.write(decodeURI(par)); // 显示获取的内容
</script>
三、XSS高级利用
XSS不仅仅是弹出一个框那么简单,在某些情况下,XSS不弱于SQL注入。下面列举了几个常见的危害:
- 盗取用户Cookie;
- 修改网页内容;
- 利用网站重定向;
- XSS蠕虫。
四、预防XSS
XSS跨站漏洞最终形成的原因是对输入输出没有严格过滤,在页面执行JavaScript等客户端脚本,这就意味着只要将敏感字符过滤,即可修补XSS跨站漏洞。但这一过程却是复杂无比的,很多情况下无法识别哪些是正常字符,哪些是非正常字符。
1. 输入与输出
都要进行转义,才能让那些XSS代码失效。
-
&(和号)转义为:&
; "(双引号)转义为:"
'(单引号)转义为:'
<(小于)转义为:<
>(大于)转义为:>
XSS可能发生的场景:
- 在标签内输出;
- 在属性内输出;
- 在事件中输出(与属性相同);
- 在css中输出;
- 在script标签中输出。
OWASP提供了一系列解决XSS场景的编码器:针对输入输出。
- html编码:
ESAPI.encoder().encodeForHTML(String input);
ESAPI.encoder().encodeForHTMLAttribute(String input);
- CSS编码:
ESAPI.encoder().encodeForCSS(String input);
- JavaScript编码:
ESAPI.encoder().encodeForJavaScript(String input);
防御XSS没有那么难,只要把控好输入与输出点,针对性的过滤、转义,就能杜绝XSS跨站漏洞。
2. HttpOnly
严格地说,HttpOnly对防御XSS漏洞不起作用,而主要目的是为了解决XSS漏洞后续的Cookie劫持攻击。
什么是HttpOnly:
是微软公司的Internet Explorer 6 SPI引入的一项新特性。这个特性为Cookie提供了一个新属性,用以阻止客户端脚本访问Cookie。至今已成为一个标准,几乎所有的浏览器都会支持HttpOnly。
在身份标识字段使用HttpOnly可以有效的阻挡XSS会话劫持攻击,但却不能够完全阻挡XSS攻击。因为XSS攻击的手段太多:模拟用户“正常”操作、盗取用户信息、钓鱼等,仅靠HttpOnly是不够的,防御的关键还是要靠过滤输入与输出
。