一、同源策略
浏览器基于同源策略保证其安全功能,同源策略限制不同源的“document”或脚本,对当前“document”读取或设置某些属性。
同源策略的本质即是同域名,同端口,同协议
注:对于当前页面,页面存放的JS文件的域不重要,重要的是加载这个JS文件的页面所在的域
eg:a.com加载了b.com的b.js,但是对a.com来说,b.js的源是a.com
<script src=http://b.com/b.js ></script>
在浏览器中,XMLHttpRequest()作为一个浏览器接口,使Javascript可以http通信,但是会受到同源策略的影响,只能访问同源的资源。
而<script>,<img>,<iframe>,<link>等标签可以跨域加载资源,这些带有src属性的标签加载时,是由浏览器发起GET请求,而表单form不受同源策略影响,但是浏览器限制了Javascript的权限,不能读写返回的内容(虽然没有读写功能,但是提交的代码依旧可以被执行)
同源策略引起跨域问题,因为现在前后端基本上处于分离状态,那么从前端到后端或后端到前端都要跨域访问资源。
解决方案:基于信任Javascript无法控制目标域返回的HTTP头,因此如果XMLHttpRequest要跨域访问,需要经过目标域返回的HTTP头来授权是否允许跨域访问(CORS)
浏览器第三方插件也存在类似的控制策略,比如Flash使用白名单策略,判断是否允许当前源的Flash跨域访问目标资源。也要注意第三方插件的安全,有可能插件中植入木马,因为扩展和插件的权限一般都高于Javascript,可以发起跨域网络请求等。
存在方法绕过同源策略:IE8的CSS跨域漏洞
通过@import加载另一个域的文件为CSS文件,渲染进当前页面的DOM,再将文件的内容赋给变量,从而进行读取,不仅绕过同源策略,而且可以对跨域资源读取
<body>
{}body{font-family:
aaaaaaaaa
bbbbbbbbb
</body>
<style>
@import url("http://www.a.com/test.html")
</style>
<script>
setTimeout(function(){
var t = document.body.currentStyle.fontFamily;
alert(t);
}, 2000);
</script>
跨域方案
1、HTML标签
常见标签有:<script>,<img>,<video>,<audio>,<embed>,<frame>,<iframe>,<link rel="stylesheet" href="...">,<applet code="..."></applet>,<object data="..."></object>
每次加载都会由浏览器发送一次GET请求
2、document.domain
相同主域名不同子域名下的页面,在两个页面中设置相同的document.domain。这个方法只适用于不同子域的框架的交互,要使用<iframe>标签
3、Window
window对象表示浏览器一个窗口,name属性可以设置或返回存放窗口名称的一个字符串,而且如果name属性设置好了,即使跳转页面(不关闭页面),也会保留这个属性
因此可以在当前页面iframe加载一个跨域页面,在跨域页面中设置window.name,然后让它进行当前页面跳转,跳转到iframe以外域的页面,就可以在当前页面获取跨域设置的window.name
window.postMessage(message, targetorigin, [transfer])方法定义安全跨域通信,message表示要发送给目标源的信息,必须是字符串类型;targetOrigin指定窗口接收信息,使用*时可以跨域,指定一个单独的URL则不允许跨域
4、local.hash
子框架修改父框架src的hash值,更改hash值页面不会刷新
比如:A域的a.html想和B域的b.html跨域通信,需要借助A域的c.html,a.html通过iframe的local.hash向b.html传值,b.html修改hash后,通过iframe的local.hash向c.html传送,最后c.html只需要和a.html同域通信
5、JSONP
原理:通过添加<script>标签,向服务器请求JSON数据,服务器收到请求后,把数据通过一个callback回调函数返回,但是只支持GET请求
二、恶意网址拦截
很多“挂马”攻击会在正常网页通过<script>,<iframe>等标签加载一个恶意网址,钓鱼网站,诈骗网站也是恶意网站。浏览器一般周期性从服务器端(由安全厂商提供)获取最新黑名单,通过黑名单拦截恶意网站。