浏览器同源策略
同源(Same Origin Policy, SOP)的定义
如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。
下表给出了相对http://store.company.com/dir/page.html
同源检测的示例:
URL | 结果 | 原因 |
---|---|---|
http://store.company.com/dir2/other.html | 成功 | |
http://store.company.com/dir/inner/another.html | 成功 | |
https://store.company.com/secure.html | 失败 | 不同协议 ( https和http ) |
http://store.company.com:81/dir/etc.html | 失败 | 不同端口 ( 81和80) |
http://news.company.com/dir/other.html | 失败 | 不同域名 ( news和store ) |
同源策略允许运行在页面的脚本可以无限制的访问同一个网站(同源)中其他脚本的任何方法和属性。当不同网站页面(非同源)的脚本试图去互相访问的时候,大多数的方法和属性都是被禁止的。
IE例外
当涉及到同源策略时,Internet Explorer
有两个主要的不同点
- 授信范围(Trust Zones):两个相互之间高度互信的域名,如公司域名(corporate domains),不遵守同源策略的限制。
- 端口:
IE
未将端口号加入到同源策略的组成部分之中,因此http://company.com:81/index.html
和http://company.com/index.html
属于同源并且不受任何限制。
源的更改
document.domain = "domain.com";
使用document.domain
来允许子域安全访问其父域时,您需要在父域和子域中设置 document.domain
为相同的值。这是必要的,即使这样做只是将父域设置回其原始值。不这样做可能会导致权限错误。
跨域测试,相同主域名不同子域名下的页面,可以设置document.domain
让它们同域。将a.html
和b.html
设置相同主域,实现跨域。
<!-- a.html -->
<html>
<body>
<script type="text/javascript">
document.domain = 'mark.com:8000';
var ifr = document.createElement('iframe');
ifr.src = 'http://b.mark.com:8000/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function() {
var ifrdoc = ifr.contentDocument || ifr.contentWindow.document;
alert(ifrdoc.getElementsByTagName('html')[0].innerHTML);
};
</script>
</body>
</html>
<!-- b.html -->
<script type="text/javascript">
document.domain = "mark.com:8000";
</script>
跨源
使用CORS
允许跨源访问。
阻止跨源
阻止跨域写操作,只要检测请求中的一个不可测的标记(CSRF token)即可,这个标记被称为(CSRF)标记。必须使用这个标记来阻止页面的跨站读操作。
阻止资源的跨站读取,需要保证该资源是不可嵌入的。阻止嵌入行为是必须的,因为嵌入资源通常向其暴露信息。
阻止跨站嵌入,需要确保你的资源不能是以上列出的可嵌入资源格式。多数情况下浏览器都不会遵守
Conten-Type
消息头。例如,如果在HTML文档中指定<script>
标记,则浏览器将尝试将HTML
解析为JavaScript
。 当资源不是网站的入口点时,还可以使用CSRF
令牌来防止嵌入。
参考:
https://www.anquanke.com/post/id/86078
https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy