和我定下契约,成为魔法少女吧! 收藏本站
登陆 / 注册 搜索

阅读:1.1万   回复: 3

WEB安全第十二课 源的继承

[复制链接]
小执念 古黑浩劫论坛大牛 2016-9-26 23:58 |显示全部楼层

可遇不可求的事:故乡的云,上古的玉,随手的诗,十九岁的你。

管理员
    某些Web应用依赖于像about:、javascript:和data:这样的伪URL来创建无须包含服务器端内容的HTML页面,这些页面的数据完全来自客户端。由于这么做不涉及常规的HTTP请求和服务器端延迟,所以用户界面的响应速度会更快。
    
    不幸的是,原始的同源策略没有考虑到这种使用场景。尤其是,如果单纯地按照前面提到协议、主机名和端口相匹配原则,那么由完全不同的网站创建的所有about:blank文档就都属于同源页面了,如果环境适宜,就可以相互通信而完全不受限制了。
    
    为了解决客户端页面与同源策略不兼容的问题,浏览器逐渐针对伪URL页面推出了一套与常规同源策略不太兼容,有时候还颇有违常理的做法,以此来计算出一个合成的源(synthetic origin)及其访问权限。👨‍🚒‏💄🪟😫👆

    1. about:blank页面的源继承
    
    about:策略在浏览器里派各种用场,大多数都和直接浏览正常网页无关。about:blank文档是个有趣的特例,然而,就这么个URL仍然可以创建一个最小的DOM层级对象(这基本上就是一个有效但空白的页面),父级页面可以在其中写入任意数据。
    

🖐🏦🍞🆎🕊‎

    以下为这一策略的典型用例:
    
[mw_shl_code=javascript,true]    <iframe src="about:blank" "name="test"></frame>
        <script>
        ...
🖕🎠🍌🅱🐋‏        frames["test"].document.body.innerHTML="<h1> Hi mom!</hl>";
    </script>[/mw_shl_code]
    
    注意:在本例子提供的HTML代码里,创建常规新窗口或框架时甚至可以省略about:blank。因为如果创建这个页面的父级文档没有设定URL值,那么默认值其实就是about:blank。
    🧑‍🌾‏👒⚒😡🖕
    在各种浏览器里,大多数情况下访问 about:biank 都会创建一个新页面,这个新的页面也继承了发起页的SOP源。在这个新的JavaScript执行环境里,继承过来的源信息体现在页面的document.domain属性里,about:blank页面对非同源DOM的访问以及非同源页面对about:blank的DOM访问都会一律被禁止。
    
    这条简单的规定对一些明确的操作是成立的,如点击某个链接、提交表单、从脚本里创建一个新的框架或窗口,以及通过程序代码的设定来跳转到某个已存在的页面。也就是说,仍然有例外的场景,最值得引起注意的是几种特殊的由用户控制的跳转方式。

    包括在地址栏里手工直接输人about:blarik,从书签里选择该地址,以及通过事先设定的手势动作打开一个新窗口或者标签页@。这些动作创建出来的页面对应的是些独一无二的合成源,因此这种about:blank就不能再被别的页面访问了。
👄🚗🍊📶🐕‏    
    另一个特例是服务器端正常返回的页面,然后再用Location或Refresh重定向到about:blank炎面。在Firefox和基于WebKit的浏览器里,这种重定向也会产生一个独一无二不可访问的源,类似上一段里提到的情况。

    而IE浏览器里情况则不同,如果新页面是在<iframe>子框架里,那它仍然能被父级页面访问到;如果是在独立的新窗口里产生的,则无法访问。
🧓‌👓📐😒✌
    Opera的表现是最让人费解的:父级页面不能访问由Refresh重定向过来的about:blank页,但通过Location跳转后的about:blank却能继承发起这次重定向页面的源。
    
    更进一步来说,父级页面可以把现有子框架的地址转向about:blank这一URL,即使这个已存在页面对应的源和作为发起者的父级页面并不一致除见浏览器,新创建出来的空白页面都会继承发起者的源。在IE浏览器里,这种跳转虽然会成功但会产生一个无法访问的页面(这种行为多半也是无意所致)。
    
    如果这些描述已经彻底把你绕晕了,我们下图里总结一下对about:blank页面的各种处理情况吧。👩‎👜🖥😈🤝

