摘要:可以说同源策略在安全中扮演着及其重要的角色。我把这个领域的东西写成了一个系列,以后还会继续完善下去安全一同源策略与跨域安全二攻击安全三攻击
之所以要将同源策略与跨域写在一起,是因为存在浏览器的同源策略,才会存在跨域问题何为同源策略
同源策略是浏览器实现的一种安全策略,它限制了不同源之间的文档和脚本交互的权限。只有同一个源的脚本才会具有操作dom、读写cookie、session 、ajax等敏感操作的权限。可以说同源策略在web安全中扮演着及其重要的角色。所谓同源简单来说即是两个页面必须具有相同的协议、端口还有域名。
以http://www.site.com/index.html为例,举个小栗子:
url | 是否跨域 | 原因 |
http://www.site.com/other/ind... | 否 | |
http://child.site.com/index.html | 是 | origin 不一样(www与child) |
http://www.site.com:8090/index.html | 是 | 端口 不一样(80与8090) |
https://www.site.com/index.html | 是 | 协议 不一样(http与https) |
不得不调侃一下,在兼容性方面IE似乎永远都难以跟上别的浏览器发展的步伐,永远都是一个例外。
授信范围(Trust Zones):两个相互之间高度互信的域名,如公司域名(corporate domains),不遵守同源策略的限制。
端口:IE未将端口号加入到同源策略的组成部分之中,因此 http://www.size.com:81/index.html 和http://www.size.com:8090/index.html 属于同源并且不受任何限制。
虽然同源策略限制了跨域文档脚本的操作能力,但明确允许部分资源性的标签是可以加载跨域资源的,如,。部分具有跨域能力的标签如下,来源于MDN:
标签嵌入跨域脚本。语法错误信息只能在同源脚本中捕捉到。
标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的Content-Type消息头。
嵌入图片。
@font-face引入的字体。
和
跨域的方法在浏览器同源策略的安全限制下,跨域的需求仍然是有的。这种需求可以分为正当的和不正当的。具体来说不正当的就是,第三方恶意网站利用同源策略的一些漏洞,对目标网站进行一些不允许的操作,这种操作我们称之为跨域攻击。具体可以参照我的另外几篇博客:
CSRF攻击(跨域伪请求)
XSS攻击(跨域脚本攻击)
正当的跨域请求可以是: 一些大集团下面的几个子域名之间的跨域交互,也可以是合作网站之间的跨域交互等等,总之就是被允许的。下面来具体说说实现这种正当跨域的几种方法:
写在前面: 所有的跨域方法都会带来安全性的问题,一旦恶意网站能够成功在目标网站运行脚本或者具有操作的能力,他们也就具有了目标网站的跨域能力。document.domain
脚本可以将 document.domain 的值设置为其当前域或其当前域的超级域。
这种方法的优点就是:简单,只要在前端js中设置就好了
弊端:只适合用于子域与父域之间还有子域之间的跨域
实现起来异常简单,主要是通过在服务器设置HttpHeader,客户端检查自己的域是否在允许列表中,决定是否处理响应。详情请参考CORS MDN, 利用CORS实现跨域请求
服务器端可以在HTTP的响应头中加入(页面层次的控制模式):
Access-Control-Allow-Origin: example.com
Access-Control-Request-Method: GET, POST
Access-Control-Allow-Headers: Content-Type, Authorization, Accept, Range, Origin
Access-Control-Expose-Headers: Content-Range
Access-Control-Max-Age: 3600
多个域名之间用逗号分隔,表示对所示域名提供跨域访问权限。"*"表示允许所有域名的跨域访问。
此方法的优点:简单快捷,配置简单,基本可以解决任何域的跨域问题
弊端:仅适用与客户端与跨域服务器的交互;另外具有浏览器的兼容性问题,不兼容IE7以及以下。
在IE8——IE9 中要使用xhr = new XDomainRequest();来替代xhr = new XMLHttpRequest();
在以前,当尝试使用 window.onerror 去记录跨域脚本的错误时,只会返回 Script error, 没法获取到具体的报错信息。这种情况在html5中得到了改观,html新加了一个crossorigin属性,允许捕获跨域脚本的详细错误信息,但是有两个条件:
跨域脚本的服务器必须通过 Access-Controll-Allow-Origin 头信息允许当前域名可以获取错误信息
当前域名的 script 标签也必须指明 src 属性指定的地址是支持跨域的地址,也就是要添加crossorigin 属性
crossorigin 具有两个值:
anonymous: 请求不带 credentials flag .
use-credentials: 请求携带 credentials flag .
credentials flag 也就是常说的cookies, client-side SSL certificates
window.postMessagepostMessage是HTML5新的语法特性,可以让跨域的脚本之间进行交互,主要分为消息的发送端和消息的接收端。
发送端:
otherWindow是其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。
otherWindow.postMessage( message, // 要发送到其他窗体的消息,可以传送任何数据对象 targetOrigin, // 消息要发送到的域,由完整的协议、地址、端口组成 [transfer] // 这是一个可选的抽象接口 );
otherWindow.postMessage() 方法被调用时,会在所有页面脚本执行完毕之后(e.g., 在该方法之后设置的事件、之前设置的timeout 事件,etc.)向目标窗口派发一个 MessageEvent 消息。
接收端:
window.addEventListener("message", receiveMessage, false); function receiveMessage(event) { // For Chrome, the origin property is in the event.originalEvent // object. var origin = event.origin || event.originalEvent.origin; if (origin !== "http://example.org:8080") return; // ... }
message 事件,包含4个参数
message 属性表示该message 的类型;
data 属性为 window.postMessage 的第一个参数即message;
— origin 调用window.postMessage() URI
— source 调用window.postMessage() 的窗口对象
兼容性:在 Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3)之前, 参数 message 必须是一个字符串。而IE10下面也有奇怪的问题
优点:适合同一个浏览器两个跨域页面之间的脚本交互
弊端:只能从窗口的引用(也就是window.open或者window.frames[0].contentWindow)发送消息到目标窗口,适用的范围有限
jsonp 是比较古老的跨域方法,也是比较常用的跨域
具体来说,它的实现如下:
function jsonp(url,data,callbackName) { var script = document.createElement("script"); var src = url+ "?"+ data+ "calback="+callbackName; script.src = src; document.head.appendChild(script); } function callbackName(data){ // data from server; }JSONP的坑
因为在jquery中JSONP使用的是ajax的封装接口,很多人它会是ajax的一种技术,实际上它是利用标签天生具有跨域能力的一种技术,所以很多人在jquery中使用JSONP时都会踩坑。
坑一:同步,很多人会想当然地使用ajax的同步参数async来实现同步。实际上jsonp只有异步,因为script是异步加载的
坑二:错误回调,在使用jquery的过程,很多人会使用ajax的error和fail接口,来捕获跨域的异常返回。ajax的错误接口只能捕获请求超时、终止、json解析错误等正常的错误,但是对于网络不通、服务器异常,jquery是选择静默地失败的。
那怎么捕获jsonp的异常呢?
实际上标签在遇到这些错误时会触发error事件。所以上面的代码我们可以稍微改一下,增加一个捕获异常的回调
function jsonp(url,data,callbackName,errorbackName) { var script = document.createElement("script"); var src = url+ "?"+ data+ "calback="+callbackName; script.src = src; script.onerror = errorbackName; document.head.appendChild(script); } function callbackName(data){ // data from server; }
另外在jquery中的处理主要有两种方法,参考 jQuery使用JSONP时的错误处理
手动暴露jsonp 的错误接口
var head = document.head || $("head")[0] || document.documentElement; // code from jquery var script = $(head).find("script")[0]; script.onerror(function(evt) { alert("error"); });
使用jsonp的拓展库
针对jquery处理jsonp的坑,早有大神封装好插件,直接引用就可以了,方便快捷省心。传送门
【相关】
web安全,是一个很重要的技能,也是一个领域的知识。我把这个领域的东西写成了一个系列,以后还会继续完善下去:
web安全一:同源策略与跨域
web安全二:CSRF 攻击
web安全三:XSS 攻击
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/93005.html
摘要:由于浏览器的同源策略导致无法直接通过拿到后台数据。目前,如果非同源,共有三种行为受到限制。此处应有掌声参考关于跨域资源共享和浏览器的同源策略限制的具体讲解。 工作中,经常会遇到需要跨域请求数据的情况。由于浏览器的同源策略,导致无法直接通过ajax拿到后台数据。解决这个问题的方式之一就是JSONP。还有一种方式更高效简单——跨域资源共享(Cross-origin Resource Sha...
摘要:扯了这么多,自然不是为了吹水,而是要为了引出前端开发的一个重要的知识点同源策略什么是同源策略出于保护用户信息安全的目的,现在的浏览器都会实施同源策略这个政策,所谓同源策略指的是不同源的客户端脚本在没有明确授权情况下,不允许读写对方的资源。 导语你家的小孩带了他的朋友来你们的家里玩,你家的小孩如果要在自家屋里拿玩具玩、拿东西吃你自然是不会阻止,但是如果你家小孩的朋友人品不行,乱拿东西吃、...
摘要:扯了这么多,自然不是为了吹水,而是要为了引出前端开发的一个重要的知识点同源策略什么是同源策略出于保护用户信息安全的目的,现在的浏览器都会实施同源策略这个政策,所谓同源策略指的是不同源的客户端脚本在没有明确授权情况下,不允许读写对方的资源。 导语你家的小孩带了他的朋友来你们的家里玩,你家的小孩如果要在自家屋里拿玩具玩、拿东西吃你自然是不会阻止,但是如果你家小孩的朋友人品不行,乱拿东西吃、...
摘要:方案浏览器设置一级域名。场景完全不同源的网站,需要窗口通信方案父子窗口互相写互相监听子窗口写后跳回同域父窗口读浏览器跨文档通信场景请求非同源地址方案架设服务器代理参考资料浏览器同源政策及其规避方法阮一峰前端常见跨域解决方案全跨域几种方式 同源 概念:协议,域名,端口 相同。目的:保证用户信息的安全,防止恶意的网站窃取数据。限制的行为: Cookie、LocalStorage 和 In...
摘要:方案浏览器设置一级域名。场景完全不同源的网站,需要窗口通信方案父子窗口互相写互相监听子窗口写后跳回同域父窗口读浏览器跨文档通信场景请求非同源地址方案架设服务器代理参考资料浏览器同源政策及其规避方法阮一峰前端常见跨域解决方案全跨域几种方式 同源 概念:协议,域名,端口 相同。目的:保证用户信息的安全,防止恶意的网站窃取数据。限制的行为: Cookie、LocalStorage 和 In...
阅读 682·2021-11-23 09:51
阅读 3274·2019-08-30 15:54
阅读 439·2019-08-30 15:52
阅读 3107·2019-08-30 13:58
阅读 2912·2019-08-30 13:53
阅读 2683·2019-08-29 14:18
阅读 2406·2019-08-27 10:54
阅读 2363·2019-08-26 18:09