瞌睡龙 · 2013/06/19 19:09

同源策略


同源策略的文档模型

同源策略(Same Origin policy,SOP),也称为单源策略(Single Origin policy),它是一种用于Web浏览器编程语言(如JavaScript和Ajax)的安全措施,以保护信息的保密性和完整性。

同源策略能阻止网站脚本访问其他站点使用的脚本,同时也阻止它与其他站点脚本交互。

原始资源 要访问的资源 非IE浏览器 IE浏览器
http://example.com/a/ http://example.com/b/ 可以访问 可以访问
http://example.com/ http://www.example.com/ 主机不匹配 主机不匹配
http://example.com/a/ https://example.com/a/ 协议不匹配 协议不匹配
http://example.com:81/ http://example.com/ 端口不匹配 可以访问

同源策略一开始是为了管理DOM之间的访问,后来逐渐扩展到Javascript对象,但并非是全部。

例如非同源的脚本之间可以调用location.assign()和location.replace()。

同源策略在提高了安全性,但同时也降低了灵活性。

例如很难将login.example.com与payments.example.com两个域之间的数据可以方便的传送。

介绍两种解决方式:document.domain和postMessage()。

javascript允许子域之间使用顶级域名。

例如login.example.com和payments.example.com都可以进行如下设置:

document.domain="example.com"

设置这个属性之后,子域之间可以方便的通信,需注意的是协议和端口号必须相同。

原始资源 访问的资源 结果
URL document.domain URL document.domain
http://www.example.com/ example.com http://payments.example.com/ example.com 可以访问
http://www.example.com/ example.com https://payments.example.com/ example.com 协议不匹配
http://payments.example.com example.com http://example.com/ (不设置) 拒绝访问
http://www.example.com/ (不设置) http://www.example.com example.com 拒绝访问

postMessage()是HTML5的一个API接口,由于比较新,所以在IE6和IE7中不支持。 1 向另外一个iframe发送消息:

var message = 'Hello' + (new Date().getTime());window.parent.frames[1].postMessage(message, '*');

iframe1.html需要向iframe2.html发送消息,也就是第二个iframe,所以是window.parent.frames[1]。

如果是向父页面发送消息就是window.parent。

postMessage这个函数接收二个参数,缺一不可,第一个参数即你要发送的数据。

第二个参数是非常重要,主要是出于安全的考虑,一般填写允许通信的域名。

这里为了简化,所以使用’*',即不对访问的域进行判断。

2 另外一个iframe监听消息事件:

iframe2.html中写个监听message事件,当有消息传到iframe2.html时就会触发这个事件。
var onmessage = function(e) {var data = e.data,p = document.createElement('p');p.innerHTML = data;document.getElementById('display').appendChild(p);
};//监听postMessage消息事件
if (typeof window.addEventListener != 'undefined') {window.addEventListener('message', onmessage, false);} else if (typeof window.attachEvent != 'undefined') {window.attachEvent('onmessage', onmessage);
}

如果你有加域名限,比如下面的代码:

window.parent.frames[1].postMessage(message, 'http://www.test.com');

就要在onmessage中追加个判断:

if(event.origin !== 'http://www.test.com') return;

XMLHttpRequest的同源策略

一个简单的同步XMLHttpRequest请求:

var x = new XMLHttpRequest();
x.open("POST", "/some_script.cgi", false);
x.setRequestHeader("X-Random-Header", "Hi mom!");
x.send("...POST payload here...");
alert(x.responseText);

XMLHttpRequest请求严格遵守同源策略,非同源不可以请求。

这个API也做过很多测试与改进,下面列出之前的测试方法:

var x = new XMLHttpRequest();
x.open("POST", "http://www.example.com/", false);
// 定义发送内容长度为7
x.setRequestHeader("Content-Length", "7");
// 构造的http请求。
x.send(
"Gotcha!\n" +
"GET /evil_response.html HTTP/1.1\n" +
"Host: www.bunnyoutlet.com\n\n"
);

现在的浏览器都不存在上面的隐患,包括基本都禁用了TRACE方法,防止httponly的cookie泄漏问题等。

Web Storage的同源策略

Web Storage是由Mozilla的工程师在Firefox1.5中加入的,并且加入了HTML5中,现在的浏览器都支持,除了IE6与IE7。

JavaScript可以通过localStorage与sessionStorage对Web Storage进行创建,检索和删除:

localStorage.setItem("message", "Hi mom!");
alert(localStorage.getItem("message"));
localstorage.removeItem("message");

localStorage对象可以长时间保存,并且遵守同源策略。

但是在IE8中localStorage会把域名相同但是协议分别为HTTP和HTTPS的内容放在一起,IE9中已修改。

在Firefox中,localStorage没有问题,但是sessionStorage也是会把域名相同的HTTP与HTTPS放在一起。