WEB安全第十二课 源的继承 QQ截图20160925211232.png


    2. data:URL的继承
    

🥷‍👔🧲😘🤝


    我们在前面首次提到过data:协议,它主要用于像图标这样的小文件,因为可以方便地通过直接编码的形式,把数据嵌人在HTML文件里,而无需再经历一遍HTTP的各个环节。例如:
    
    <img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD...">
    
    在对特定类型的子资源使用data:协议时,比较特殊的一个安全问题就是:有些插件系统是根据插件小程序自身的URL,来判断要为它赋予怎样的执行权限。此时就不能只按照data:这样的URL来计算源了,这时的表现往往有点难以预测,而且和各插件自身的处理有很大的关系(例如,Adobe Flash现在已经完全禁止使用data:的URL形式了)。
👃🏠🥄♏🐮‏    
    比data:在上述类型相关内容里的表现更要紧的是,在窗口或框架的目标地址里使用这个协议会带来的问题。除IE浏览器之外的其他所有浏览器里,这个协议都可以视为about:blank的改良版变型,如下例:
    
    <iframe src="data:text/html;charset=utf-8,<hl>Hi mom!</hl>">
    </iframe>🧑‍⚕️‏💎🪟😀✋
    
    在这种用法里,data:形式的URL和about:blank的表现应该是一样的。但实际上,在某几种浏览器里两者的表现并不相同,因此使用的时候务必要小心:
    
    WebKit浏览器 在Chrome和Safari里,所有的data:页面都享有独一无二不可访问的源,也完全不会从父级页面继承源的信息。
    

🙏🏦🍼📵🐻‌

    Firefox 在Firefox里,data:页面的源取决于浏览的环境,具体类似于about:blank.但有别于about:blank的地方是,手工直接输入或从书签里访问data:URL打开新页面时,它的源会继承这次浏览动作发起时所在页面的源信息。
    
    IE浏览器 IE8 以前的版本并不支持data:URL。只有IE8和9里特定类型的子资源才可以使用这个协议,并且不能用于跳转。

    下图总结了 data:url 的表现。👨🦱‏👓🪟😪🦴

WEB安全第十二课 源的继承 QQ截图20160926235530.png
    
    3. javascript: 和 vbscript:URL 对源的继承
    
    与脚本相关的伪URL,如javscript:的源继承机制相当有意思。用这种URL机制加载某些类型的子资源时,会在加载这个URL的页面里,以该页面的上下文权限执行相应的脚本代码。举例如下:
💅🚤🥭♏🐢‌    
    <iframe src="javascript:alert('Hi mom!')"></iframe>
    
    比创建新的子资源更令人感兴趣(往往也更隐晦)的是,使当前已存在的窗口或框架跳转到javascript:URL,这样会导致在被跳转的页面(而非发起跳转的页面)运行环境里以内嵌方式执行了这段JavaScript代码——即使这个URL只是手工输入或从书签里加载的。
    
🤟🌦🍭🆘🐠‌    因为这种表现,任何把非同源页面跳转到javascript:URL的行为明显都是非常不安全的,因为这样就绕过了其他的内容隔离机制:比如在子框架里先加载fuzzybunnies.com,然后再令这个框架里的页面跳转到javascript:do_evil_stuff(),那就彻底完了。

    因此,除了Firefox,这种行为都是被禁止的。Firefox显然出于某种考虑而允许了这种行为,但也还是偷偷地改变了原本的语义。当发起页面的源和要跳转的目标不匹配时,javascript:里的内容会放到一个特殊的空白源里执行,这个环境里没有DOM或任何浏览器支持的I/O函数(所以只能执行纯运算型的操作)。
    
    非同源的情况是危险的,但同源的情况则不然:在同源的情况下,任何内容都可以根据需要,任意地把自身或者同等权限的页面转向javascript:URL。在这种情况下,点击链接、提交表单、调用location.assign(...)等操作时,都可以成功执行javascript:URL。在WebKit和Opera里,Refresh也可以被重定向到javascript:;而其他浏览器则由于担心恶意或误用导致的脚本注人,禁止了这种跳转。

