1 概述
本文是走入Linux操作系统系列的其中一篇,本文主要是针对近期关于web安全检测的一些学习和体会,web安全的关心范畴来自于web开发人员,测试人员,安全运维人员,以及互联网的另一头所谓的小黑们。WEB的应用逐渐成为互联网的核心,WEB的安全技术也在兴起,对web安全的问题爆发也越来越流行。
2011年末,一场有CSDN密码泄漏用户数据的事件掀起了一场血淋淋的个人密码泄漏大幕。跟随着网x,xx网,天x,猫x等大型网站的爆库现象,用户的用户名和密码便在互联网上随意下载,一时风声鹤唳,草木皆兵。
2 前言
2011年的那场爆库现象,警方也得出结论,模糊的记得其中2条(与本文不太相关,没有深究其准确性),一是安全意识不够,管理不规范。二是没有使用国家规定安全级别的操作系统。安全问题大都是出自对安全意识问题,如:你的密码在各大网站注册的时候,无论是用户名和密码都是一样的,甚至是你的邮箱。邮箱问题很是严重,因为很多网站是通过邮箱找回密码的,邮箱破解了,很多你的个人秘密和利益都被破解了,当然这其中有一部分属于社会工程学范畴。
一篇文章不能把web安全相关的东西讲的很全面,但我想还是将一些比较重要的东西说出来比较好,这样可以丰富大家的知识。写一篇文章要参考了很多书籍和资料,这里推荐大家的资料为:《The.Web.Application.Hacker’s.Handbook.Finding.and.Exploiting.Security.Flaws,.Stuttard,.Pinto,.2ed,.Wiley,.2011》,当然这本中文翻译本也有了,《黑客攻防技术宝典:Web实战篇(第2版)》 china-pub 地址为:http://product.china-pub.com/3662840 。《白帽子讲WEB安全》。
3WEB安全发展历程
说起安全就会想起hacker这个词,hacker这个词的褒贬暂且不提,对于hacker来说,不想拿到root的hacker不算好hacker,在hacker的行业里,有人分为2种黑客,一种是玩exploit(精通计算机技术,挖掘漏洞编写exploit),另一种是玩脚本的(对攻击本身感兴趣,编程技术不是很高)。在国内存在者一些功利性比较强的黑客,与本主题无关这里闭而不谈。
黑客帝国想必大家都看过吧,其中有很多镜头,如下图:
其中这张图利用到了常见的nmap和ssh,以及一个sshnuke的exploit。最近韩国的幽灵电视剧也有很多镜头显示黑客们利用exploit的技能。但现在的电视剧上关于黑客的镜头大多是无厘头的,cd,ls什么的,便可以入侵了。有点玄乎。
Web安全问题的兴起在web1.0时代,关注服务器动态脚本的安全问题,如webshell(将可执行脚本上传到服务器)。
SQL注入以及XSS的威力也逐步被大家重视,在web2.0时代,XSS以及CSRF的危险则更强大。
上图是2007-2011年web应用安全事件的统计表。
要全面的认识一个安全问题,首先要明白安全问题组成的属性,有人提出了安全的三个要素:机密性,完整性以及可用性,后来有人补充了可审计性和不可抵赖性等要素。
设计安全方案,要做到以下几点:
1 能够有效的解决问题
2 用户体验好
3 高性能
4 低耦合
5 易于扩展和升级
安全问题的发展历程也不是短短百十字能描写清楚,HTML5以及云计算的爆发,对web安全要求越来越高,下面从理论性上简单的了解一下web安全的问题。
4 脚本安全
4.1 浏览器安全
浏览器是互联网的最大入口,每个浏览器都有自己的安全特性,而同源政策的一种安全约定是浏览器最为核心也最为基本的安全功能。web是建在同源策略的基础之上,浏览器则是同源策略的一种实现。
4.1.1同源策略
什么是同源策略?
同源策略是指浏览器会阻止从一个域上加载的脚本获取或者操作另一个域上的文档属性,也就是说,受到请求的URL的域必须与当前的WEB页面的域相同,否则浏览器会主动隔离来自不同源的内容。这一种同源策略,限制了不同源的”document”或脚本。
同源是指:同协议,同域名,同端口,host(域名或IP地址,如果是IP地址可以当作子域名)
他的精髓很简单,它认为任何站点装载的信赖内容是不安全的,当被浏览器半信半疑的脚本运行在沙箱时,它们应该之被运行访问来自同一站点的资源,而不是那些来在其它站点可能怀有恶意的资源。
需要注意的是,对于当前页面来说,页面内存放的javascript文件的域并不重要,重要的是加载js的页面所在的域是什么。如
a.com通过以下代码加载b.com上的b.js。但js是运行在a.com页面中。
a.com的index页面调用b.com的b.js。b.com的index也同样调用b.js.该测试按钮的作用显示当前的href页面。
<script type=”text/javascript” src=”http://www.b.com/b.js”></script>,其测试效果如下:
这个是a.com的测试效果,显示为www.a.com。
而这个则是b.com的测试效果,显示的为www.b.com。
测试的效果显示,其中b.js的脚本是在a.com的页面中运行。因此对于当前页面a.com来说,b.js的源则是a.com;而不是b.com;
测试代码如下:
b.js内容:
function echo(){ var filename = location.href; alert(filename); }
同样的对于<script>,<img>,<iframe>,<link>等标签都可以跨站加载资源,而不受同源策略的限制,实际上这些带”src”属性的标签每次加载时,是由浏览器发起一次GET请求。不同与XMLHttpRequest的是,通过src属性加载的资源,浏览器限制了javascript的权限,使其不能读写返回的内容。
点击测试按钮
而在站a.com则会出现,其中返回错误状态码为0。B1.txt没有取到
可以看的出,XMLHttpRequest 受到同源策略的约束,不能跨域访问资源。
测试代码如下:
b.js loadXMLDoc;
var xmlhttp; 8 function loadXMLDoc(url){ 9 xmlhttp=null; 10 11 if(window.XMLHttpRequest) 12 { 13 xmlhttp= new XMLHttpRequest(); 14 15 } 16 if (xmlhttp!=null) 17 { 18 xmlhttp.onreadystatechange=state_Change; 19 xmlhttp.open("GET",url,true); 20 xmlhttp.send(null); 21 } 22 else{ 23 alert("不支持XMLHttpRequest"); 24 } 25 26 } 27 function state_Change(){ 28 if(xmlhttp.readyState==4){ 29 //4 = "loaded"; 30 if(xmlhttp.status == 200){ 31 //200 = OK 32 document.getElementById("test1").innerHTML=xmlhttp.responseText; 33 } 34 else 35 { 36 alert("错误状态码:" + xmlhttp.statusText); 37 } 38 } 39 }
xmlHttptest.html code: b.com的代码。a.com域的代码类同。
<script type="text/javascript" src="http://www.b.com/b.js"></script> 7 8 <body style="background-color:rgba(44,44,44,0.3);" onload="loadXMLDoc('http://www.b.com/b1.txt')"> 9 <h1 style="font-size:1.2em;color:#228f43;">这是测试<font style="color:red">XMLHttpRequest同源请求</font>页面 </h1> 10 <hr width=80% size=1 color=#00ffff style="border:1 dashed #00ffff; float:left;" ></br> 11 <p style="font-size:14px;color:#fff;">By Qfong >>>www.selinuxplus.com</p> 12 <div id="test1" style="border: 2px solid #228f43;border-radius:3px 3px 3px 3px; height:100px;width:400px;margin:15px;padding:20px;"></ div> 13 <button style="color:#fff;backgroud-color:#c7c7c7;border: 2px solid red ;border-radius: 5px 5px 5px 5px; box-shadow: 0 0 25px rgba(0, 0, 0, 0.5);"; onClick="loadXMLDoc('http://www.b.com/b.txt')"; >测试按钮 </button> 14 15 </body>
但,随着互联网的发展,跨域请求的需求越来越多,W3C委员会制定了针对XMLHttpRequest跨域访问标准。他需要通过目标域返回的HTTP头来授权是否允许跨站访问,由于HTTP对与js来说一般是无法控制的,所以认为这个方案是可以实施的,但注意,可以跨域的方案的安全基数是信任”Javascript无法控制该HTTP头”。如果此信任被打破,则方案也将不在安全。
以下将在chrome上实现跨域访问的实验
点击测试按钮,结果如下:
这个测试需要在服务器端进行修改http header,使其支持Access-Control-Allow-Origin协议。
我们可以抓取http报头信息看到:
http://www.b.com/test.php?url=http://www.b.com/b1.txt
GET /test.php?url=http://www.b.com/b1.txt HTTP/1.1 Host: www.b.com User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Connection: keep-alive Referer: http://www.a.com/xmlhttptest.html Origin: <a href="http://www.a.com/">http://www.a.com</a> 代表http发起的源 HTTP/1.1 200 OK Date: Sun, 02 Sep 2012 05:31:40 GMT Server: Apache/2.2.22 (Fedora) X-Powered-By: PHP/5.3.15 Access-Control-Allow-Origin: <a href="http://www.a.com/">http://www.a.com</a> 此处显示为支持跨域请求。 Content-Length: 74 Connection: close Content-Type: text/html; charset=UTF-8
———————————————————
下面将贴出测试代码:
需要修改b.js的loadXMLDoc(url)函数体的地方
xmlhttp.open("GET","http://www.b.com/test.php?url="+url);
需要使用php修改header的代码
1 <?php 2 header("Access-Control-Allow-Origin:http://www.a.com"); 3 $file=$_GET['url']; 4 echo readfile($file); 5 ?>
如果使用的其他语言实现,需要使用request.addheader方法实现,IE8需要使用XDomainRequest的方法。
跨域的风险是要注意的,ajax一般不允许跨域,也要根据不同的浏览器设定了。跨域容易引起第三方的恶意安全注入,网络攻击者(“中间人攻击”) 可能篡改服务器响应内容从而可能攻击你编写的扩展内容。
对于浏览器而言,除了DOM,Coookie,XMLHttpRequest受到同源策略的限制外,第三方插件也有各自的同源策略。如 flash,JAVA Applet等。
同源策略也会有很多漏洞,这里就不再深究下去了,有兴趣的可以查阅互联网