Cookie的安全策略

设置Cookie总结

在foo.example.com设置cookie,domain设置为:

最终cookie的范围

非IE浏览器

IE浏览器

设置为空

foo.example.com(一个域)

*.foo.example.com

bar.foo.example.com

cookie设置失败,设置的域是当前域的一个子域

foo.example.com

*.foo.example.com

baz.example.com

cookie设置失败,域名不匹配

example.com

*.example.com

ample.com

cookie设置失败,域名不匹配

.com

设置失败,域名太广,存在安全风险。

Cookie中的path参数可以设定指定目录的cookie。

例如设定domain为example.com,path为/some/path/ 在访问下面url的时候会带上设定的cookie:

http://foo.example.com/some/path/subdirectory/hello_world.txt

存在一定的安全风险,因为path的设定没有考虑到同源策略。

httponly属性可以防止通过document.cookie的API访问设定的cookie。

secure属性设定后只有在通过https传输时才会带上设定的cookie,可以防止中间人攻击。

Adobe Flash

AllowScriptAccess参数:用来控制flash通过ExternallInterface.call()函数调用javascript的时的限制。

有三个值:always,never和sameorigin,最后一个值只允许同域的JavaScript操作(08年之前默认为always,现在默认为sameorigin)。

AllowNetworking参数:用来控制flash与外部的网络通讯。

可选的值为:all(允许使用所有的网络通讯,默认值),internal(flash不能与浏览器通讯如navigateToURL,但是可以调用其他的API),none(禁止任何的网络通讯)

本地文件

由于本地文件都是通过file:协议进行访问的,由于不存在host,所以无法遵循同源策略。

所以本地保存的一个HTML文件,在浏览器中通过file:协议访问后,可以通过XMLHttpRequest或DOM对本地其他文件进行操作。

与此同时,也可以对互联网的其他资源做同样的操作。各浏览器厂商意识到这个问题,并努力做了修改:

测试代码:

1.html(1.txt随机写一些字符串即可)

<script>
function createXHR(){return window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");
}
function getlocal(url){xmlHttp = createXHR();xmlHttp.open("GET",url,false);xmlHttp.send();result = xmlHttp.responseText;return result;
}
function main(){url = "file://路径/1.txt";alert(url);result = getlocal(url);alert(result);
}
main();
</script>

结论:

1 Chrome浏览器(使用WebKit内核的浏览器)
完全禁止跨文档的XMLHttpRequest和DOM操作,并禁止了document.cookie和<meta http-equiv="Set-Cookie" ...>的操作。
2 Firefox
允许访问同目录与子目录里的文件。也可通过document.cookie与<meta http- equiv="Set-Cookie" ...>设定cookie,file:协议下cookie共享,storage也是。
3 IE7及以上
允许本地文件之间的访问,但是在执行JavaScript之前会有一个提示,用户点击通过之后可以执行,cookie域Firefox类似,但是file:协议下不支持storage。
4 IE6
允许本地文件的访问,同时也允许对http协议的访问,cookie也是一样。

伪URL的域


一些web应用用到了伪URL例如about:,javascript:,和data:来创建HTML文档。

这种方法是为了不需要再与服务器通信,可以节约时间更快的响应,但是也带进了很多安全隐患。

about:blank

about协议在现在的浏览器中有很多用途,但是其中大部分不是为了获取正常的页面。

about:blank这个URL可以用来被创建DOM对象,例如:

<iframe src="about:blank" name="test"></iframe>
<script>
frames["test"].document.body.innerHTML = "<h1>Hi!</h1>";
</script>

在浏览器中,创建一个about:blank页面,它继承的域为创建它的页面的域。

例如,点击一个链接,提交一个表单,创建一个新窗口,但是当用户手动输入about:或者书签中打开的话,他的域是一个特殊的域,任何其他的页面都不可以访问。

data:协议

data:协议是设计用来放置小数据的,例如图标之类的,可以减少http请求数量,例如:

<img src="https://img-blog.csdnimg.cn/2022010615445939419.jpeg">

用以下代码研究域的问题:

<iframe src="data:text/html;charset=utf-8,<script>alert(document.domain)</script>" >

在Chrome与Safari中,所有的data:都会赋予一个单独的,不可获取的域,而不是从父域中继承的。

Firefox与Opera中,域是继承于当前页面。

IE8之前的版本不支持data:协议。

javascript:和vbscript:

javascript:协议允许后面执行javascript代码,并且继承了调用的当前域。

有些情况会对后面的内容处理两次,如果代码正确的话,会把后面的代码当成html解析,覆盖掉原来的html代码:

<iframe src='javascript:"<b>2 + 2 = " + (2+2) + "</b>"'>
</iframe>

