浏览器安全之同源策略
同源策略
同源策略是一种约定,它是浏览器最核心也是最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能会受到影响.可以说Web是构建在同源策略的基础之上的,浏览器只是针对同源策略的一种实现.
浏览器的同源策略,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属性.影响"源"的因素有:协议,域名,端口号.
需要注意的是,对于当前页面来说,页面存放JavaScript文件的域并不重要,重要的是加载JavaScript页面所在的域是什么.
在浏览器中,<script>,<img>,<ifram>,<link>等标签都可以跨域加载资源,而不受同源策略的限制.这些带"src"属性的标签每次加载时,实际上是由浏览器发起了一次GET请求.不同于XMLHttpRequest的是,通过src属性加载的资源,浏览器限制了JavaScript的权限,使其不能读写返回的内容.
XMLHttpRequest受到同源策略的约束,不能跨域访问资源.如果XMLHttpRequest能够跨域访问资源,则可能会导致一些敏感数据泄露,比如CSRF的token,从而导致发生安全问题.
但是互联网是开放的,随着业务的发展,跨域请求的需求越来越迫切,因此W3C委员会制定了XMLHttpRequest跨域访问标准.它需要通过目标域返回的HTTP头来授权是否允许跨域访问,因为HTTP头对于JavaScript来说一般是无法控制的.
对于浏览器来说,除了DOM,Cookie,XMLHttpRequest会受到同源策略的限制外,浏览器加载的一些第三方插件也有各自的同源策略.最常见的一些插件如Flash,Java Applet等都有自己的控制策略.以Flash为例,它主要通过目标网站提供的crossdomain.xml文件判断是否允许当前
"源"的Flash跨域访问目标资源.
然而浏览器的同源策略也并非坚不可摧,由于实现上的一些问题,一些浏览器的同源策略也曾经被多次绕过.比如下面这个IE8的CSS跨域漏洞.
www.a.com/test.html
<body> {} body {font-family: aaaaaaaaaaaa bbbbbbbbbbb </body>
www.b.com/test2.html
<style> @import url("http://www.a.com/test.html") </style> <script> setTimeout(function() { var t = document.body.currentStyle.fontFamily; alert(t); },2000);
在"www.b.com/test2.html"汇总通过@import加载了"http://www.a.com/test.html"为CSS文件,渲染进入当前页面DOM,同时通过"document.body.currentStyle.fontFamily"访问内容.问题发生在IE的CSS PARSE的过程中,IE将fontFamily后面的内容当做了value,从而可以读取"www.a.com/test.html"的页面内容.