同源策略(SOP)和跨域访问

来源:互联网 发布:人体工程学鼠标 知乎 编辑:程序博客网 时间:2024/05/22 08:25

参考:
http://web.jobbole.com/83864/
http://louiszhai.github.io/2016/01/11/cross-domain/
https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
http://zhihu.com/question/25427931/answer/30848852
浏览器同源政策及其规避方法

所谓同源就是要求, 域名, 协议, 端口相同. 非同源的脚本不能访问或者操作其他域的页面对象(如DOM等). 作为著名的安全策略, 虽然它只是一个规范, 并不强制要求, 但现在所有支持 javaScript 的浏览器都会使用这个策略. 以至于该策略成为浏览器最核心最基本的安全功能, 如果缺少了同源策略, web的安全将无从谈起.

iframe限制

可以访问同域资源, 可读写;
访问跨域页面时, 只读.

Ajax限制

Ajax 的限制比 iframe 限制更严.
同域资源可读写;
跨域请求会直接被浏览器拦截.(chrome下跨域请求不会发起, 其他浏览器一般是可发送跨域请求, 但响应被浏览器拦截)

Script限制

script并无跨域限制, 这是因为script标签引入的文件不能够被客户端的 js 获取到, 不会影响到原页面的安全, 因此script标签引入的文件没必要遵循浏览器的同源策略. 相反, ajax 加载的文件内容可被客户端 js 获取到, 引入的文件内容可能会泄漏或者影响原页面安全, 故, ajax必须遵循同源策略.

这里需要澄清一个概念, 所谓的域, 跟 js 等资源的存放服务器没有关系, 比如你到 baidu.com 使用 script 标签请求了 google.com 下的js, 那么该 js 所在域是 baidu.com, 而不是 google.com. 换言之, 它能操作baidu.com的页面对象, 却不能操作google.com的页面对象.

这里要与referer区分开,referer是浏览器的行为,所有浏览器发出的请求都不会存在安全风险。而由网页加载的脚本发起请求则会不可控,甚至可以截获用户数据传输到其他站点。referer方式拉取其他网站的数据也是跨域,但是这个是由浏览器请求整个资源,资源请求到后,客户端的脚本并不能操纵这份数据,只能用来呈现。

源的更改

页面可能会更改其自己的来源,但有一些限制。脚本可以将 document.domain 的值设置为其当前域或其当前域的超级域。如果将其设置为其当前域的超级域,则较短的域将用于后续原始检查。例如,假设文档中的一个脚本在 http://store.company.com/dir/other.html 执行以下语句:

document.domain = "company.com";

这条语句执行之后,页面将会成功地通过对 http://company.com/dir/page.html 的同源检测。而同理,company.com 不能设置 document.domain 为 othercompany.com.
这里写图片描述

以下是可能嵌入跨源的资源的一些示例:

<script src="..."></script>标签嵌入跨域脚本。语法错误信息只能在同源脚本中捕捉到。
<link rel="stylesheet" href="...">标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的Content-Type消息头。不同浏览器有不同的限制: IE, Firefox, Chrome, Safari (跳至CVE-2010-0051)部分 和 Opera。
<img>嵌入图片。支持的图片格式包括PNG,JPEG,GIF,BMP,SVG,…
<video><audio>嵌入多媒体资源。
<object>, <embed><applet>的插件。
@font-face引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。
<frame><iframe>载入的任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。

如何阻止跨源访问

  • 阻止跨域写操作,只要检测请求中的一个不可测的标记(CSRF token)即可,这个标记被称为Cross-Site Request Forgery (CSRF) 标记。必须使用这个标记来阻止页面的跨站读操作。
  • 阻止资源的跨站读取,需要保证该资源是不可嵌入的。阻止嵌入行为是必须的,因为嵌入资源通常向其暴露信息。
  • 阻止跨站嵌入,确保你得资源不能是以上列出的可嵌入资源格式。多数情况下浏览器都不会遵守Conten-Type消息头。例如,如果你在<script>标签中嵌入HTML文档,浏览器仍将HTML解析为Javascript。

最严重的跨域——跨特权域

所有跨域行为中最严重的莫过于跨特权域。在客户端中,有一些域的权限比较高,例如file://这个协议域,ie中允许调用ActiveX执行cmd,Webkit中可以读取磁盘上的文件。另外还有客户端自定义的特权域,例如Chrome的chrome://downloads/域,有着执行exe的权限。这事儿太严重了,这不仅意味着任意一个网站都可以浏览/修改你的浏览器配置,而且可以不经你同意上传文件,甚至会在你的电脑上安装木马。跨特权域最经典的例子莫过于黑哥去年讲的 《跨过的那些客户端》。

0 0
原创粉丝点击