Browser Security-同源策略、伪URL的域相关推荐

  1. 浏览器同源策略,及跨域解决方案

    原文链接:浏览器同源策略,及跨域解决方案 一.Origin(源) 源由下面三个部分组成: 域名 端口 协议 两个 URL ,只有这三个都相同的情况下,才可以称为同源. 下来就以 "www.e ...

  2. 实现跨域访问---同源策略 、常见跨域方法

    实现跨域访问 同源策略 为了保证用户数据安全 防止恶意网站窃取数据 同源策略 三个行为限制: ​ Cookie.LocalStorage.indexDB无法读取 ​ DOM无法获取 ​ AJAX请求不 ...

  3. 跨域获取后台数据undefined_同源策略amp;JSONP跨域

    同源策略&JSONP跨域 同源策略 对于同源的定义,MDN给出了这样的解释:如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的源. 如何确定两个页面是否同源,只要比较两个 ...

  4. 什么是同源策略?解决跨域的三种方法?

    1.同源策略 同源策略是一种约定和规范好的安全策略,是浏览器最核心最基本的安全保障.同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据. 满足的条件: (1)协议要相同:HTTP.HTT ...

  5. 什么是同源策略及解决跨域的三种方式

    同源策略 1.1.1 所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个 ip 地址,也非同源.同源策略/SOP(Same origin policy)是一种约 ...

  6. 新蜂商城(newbee-mall-api)部分接口实验,跨域处理(同源策略,跨域访问,CORS),系统安全问题(Session,Cookie,Token,OAuth)(软件工程综合实践课程第十三周)

    文章目录 一.要求 二.知识总结 跨域处理 1.同源策略 1.1 浏览器的同源策略 1.2 跨域请求实验 2 跨域访问 2.1 添加响应头来处理跨域 2.1.1 CORS 跨域资源共享 2.1.2 设 ...

  7. 同源策略——浏览器安全卫士

    对于软件开发人员来说,理解同源策略.能够非常好地攻克了一个痛点. 不同域名下的资源读写 ! 古代的楚河汉界明白地规定了两方的活动界限.假设没有这些界限,天下必将大乱.相同,在我们的浏览器,也有着一些界 ...

  8. 同源策略(拓展) HTML DOM、API等介绍

    01 两种类型信息泄露 个人信息泄露.黑客可以针对个人的习惯生成有规则的字典,然后通过去社工网站寻找你曾经注册过的网站,然后对这些你注册过的网站进行逐一的暴力破解. 世界上没有爆破不出的密码,只看你的 ...

  9. 禁用浏览器同源策略的方法

    1.引言 前端和后台联调的时候总会涉及到跨域,平时我们跨域主要的方法是通过CORS进行跨域,但是通过CORS进行跨域有的时候会涉及到数据安全的问题,这时候我们可以通过禁用本地浏览器的同源策略来进行跨域 ...

最新文章

  1. Python未来的发展趋势怎么样
  2. js如何生成一个对象,并转化为json字符串
  3. 关于Java中next() nextLine()的区别
  4. oracledb_npm包的使用
  5. 天堂Lineage(單機版)從零開始架設教學 Installing Lineage 3.52 Server - On Windows
  6. 【转】SharePoint 术语表
  7. 阿里云:助力数字经济新基建,打造物联网安全基石
  8. python中的是干什么用的_python主要用来干什么?
  9. rust开发环境_Rust 环境搭建
  10. sqlserver2008安装报错 “Previous releases of Microsoft Visual Studio 2008″ failed.
  11. java接口参数类型为枚举_Spring MVC处理参数中的枚举类型通用实现方法
  12. java泛型实验报告,java实验报告异常集合类和泛型
  13. 使用百度富文本编辑器UEditor碰到的问题
  14. 一大波Java来袭(四)String类、StringBuilder类、StringBuffer类对照
  15. 关于SVN提交注释的问题
  16. 孙鑫VC学习笔记:第十八讲 ActiveX 控件
  17. MySQL查询时当offset较大时查询效率低
  18. mysql stored_mysql stored routine (存储例程) 中 definer 的作用 和实例
  19. 共轭梯度法(CG)详解
  20. ADS系列之SIPI仿真笔记:ADS多种版本的安装、卸载重装(一)

热门文章

  1. 利用ATL创建com组件和如何在程序中使用组件的接口函数和设置接口的属性
  2. 我的 Windows Vista 上安装的工具
  3. Linux-Shell 快捷键
  4. python取列表中最接近某值的元素及索引
  5. matlab工作路径
  6. python目录操作shutil
  7. Java控制语句——switch语句
  8. 解决启动httpd报: apr_sockaddr_info_get() failed for错误
  9. 调试linux内核前的多虚拟机网络配置(图文教程)
  10. CSDN中对Web自定义控件的讨论帖