👁⛴🫖🅾🦬‎

    
    对脚本型URL的处理总结见下图。

WEB安全第十二课 源的继承 QQ截图20160926221205.png
    
    除了这些让人眼花缭乱的语义用法,还有一个仅在javascript:策略里才会出现的情况:在某些情况下,处理这些包含脚本的URL还会带来第二步动作。特别是,如果提供的代码能正确执行,而且最后一行代码的值为非空,并可以转化成一个字符串时,这个字符串会被当做HTML文档来解析,进而代替被跳转的原页面内容(源则从发起页继承过来。这种令人好奇的行为背后的逻辑和影响与data:URL的情况非常类似。这种替代页面的表达式例子如下:    🧑‍🚀‏👗✏😷✍
    
    javascript:"<b>2+2= "+(2+2)+"</b>"


    4. 关于受限伪URL的一些补充
🖕🧳🦀™🪶‍    
    尽管各自的表现都有点稀奇古怪,大部分的网站也只需要关心我们上面提到的这三种伪URL格式:about:blank、javascript:和data:。然而,浏览器里还有一堆其他的页面,既无从继承,也没有清晰定义的源(例如Firefox里的about:config,这个特权JavaScript页面用于调整浏览器的隐藏设置,或Chrome里的chrome://downloads,它可以列出最近下载过的文档和直接打开下载文件的链接)。这些页面一直是引发安全问题的来源,即使它们不能从互联网上直接访问到。
    
    因为这些URL与同源策略控制的边界不兼容,无论是由于用户的操作而加载在浏览器里的页面,还是其他浏览器级别处理的间接后果,都必须充分地把这些URL和其他的内容隔离开来。2010年在Firefox处理about:neterror时出现的一个bug,正是描述这种风险的有趣案例。
👳‌🎒🗝😊👃
    当Firefox不能成功地从远端服务器取回文档时(只要费点心构造个假链接,就很容易触发这一条件),尽管在浏览器地址栏里还是目标URL,但内容部分加载的其实是about:neterror页面。但不幸的是,尽管只是个小小的疏忽,但这个特殊的出错页面和其他互联网页面打开的所有about:blank页面都是同源的,因此,攻击者就可以一边在浏览器里保持正确的URL地址显示,另一边对about:neterror窗口注人任意内容了。
    
    这个故事的教训是什么?就是避免和同源策略做对赌;而应该顺势而为。如果把about:neterror当成一个层级URL,而不是使用一个合成形式的源,就能阻止这个bug。#t237:

上一篇
下一篇
帖子热度 1.1万 ℃

清风霁月 「出类拔萃」 2017-9-22 19:47 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

佩服佩服!#j325:
屋顶,数星星 「出类拔萃」 2018-4-30 22:59 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

第一次评论,

🤞⛴🧊🆚🐝‍

好紧张啊,


该怎么说啊,
👴‎🩰📞😒💅
打多少字才显的有文采啊,
这样说好不好啊,


会不会成热贴啊,
🤳💈🍞🅱🦉‍
我写的这么好会不会太招遥,
写的这么深奥别人会不会看不懂啊,
怎样才能写出我博士后的水平呢,
半年写了这么多会不会太快啊,🧑‍💻‌🎩🏮🥰🙏
好激动啊。#y424:#y424:
夏雨初晴 「出类拔萃」 2018-5-7 09:22 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

          ⚠内容无法访问
        ━━━━━━━━━━━━━━━
当前网络不可用,是否尝试连接无线网络?
——————————————————
     ✗ 取消   │  ✓ 确定
您需要登录后才可以回帖 登录 | 免费注册  

本版积分规则

快速回复 返回列表