浏览器的同源策略

如今的WEB标准纷繁复杂,在浏览稍大一些的网站时,细心的人会发现网页上呈现的内容并不仅限于网站自身提供的内容,而是来自一堆五花八门的网站的内容的集合。但有谁会想到同源策略在保护着网民们的安全呢?

了解同源策略是十分有必要的,要深入掌握XSS / CSRF等WEB安全漏洞,不了解同源策略就如同盲人摸象一般,无法说出全貌,更无法应用其进行打击。另外,无论是网银盗号,还是隐私泄露,理解了同源策略,就有助于理解自己面临着什么样的威胁。

0x00 什么是源和同源策略

源就是主机,协议,端口名的一个三元组。

同源策略(Same Origin Policy, SOP)是Web应用程序的一种安全模型,它控制了网页中DOM之间的访问。重要的事情说三遍,它只是个模型,而不是标准(哪怕标准在实现的时候也会千差万别)。同源策略被广泛地应用在处理WEB内容的各种客户端上,比如各大浏览器,微软的Silverlight,Adobe的Flash/Acrobat等等。SOP影响范围包括:普通的HTTP请求、XMLHttpRequest、XSLT、XBL。

0x01 如何判断同源

定义:如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的源。我们也可以把它称为“协议/主机/端口 tuple”,或简单地叫做“tuple". ("tuple" ,“元”,是指一些事物组合在一起形成一个整体,比如(1,2)叫二元,(1,2,3)叫三元)

下表给出了相对http://store.company.com/dir/page.html同源检测的示例:

0x02 同源策略究竟限制了什么?

首先,我们要明确同源策略只作用在实现了同源策略的WEB客户端上。 虽然笔者不常用百度,但是我们来看一个具有误导性的结论:百度词条对于同源策略的解释说“只有和目标同源的脚本才会被执行”,这是不对的,同源策略没有禁止脚本的执行,而是禁止读取HTTP回复。 更正了这个概念之后,我们会发现,SOP其实在防止CSRF上作用非常有限,CSRF的请求往往在发送出去的那一瞬间就已经达到了攻击的目的,比如发送了一段敏感数据,或请求了一个具体的功能,是否能读取回复并不那么重要(唯一的作用是可以防止CSRF请求读取异源的授权Token)。 另外,一般静态资源通常不受同源策略限制,如js/css/jpg/png等。

0x03 跨源的网络访问

为什么要起这么拗口的名字:网络访问?因为WEB上资源访问的多样性,不能简单的称之为网络请求。大体看来我们有三种类型:

跨域写,通常被允许,例如链接,重定向和表单提交,一些不常见的HTTP请求方法例如PUT,DELETE等需要先发送预请求(preflight),例如发送OPTIONS来查询可用的方法。

跨域嵌入,通常被允许。

跨域读,通常被禁止,然而,我们可以用其他方法达到读取的效果。

一个经久不衰的BUG

早在2011年,一个用户在Mozilla的Bug追踪系统中就提交了一个issue,声称他可以判定某个网站的访客是否登录了gmail,facebook等等。

嵌入iframe来获取一个访问网站的用户是否登陆了gmail:

<img style="display:none;"  
 onload="logged_in_to_gmail()"
 onerror="not_logged_in_to_gmail()"
 src="https://mail.google.com/mail/photos/img/photos/public/AIbEiAIAAABDCKa_hYq24u2WUyILdmNhcmRfcGhvdG8qKDI1ODFkOGViM2I5ZjUwZmZlYjE3MzQ2YmQyMjAzMjFlZTU3NjEzOTYwAZwSCm_MMUDjh599IgoA2muEmEZD"
/>

src的代码试图访问一张gmail中攻击者上传的图片,如果用户没有登陆gmail,就无法成功加载。从而达到判断用户是否登陆gmail的效果。这种方法可以推广到任何对不应跨源访问的资源没有正确设置同源策略的网站。

0x04 谈谈攻击

作为一个抽象的WEB安全模型,每个处理WEB内容的客户端实现的都不完全一样,这就带来了许多差异点,而差异点的存在就带来了漏洞,正所谓“千里之堤,溃于蚁穴”。

对URI的解析

IP是URI的重要组成部分,如果留心了RFC的人就会知道,IP不止有一种格式。下面的标注形式其实都代表了同一个IP:216.58.209.68,大家可以在浏览器里实验。

216.58.53572
0xD8.072.53572
3627733316
0330.3854660

当某些浏览器对URI的解释存在漏洞的时候,就可以构造出有趣的攻击链来绕过SOP。 比如CVE-2015-7188火狐浏览器SOP绕过中。攻击者构造了特殊的URL,并在攻击者自己控制的来自37.187.18.85的网页中发起跨域请求

