一、浏览器的同源策略
同源策略:不同域的客户端脚本在未经授权的情况下不能读写对方的资源。
这里有几个关键词:域、脚本、授权、读写、资源
1、同域要求两个站点:同协议、同域名、同端口。下表展示了所列站点与http://www.a.com是否同域的情况。
站点 | 是否同域 | 原因 |
https://www.a.com | 不同域 | 协议不同,http和https是不同的协议 |
http://map.a.com | 不同域 | 域名不同,map子域和www子域不同 |
http://a.com | 不同域 | 域名不同,顶级域名和www子域不是一个概念 |
http://www.a.com:8080 | 不同域 | 端口不同,8080和默认的80端口不同 |
http://www.a.com/a/ | 同域 | 满足同协议、同域名、同端口,只是多了一个目录 |
2、脚本:主要指JavaScript和ActionScript,当然也包括VBScript(相对较孤立)。
3、授权:如Ajax跨域,默认情况下是不允许跨域访问的,只有目标站点(假如是http://www.a.com)明确返回http响应头 Access-Control-Allow-Origin:http://www.e.com时,www.e.com站点上的客户端脚本才能有权通过Ajax技术对www.a.com上的数据进行读写操作。
4、读写权限:web上的资源有很多,有的只有读权限,有的同时拥有读和写的权限。比如:http请求头里的Referer只可读,而document.cookie则具备读写权限。
5、资源:同源策略里的资源是指web客户端的资源。一般来说,包括:http消息头、整个DOM树、浏览器存储(Cookies、FlashCookies、localStorage等)。
如果没有同源策略,web世界会发生什么:当你登录网易邮箱,并打开另一个站点e时,e站点上的JavaScript就可以跨域读取你的网易邮箱数据,导致隐私泄露。
二、信任问题
安全问题从某种程度上讲就是信任问题。同源策略也是信任的一种表现,默认情况下,不同源则不信任。下面有两个关于信任的场景:
1、场景一
一个Web服务器上有两个网站A和B,黑客入侵目标是A,但是直接入侵A遇到了巨大困难,而入侵B却成功了。由于A与B之间过于信任(在同一个文件系统里,且没有有效的文件权限配置),未能做很好的分离,黑客就可以轻松地攻克网站A。
2、场景二
网站本身是很安全的,由于嵌入了第三方内容(如统计脚本),建立了信任关系,如果第三方的统计脚本被黑客挂马,将导致网站不安全。虽然这样不会导致你的网站直接被入侵,但却危害到了访问你网站的广大用户。
三、前端安全的主要三大类
Web前端安全主要包括跨站脚本(XSS)、跨站请求伪造(CSRF)、界面操作劫持这三大类。
1、XSS
XSS发生在目标网站中目标用户的浏览器层面上,当用户浏览器渲染整个html文档的过程中出现了不被预期的脚本指令并执行时,XSS就会发生。也可以通俗地总结XSS为:想尽一切办法将你的脚本内容在目标网站中目标用户的浏览器上解析执行即可。
场景:
http://www.a.com/xss/reflect.php的代码如下,
<?php echo $_GET['x']; ?>
输入x的值未经任何过滤就直接输出,可以提交:
http://www.a.com/xss/reflect.php?x=<script>alert(1)</script>
服务器端解析时,echo就会完整地输出<script>alert(1)</script>到响应体中,然后浏览器解析执行触发。
2、CSRF
对于CSRF来说,它的请求有两个关键点:跨站点的请求与请求是伪造的。
跨站点请求的来源是其他站点,比如,目标网站的删除文章功能接收到来自恶意网站客户端(JavaScript、Flash、HTML等)发出的删除文章的请求,这个请求就是跨站点的请求,目标网站应该区分请求来源。
如果请求的发出不是用户的意愿,那么这个请求就是伪造的。
场景:
目标网站A:www.a.com 目标网站B:www.b.com
目标网站A上有一个删除文章的功能,通常是用户单击“删除链接”时才会删除文章,这个链接是www.a.com/blog/del?id=1,id代表不同的文章。
CSRF思路,步骤如下:
- 在恶意网站B上编写一个CSRF页面(www.b.com/csrf.htm),考虑用代码<img src=http://www.a.com/blog/del?id=1/>向目标网站A发出一个GET请求的方法。
- 然后欺骗已经登录目标网站A的用户访问www.b.com/csfr.htm页面,攻击发生。
这里攻击过程有三个关键点:跨域发出了一个GET请求、可以无JavaScript参与、请求是身份认证后的。
3、界面操作劫持
界面操作劫持是一种通过在可见输入控件上覆盖一层不可见的框(iframe),使得用户误以为在操作可见控件,而实际上操作行为被不可见框劫持,执行不可见框的恶意支持代码,从而导致用户在不知情的情况下被窃取敏感信息、篡改数据等。
下面是一个点击劫持的简单例子,clickjacking.htm代码如下:
<style> #click{ width:100px; top:20px; left:20px; position:absolute; z-index:1 } #hidden{ height:50px; width:120px; position:absolute; filter:alpha(opacity=50); opacity:0.5; z-index:2 } </style> <input id="click" value="Click me" type="button"/> <iframe id="hidden" src="inner.htm" scrolling="no"></iframe>
嵌入的inner.htm代码如下:
<input style="100px;" value="Login" type="button" onclick="alert('test')"/>