http://37.187.18.85BuFF20translate.google.com/fx_sop_bypass/FlashTest.swf?url=http://translate.google.com/manager/website/

先通过B让Firefox认为这个请求是请求37.187.18.85本身的内容,再通过类似@字符的Unicode字符@(uFF20)让浏览器认为@之前的字符都是translate.google.com的账号和密码,从而返回translate.google.com的网页内容,实现绕过SOP。

设计缺陷导致SOP绕过

在Java6,7中,如果两个域名解析到相同的IP,则会认为他们同源。假设我们有attacker.com和victim.com,两者都共享主机123.123.123.123。攻击者attacker.com可以在自己控制的域名下上传一个jar文件来访问victim.com的内容。

访问本地文件的同源策略

不同的浏览器使用不同的浏览器引擎,而不同的引擎对于同源策略的处理也并非完全一致。例如,Firefox使用Gecko浏览器引擎,在古老的Gecko1.8版(Firefox3)之前,任意两个file://的URI都被认为是同源的,意思就是,任意本地HTML文件将有权限访问本地计算机上任意其他文件。如今的Gecko版本中,一个HTML文档只能访问其所在文件夹下的其他文件。 对于跨越窗口的DOM访问,每个文件被当作一个单独的源,除了一种情况:当一个文件被另一个文件可以用同源策略访问时,视为相同的源。

<!-- 文件路径:/home/user/1.html -->  
<html>  
<frameset cols="50%,*">  
  <frame src="/home/user/dir/2.html">
  <frame src="...">
</frameset>  
</html>

上图中,1.html和2.html被视为相同的源。

<!-- 文件路径:/home/user/dir/1.html -->  
<html>  
<frameset cols="50%,*">  
  <frame src="/home/user/2.html">
  <frame src="...">
</frameset>  
</html>

上图中,1.html和2.html被视为异源。

特立独行的Internet Explorer

在IE中,有两种情况同源策略无效:

TrustZones(信任域):当一个URI被加入到了IE的信任网站区域中时,浏览器会无视同源策略。

IE在考虑同源策略时不包括端口, 这意味着不同端口上的应用程序可以读取到比如用户的登陆账户密码/cookie等。

通过变更自身的源绕过同源策略

IE 6,7版中网页可以通过document.domain设置自身的来源为任意其他来源。如今网页仍然可以更改源,但是有一些限制。

网页可以变更自身的源为父级域名。

例如http://malicious.eth.space/1.html可以通过执行

document.domain = "eth.space";

来绕过同源策略的限制,从而可以读取http://eth.space/login.html上的内容。这其中的应用大家可以自己去想。

注意端口不同的情况。

需要注意的是,在改变源时,端口号是需要特别指定的。由于运行以下js代码

document.domain = document.domain

将会导致端口号被重置为null。所以源http://eth.space:1337不能通过修改document.domain="eth.space"来访问http://eth.space的数据,除非后者也设置了document.domain="eth.space",这样双方的源端口号才能一致(null)。反之亦然。

0x05 谈谈防御

如何安全地允许跨源访问?

最好的方式是使用CORS,跨源资源共享机制。这个需要的篇幅挺大,我们有机会下次讲。

使用Window.postMessage

使用JSONP。

如何禁止(你的资源被)跨源访问?

为了禁止跨域写,我们需要引入CSRF令牌,然而我们需要正确的配置同源策略,否则CSRF令牌本身也将被恶意网页读取。

为了禁止跨域读,我们可以通过设置X-Frame-Options头来禁止该页面被嵌入到恶意页面中,就如同在“经久不衰的BUG”中一样。

为了禁止跨域嵌入,确保你的资源本身无法嵌入到各种跨域访问方式中,比如<script src=></script> <img src=x></img>,<svg onload=>,各种字体加载等等。同时,使用CSRF令牌也可以有效避免被跨域嵌入。

如何禁止你控制的网页中嵌入的iFrame做出恶意行为?

使用HTML5的沙盒iframe。

先写到这里吧,事实上,WEB安全中还有几个重要的机制,例如和同源策略相辅相成的跨域资源共享机制(CORS),和内容安全策略(Content Security Policy, CSP)下次再写。
文章参考于:
1.https://eth.space/same-origin-policy-101/
2.https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
3.书籍《白帽讲web安全》(如有需要请私自联系)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,825评论 4 377
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,887评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,425评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,801评论 0 224
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,252评论 3 299
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,089评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,216评论 2 322
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 31,005评论 0 215
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,747评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,883评论 2 255
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,354评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,694评论 3 265
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,406评论 3 246
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,222评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,996评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,242评论 2 287
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 36,017评论 2 281