面对就好,去经历就好。 收藏本站
登陆 / 注册 搜索

阅读: 8.1K   回复: 3

[# 网络安全] WEB安全第十一课 内容隔离逻辑

小执念 古黑浩劫论坛大牛 2016-9-17 22:09 |显示全部楼层

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

管理员
        浏览器通过隔离来自不同源的文件之间的访问来提供各种安全保障。这个预设前提很简单:来自不同源的两个页面之间不应该彼此交互。当然,实际应用上会更复杂,毕竟,到底从哪里到哪里算是一个独立的文档,以及对单一来源的组成,都没有统一的规定。结果就是一堆难以预期、相互抵触的策略拼凑在一起,这些机制运行得不算很好,但要去调整它们的话,又势必会极大地影响现有Web应用的正常使用。
       
        除了这些问题之外,从最初的时候开始,哪些行为需要进行安全检查就没有明确界定。某些交互动作,如点击某个链接,就不需要做特别的限制,否则就会影响整个互联网的生态系统,而其他一些行为,如修改在另一个窗口里的页面内容,就必须进行安全检查了。但在这两种极端情况中间,还有大片的灰色区域,在这片灰色区域里,似乎就缺乏统一的安排了,事情往往像拋骰子一样随机而定。在这汪浑水里,正适合滋生各种漏洞,譬如跨站请求伪造。
       
        现在是时候展开这一主题了。让我们掷出手中的骰子,先从JavaScript开始,踏上探索之旅吧。

WEB安全第十一课 内容隔离逻辑 javascript.jpg
       
        1.DOM的同源策略
       
        同源策略(Same-OriginPolicy,以下简称SOP)概念是1995年Netscape公司连同JavaScript和文档对象模型(Document Object Model,DOM)—起引入的,仅比HTTP Cookie晚了一年。这条规则颇为直接了当:除非JavaScript所处的两个页面的协议、DNS域名、端口都完全一致,否则两个独立的JavaScript运行环境不能访问彼此的DOM。其他任何跨文档JavaScriptDOM访问也会失败。
       
        这种由协议-域名-端口三元素组合在一起的算法就叫"源"(Origin)。源这一概念作为一项基础的安全策略还算比较健壮:所有常用浏览器都支持SOP,而且实现也颇为一致,除了偶尔还有些缺陷。实际上,由于IE浏览器在做同源检查时会忽略端口,所以主要的问题都在它身上。这个惯例在实际运用中还略有些不安全的因素,特别是对支持HTTP/0.9协议的Web服务器提交非HTTP请求数据时。但这个影响通常不算大。        .
       
        下图描述了各种场景里同源检查的结果。

WEB安全第十一课 内容隔离逻辑 QQ截图20160916225140.png

        注意:同源策略开始时只是用于限制对DOM的访问;也就是说,涉及实际彡展示的文档内容有关的方法和属性。但逐渐地,这项策略慢慢也扩散到保护JavaScript的根对象开始的其他敏感数据,当然同源机制也并非无所不包的。例如,非同源的脚本仍然可以对任意窗口或框架使用location.assign()或location.replace...)。

        同源策略的简单既是一种优势又是一种障碍。这套机制很易于理解,正确实现也不难,但由于缺乏灵活度,对开发人员来说可能是个负担。但在某些方面,这套策略又太宽泛了,导致无法隔离原本属于两个用户的网页(因为无法给每个用户单独分配一个域名)。而在另一种环境下,相反的情况也是成立的:这个策略使得原本合法的同站点域名(例如login.example.com和payments.example.com)之间不能无缝地交换数据。
       
        尝试修复第一个问题的努力——也即缩小同源的范围,由于浏览器里其他显式或隐式的安全控制,通常都会注定失败。尝试放宽同源的范围或实现跨域交互是更常见的情况。为达成这一目标而受到广泛支持的两种方式分别为document.domain和postMessage(...),下面我们来讨论一下这两套机制。
       
        1.1. document.domain
       
        JavaScript允许两个拥有同一顶级域名的相关网站(如example.com甚至仅仅是.com),协商认可彼此的同源检查,把它们视为同样的站点。例如,login.example.com和payments.example.com都进行以下赋值:
       
        document.domain="example.com"
       
        设置了这个属性会覆盖在同源策略检查中的主机名匹配逻辑。协议和端口号仍然需要匹配,如果协议和端口号不一致,仅仅调整document.domain并不会达到预期的结果。
       
        而且双方都必须明确地遵从这一规定。只是简单地在login.example.com—方把document.domain设置为example.com,并不能使它就可以访问网站 http://example.com/ 的内容。即使按我们的常识来看似乎没必要,但对方网站也必须进行同样的赋值。这个效果是相互的。一个设置了document.domain的页面不能访问一个没有设置过的页面,而且设置了这一属性后,原本与发起方同源的页面,现在就几乎(但并非完全)无法访问该页面了。

        下图显示了各种document.domain值设置的效果。

WEB安全第十一课 内容隔离逻辑 QQ截图20160916225706.png
       
        除了这套机制有点复杂,在某些场景里不够明晰外,document.domain也不是特别安全。它最大的弱点是会招来讨厌的不速之客。如双方都把这一属性设置为example.com,这样不但logiruexample.com和payments.example.com可以相互通信;而且funny-cat-videos.example.com也可以趁势加人了。由于不同页面之间的访问控制,以及参与各方的JavaScript运行环境的安全性,都没有切实的保障。也就是说,修改document.domain会不可避免地把网页的安全交托给整个域名环境里安全最薄弱的环节了。一个极端的例子就是把这个值设置为*.com,那基本上就等于引狼入室了。

        1.2. postMessage(...)

        postMessage(...)API原本属于HTML5里的扩展,使用虽然略有不便,但对非同源站点之间的通信更安全,也不会损害任意一方网站的完整性。所以尽管是一门相当新的技术,但现已获得除InternetExplorer6和7以外所有常用浏览器的支持。
       
        只要发送端拥有某个窗口的有效JavaScript句柄,就可以通过这套机制向该窗口发送任意长度的文本信息。如果要使用其他类似的方式达到同样的效果,就会受困于同源策略,因为这中间还要跨过好几道关口,但用postMessage的方式却是安全的。这套机制由发送端来决定哪个页面能接收到其发出去的信息(以防目标窗口中的URL发生过变化),在发送的过程中,也会为接收端提供发送页面自身的身份信息,所以能轻易确定这个通道的真确性。相反,以前依赖于同源的做法往往并没有这样的保障;如果对某个动作没有进行足够的安全检查,那这个动作就有可能来自恶意的第三方,而非来自原来预想中的参与方。
       
        要正确描述PostMessage(...)的使用,请考虑以下这个场景,在payments.example,com的根路径下有个页面,需要把用户的登录信息显示在该页面上。为达到这个目的,payments.example.com的这个页面加载了一个指向login.example.com的子框架。这个子框架只需要发出以下指令:
       
        parent.postMessage("user=bob","https://payments.example.com");
       
        只有当父级页面确实就是指定的信任源时,浏览器才会向它发出postMessage的消息。而处于根路径下的接收方文档需要使用以下代码才能安全地处理这个响应:
       
[mw_shl_code=javascript,true]        //对传进来需要处理的消息先进行注册:
        addEventListener("message",user_info,false);
       
        //收到实际数据时的具体处理:
        function user_info(msg){
                if(msg.orlgin =="https://login.example.com"){
                //根据计划使用msg.data数据。
        }
        }[/mw_shl_code]
       
        PostMessage(...)的机制很强壮,它提供的好处也远比document.domain和之前出现的各种杂牌方案来得更大,因此应该尽量采用这种方式。当然,这套机制也仍有可能使用不当。考虑一下这个检查发送端域名是否包含某些特定字符串的处理:
       
[mw_shl_code=javascript,true]        if(msg.origin.indexOf(".example.com")!= -1){...}
[/mw_shl_code]
       
        很明显,这个对比不但会匹配到在example.com范围内的站点,还会想当然地接受www.example.com.bunnyoutlet.com这样的域名而在后面的探索之旅中,显然我们还会不断地碰到与之类似的代码。这就是艰难的人生啊!
       
        注意最近对HTML5的调整也扩展到了postMessage(...)API,以整合有点过于复杂的"端口"和"通道",这两者主要用于网站之间的流媒体通信。支持这些特性的浏览器目前还很有限,实际使用效果也还不太清楚,但从安全的角度来说,似乎没有什么特别值得关注的地方。
       
        1.3与浏览器身份验证的交互
       
        我们快要讲完与DOM相关的同源策略了,很重要的一点是,要记住同源策略没办法和全局身份认证、SSL状态、网络上下文环境以及众多由浏览器管理涉及安全的其他参数进行同步。在同一个浏览器里打开的任意两个窗口或页面框架之间,即使在一个窗口里用户已经退出登录了,而在另一个里仍保持登录状态,这两个页面也仍算是同源,如果两个页面其中一个的HTTPS证书有效而另一个无效,也是同理。

        由于同源策略和其他身份验证信息之间缺乏必要的同步机制,可能会导致一些安全漏洞。例如,某站点的登录表单有跨站请求伪造漏洞,任何第三方站点只需要简单地提交一下用户名和密码,就能把用户登录到攻击者控制的某个账号里去。这点乍一看似乎挺无害的,但如果浏览器已经加载的页面和这步登录操作之后的页面被视为同源页面,那原本不会起作用的"自感染"(self-inflicted)跨站脚本漏洞(这类跨站脚本漏洞的含义是,它们仅对登录用户自身有效)突然就变得严重了。

        在最基本的场景里,攻击者首先在框架里嵌入目标网站上的一个敏感页面(譬如http://www.fuzzybunnies.com/address_book.php) 然后诱使受害者登录到该站一个由攻击者控制的账号里,然后执行fuzzybunnies.com站点其他应用里的自XSS跨站攻击。尽管此时HTTP身份验证信息已经改变了,但在后一个步骤里的代码注人却会对之前加载的子框架具有完全的访问权限,也会导致数据被窃取。

#f185:

        2. XMLHttpRequest 的同源策略
       
        在之前的章节里也偶尔提到过几次XMLHttpRequest API,可以用这项技术向JavaScript程序所在文档对应的服务器发送几乎不受限制的HTTP请求,并读取返回的响应头域和文档的内容。如果不是因为这套机制也会用到浏览器的HTTP堆栈及其组件,包括全局身份认证、缓存机制、持续会话等等,这种能力倒也不值得特别关注。
       
        以下这个同步方式的XMLHttpRequest应用很简单,就光看字面也很容易理解:
       
[mw_shl_code=javascript,true]        var x = new XMLHttpRequest();
        x.open("POST","/some_script.cgl",false);
        x.setRequestHeader("X-Random-Header","Hi mom!");
        x.send("...POST payload here...");
        alert(x.responseText);[/mw_shl_code]
       
        异步的请求也非常类似,但执行的时候不会阻塞JavaScript引擎或浏览器。请求会在后台发送,完成时会调用相应的事件处理器。
       
        按原先的设想,通过XMLHttpRequestAPI发送HTTP请求和读取数据要遵循的同源策略与浏览器默认的差不多完全一致,但有两项看起来很随意的细微调整。首先,document.domain设置这时候是完全无效的,在XMLHttpRequest.operK...)里设定的目标URL地址必须与发起的页面真正地同源。其次,在这个执行环境里,即使IE9之前的版本也会把端口一致考虑进去,虽然IE浏览器在其他的同源判断里并不包括端口。
       
        用户对XMLHttpRequest方式发出的请求头域具有前所未有的控制力,这点在安全上反而是项优势。例如,可以插入一个自定义的HTTP头域,如X-Coming-From:same-origin,作为确认特定请求并非来自第三方站点的一个简单方法,因为如果来自其他站点,从浏览器发出的请求里则不可能带有这个自定义的头域。

        但这个保障也不算特别靠谱,因为并没有什么规范明确规定,跨域的请求头是一成不变的;反正说到Web安全,我们也只能勉强接受这类不算绝对可靠的预设条件了。
       
        然而能控制HTTP请求的构成也可能会产生问题,因为插入某些类型的请求头可能对目标服务器端或代理服务器的请求解析产生影响,而浏览器本身却完全没察觉到。例如设定错误的Content-Length值可能导致攻击者在原该由浏览器维护的HTTP持续会话里偷偷摸摸地加塞进第二个请求,具体如下:
       
        [mw_shl_code=javascript,true]var x = new XMLHttpRequest();
        x.open("POST","http://www.example.com/",false);
       
        //这会覆盖掉浏览器计算出来的Content-Length请求头:
        x.setRequestHeader("Content-Length","7");
       
        //服务器会认为在收到7个字节之后,浏览器发过来的数据就结束了,
        //其余的部分则另属于一个独立的HTTP请求
        x.send(
        "Gotcha!\n"+
                "GET /evil_response.html HTTP/l.l\n" +
                "Host: www.bunnyoutlet.com\n\n"
        );[/mw_shl_code]
        如果发生这种情况,第二个被注入进去的请求产生的响应内容可能会被浏览器错误解析,结果导致缓存内容被污染或内容注入到了另一站点。这种情况在使用HTTP代理服务器,并且所有的HTTP请求都通过一个共享通道发出时尤为突出。
       
        因为这种风险以及由此带来的各种折腾和问题,常用浏览器会把一部分HTTP请求头和请求方法列入了黑名单。但各家的做法并不是很统一:

        所有浏览器都把Referer、Content-Length和Host列人黑名单,但各家对User-Agent、Cookie、Origin和If-Modified-Since的处理则略有不同。类似地,TRACE方法也是完全被禁掉了,因为这个方法会给设置了httponly的Cookie带来意想不到的风险——但Firefox允许CONNECT方法,尽管这个方法有可能给HTTP代理服务器带来潜在的风险。
       
        当然啦,这些黑名单的实现也各有滑稽之处。以下仅供娱乐,看看这个案例,3年前某些浏览器里还支持这种请求:
       
        XMLHttpRequest.setRequestHeader("X-Harmless","1\nOwned:Gotcha");
       
        或者:
       
        XMLHttpRequest.setRequestHeader("Content-Length:123        ", "";
       
        或者仅仅是:

        XMLHttpRequest.open("GET\thttp://evil.com\tHTTP/l.0\n\n","/",false);
       
        注意:跨域资源共享(Cross-Origin Resource Sharing,CORS)是针对XMLHttp-Request的一项建议性扩展,用这种方式发送跨域HTTP请求时,只有返回的数据里包含特定的响应头时,浏览器才能读取到响应数据。这套机制改变了本章讨论的XMLHttpRequest API语义,因为这样就可以用XMLHttpRequest.open(...)的方式,直接发送某些受到认可的"友善无害"的跨域请求,而无须受到额外的限制,就能把这些跨域请求视为常规的访问;更复杂一点的请求需要先以OPTIONS方法发送一个"试飞"(preflight)性质的测试请求。

        现在已经有一些浏览器支持CORS机制了,但微软对这套机制比较抵触,因为他们在IE8和9里开发了与之竞争的XDomainReques机制。两种机制间的冲突会带来什么后果暂时还不清楚,但对CORS机制的详细讨论会放在后面,到时我们还会更系统地探讨正在涌现的各种实验性机制。

#f192:

        3. Web Storage 的同源策略
       
        Web存储(Web Storage)方式始于Firefox 1.5,是Mozilla工程师在浏览器里实现的一种简单的数据库,并逐渐为HTML5规范所接受,现在除了IE6和7之外,所有的浏览器都支持这项技术。
       
        在经过几个略有问题的迭代之后,目前的设计架构在两个简单的JavaScript对象上:localStorage和sessionStorage。这两个对象的API完全一致也非常简单,用于对浏览器管理的数据库进行名-值数据对的创建、检索和删除等操作。例如:
       
        [mw_shl_code=javascript,true]localStorage.setItem("message","Hi mom!");
        alert(localStorage.getItem("message"));
        localstorage.removeItem("message");[/mw_shl_code]       
        localStorage对象实现的是与站点源(origin)相关的持久存储,关闭浏览器之后localStorage仍然有效,而sessionStorage则绑定了当前浏览器窗口,提供的是临时的缓存机制,在浏览会话结束之后就会被清理掉。尽管规范里认为localStorage和sessionStorage都应遵从SOP形式的同源策略(根据协议-主机名-端口 3元素进行匹配),但在某些浏览器里的具体实现却未必遵守这一规定,可能会引人潜在的安全漏洞。

        最值得引起注意的是,IE8在比较是否同源时,会忽略协议的部分,这导致HTTP和HTTPS页面会共享同样的运行环境。这个设计使得HTTPS站点通过这个API存储和读取敏感数据时变得很不安全(这一问题在IE9里得到了纠正,但似乎还没有计划修复旧版本的问题)。
       
        而Firefox的做法又不一样,它对localStorage的处理是正常的,但sessionStorage的接口却有问题。Firefox的HTTP和HTTPS存储共享同一个工作环境,如果HTTP的内容去读取由HTTPS创建的Key,Firefox的安全检查会阻止这种行为。但这里存在一个严重的漏洞:任何由HTTP创建的Key,后来又被HTTPS更新过,就仍然能够由非加密的HTTP页面访问到。这个缺陷在2009年4的时候才被发现,据说Firefox会修复此漏洞,但何年何月还不清楚。

#f192:

        4. Cookies 的安全策略
       
        我们在前面探讨过 HTTP Cookie的语义,但在之前的讨论里,我们没有涉及一个重要的细节:要使用怎样的安全策略,才能使某站点的Cookie不会被无关页面篡改掉。这个主题特别有意思,因为Cookie的出现早于同源策略,所以两者的交互会产生一些意想不到的问题。
       
        Cookie的默认有效范围是域名,但却没有办法把Cookie的范围限制在单个主机名上。可以把Cookie里带的domain参数设置成和当前主机名完全一样(例如foo.example.com),但实际上访问该主机名的子域名如bar.foo.example.com时,也会发送相应的有效Cookie。如果把domain设置为example.com,按照从最右边开始匹配主机名的做法,显然能匹配到的范围就更大了。
       
        有意思的是,最开始的RFC版本显示,Netscape的工程师原本希望Cookie的匹配范围就是精确地与主机名保持一致,但他们却没有遵守自己的提议。之后的Netscape Navigator版本(或者说之后的任何版本)都再没有支持过原先构想的Cookie范围。在某些浏览器里如果完全不设置domain参数,反而能使Cookie的范围局限于主机名之内,但这个方法也颇受限制,因为对IE就完全无效。

        下图描述了在各种特定场景里Cookie设置的表现。

WEB安全第十一课 内容隔离逻辑 QQ截图20160917114802.png

        唯一有效的Cookie范围设置参数其实是路径前缀(pathprefix):通过对任何Cookie设置一个特定的path值。这个值提示浏览器,只有请求的路径与Cookie里的path参数相吻合时,才发送该Cookie;Cookie的domain范围如果为example.com,路径设定为/some/path/,访问以下链接的请求就会包含该Cookie:
       
        http://foo.example.com/some/path/subdirectory/hello_world.txt
       
        这套机制也有一定的欺骗性。因为同源策略并不检查URL路径,因此URL路径没法构成有效的安全边界〇无论Cookie如何设定,JavaScript代码都可以随意访问同一主机上的不同URL,并对这些目标注人恶意数据,以至于能攻击到原本受路径形式Cookie保护的功能(颇有些安全方面的书籍和白皮书都推荐设定Cookie的路径范围作为安全手段。但大多数情况下,这个建议是完全错误的。)
       
        除广这些与Cookie范围真正相关的特性(Cookie的范围和名称一起就能独一无二地确定一个Cookie),网站服务器还对Cookie提供了两个特殊的可单独设置的标记:httponly和secure。前者通过设置httponly标签,可以禁止使用document.cookie API来访问页面的Cookie,这样即使页面真的被注人了恶意代码,也无法简单地用这个API复制出用户的身份信息。

        后面这个secure标签,使得Cookie无法被用在非加密协议的通道里,这样就必须使用HTTPS服务所以能防御主动攻击(Active Attacks)。
       
        但这些机制的缺陷是它们都只能防止数据不被读取,但却不能防止数据被覆盖。例如,运行在HTTP通道的JavaScript代码可以简单地使某域名对应的Cookie池发生溢出,然后再设置一个新的不带secure标记的Cookie。

        可以这么做的原因是,浏览器发出的Cookie请求头里其实并没有携带任何与Cookie的源或范围有关的元数据信息,所以这套把戏很难被发现。这种行为的另一个重大的影响是,防范跨站请求伪造漏洞的一个做法往往会同时在客户端Cookie和隐藏的表单字段里,都分别存放一个隐秘的令牌数据,之后再对比两者是否一致,这套"无状态"(Stateless)的防范方式对HTTPS站点来说就不是很安全了。仔细想想,看你能否明白这里头的问题。
       
        注意:说到破坏性的干扰,直到2010年,Cookie 的 httponly 标签和 XMLHttpRequest 仍然有冲突。XMLHttpRequest 的开发者们完全没有考虑到 XMLHttpRequest.getResponseHeader(...)函数需要判断服务器端提供的Set-Cookie值是否被标记为httponly——这个结果就可想而知了。
       
        4.1. Cookie 对同源策略的影响
       
        同源策略对Cookie的安全性带来了一些不好的影响(更具体来说,影响了Cookie的路径范围机制),但反过来的情况其实更常见也更严重。因为麻烦之处在于HTTPCookie经常被用作身份认证的标识,在这种情况下,能获得Cookie信息就差不多等同与绕过同源策略了。很简单,只要有正确的Cookie值,攻击者就可以伪装成受害者,用自己的浏览器直接与目标站点交互;这已经没同源策略什么事,但亦全盘皆输了。
       
        因为这个属性,Cookie和同源策略两者间的差异会导致在安全上更严格的那一方受到损害。例如,对相对宽松的HTTP Cookie域名范围规则而言,这意味着不可能把webmail.example.com上的敏感信息和blog.example.com上较不可靠的HTML页面完全隔离开来。即使Webmail应用的管理者已经把Cookie的范围设置得非常严密(这么做的代价往往会把登录过程弄得很复杂),但如果攻击者能在博客站点上找到脚本注人漏洞,就能轻易地在基于域名的Cookie池里覆盖掉旧的Cookie,进而删掉原有的身份认证信息,并设置成黑客自己的*.example.com范围内的Cookie。

        在之后的所有请求里,这些被注入的Cookie会再发往webmail.example.com,这时候网站已经完全无法分辨出真假Cookie了。
       
        这个花招乍一看好像无什么危害,但这个攻击能把受害者登录到一个伪造的帐号里去,在用户甚至还未留意到有任何异常之前,他的某些操作(如发送电子邮件)已经在这个帐号里被无意中记录下来并泄漏给攻击者了。用Webmail应用做例子也许有点偏门,那想想看在Amazon或视频租赁网站Netflix里发生这种事情吧:在用户还未及留意到站点有何异常前,他的产品浏览和搜索操作已经被泄漏给攻击者了(此外,很多站点都没有考虑过如何处理在Cookie里注人的恶意数据,这些超出预期的输入数据很可能会导致跨站或其他类似问题)。
       
        HTTP Cookie的落伍特性使得即使在加密通道里传输的Cookie也不是那么可靠。

        https://webmail.example.com/ 设置的secure属性的Cookie也还是有可能受到攻击和被替换掉,只要通过假冒的

        http://webmail.example.com/ 页面来构造Cookie值即可,即使在这个假域名上压根没有Web服务在80端口监听着。
       
        4.2. 域名限制带来的问题
       
        Cookie的有效范围是整个域名级别这一误导人的概念给浏览器开发商也带来了问题,由此引发了许多悲惨的故事。最关键的问题是,如何可靠地防止example.com设置出针对*.com范围的Cookie,以避免Cookie被错误地发往互联网上每一个网站。
       
        针对这一问题有几种简单的处理方式,可是如果考虑到国家级别的顶级域名格式:example.com.pl,所以Cookie的发送范围也不能用*.com.pl,这样之前的那些做法又都无效了。意识到这一点,原本NetscapeCookie规范里有以下建议:
       
        只有处于具体域名的主机名范围内,才能设置该域名对应的Cookie,这个具体域名至少需包含2个或3个点号,以避免出现以下形式的域名:".com"、".edu"和"va.us"
       
        如果域名属于以下7种特定格式的顶级域名之列,那么它的有效域名范围只需要包含2个点号。除此之外的其他域名范围,则需要至少3个点号。这7种特殊的顶级域名为:"COM"、"EDU"、"NET"、"ORG"、"GOV"、"MIL"和"INT"。
       
        唉,这条3个点号的使用规定只对国家域名里的层级关系和常规顶级域名一致时(example.co.uk)才有效,但对另一种很常见的直接使用国家代码域名的方式(example.fr)却并不适用。事实上,在有些国家和区域这两种形式都是可以的;例如,exampie.jp和example.co.jp都属完全合法。
       
        由于这条建议与实际情况相脱节,导致大多数浏览器开发商都对它置之不理,取而代之的是针对不同的情况进行东拼西凑的处理,这样的后果往往是泥足深陷(例如其中的一个例子,在超过10年的时间里,实际上可以把Cookie的范围设置为在过去4年里,所有常用浏览器都针对国家代码的顶级域名处理进行了全面修正....
       
        注意:雪上加霜的是,Internet Assigned Numbers Authority在最近几年又增加了一批顶级域名(例如.int和.biz),而且该机构还在酝酿一个允许任意顶级域名注册的提案。如果真到了那一步,Cookie机制恐怕得要从头开始再设计一次了。
       
        4.3. localhost 带来的非一般风险
       
        Cookie的有效范围是整个域名级别,显而易见,在整个域名范围内,较敏感的主机名会被其中较不可信(或有漏洞)的同一域名其他主机所拖累;这样就可能有损系统的保密性,不可避免的,任何以Cookie方式存放的用户身份的真确性都会受到危害,由此更是有可能影响目标应用的所有信息。
       
        以上缺陷是一目了然的,到了2008年,Tavis Ormandy还发现了一个很有违常理也非常可笑的问题:由于HTTP Cookie的工作机制与端口完全无关,有些管理员为了方便管理,往往会在自己的域名记录里添加一项名为"localhost"的条目,并把它指向IP127.0.0.1,这实际上会带来一定的风险。

        Ormandy发表这篇报告时认为设置localhost域名条目的做法非常广泛,这点确实没什么争议,以下这些域名解析的结果也能支持他的论点:
       
        localhost.microsoft.com has address 127.0.0.1
        localhost.ebay.com                 has address 127.0.0.1
        localhost.yahoo.com         has address 127.0.0.1
        localhost.fbi.gov                 has address 127.0.0.1
        localhost.citibank.com  has address 127.0.0.1
        localhost.cisco.com         has address 127.0.0.1
       
        为什么这会带来安全风险呢?很简单,这么做之后,原本在用户自己机器上的HTTP服务,就变得和互联网上的真实网站拥有同样的域名了,而更重要的是,只要看起来像是HTTP的服务都被混为一谈了。而这些内网里的服务由于不需要对互联网开放,所以一般不会经过特别严谨的设计也不需要经常更新。Tavis举的例子就是CUPS(Common UNIX Printing System,通用UNIX打印系统)提供的打印机管理服务,通过以下方式,就可以在example.com环境里执行攻击者提供的JavaScript程序了:
       
        [mw_shl_code=javascript,true]http://1ocalhost.example.com:631/jobs/?[...]
        &job_printer_uri=javascript:alert("Hi mom!")[/mw_shl_code]       
        CUPS里的漏洞是可以修复,但在各式各样操作系统上很可能还有各式各样隐秘的本地服务——包括从磁盘管理工具到防病毒状态栏。引入指向127.0.0.1这样的域名解析,或任何其他不受控的目标地址,都会把用户域里的Cookie安全性与任意第三方软件的安全性绑到了一起。应该尽量避免这种事啊。

#f192:
       
        4.4. Cookie 与"合法"DNS劫持
       
        Cookie域名范围策略带来的问题还远不止localhost这一种。另一个让人意想不到的效果与某些ISP(互联网服务供应商)和DNS服务商对于不存在的域名(这种"不存在"的域名往往是由于输入错误导致)查询处理有关,这种做法很常见但也广被垢病。

        这些服务商不是从上级域名服务器返回标准规定的NXDOMAIN响应(这种情况会触发浏览器或其他网络应用返回出错信息),而是会假造一个记录,把域名解析引向自己的站点。而他们自己的站点,则会根据浏览器里的Host请求头的信息,把用户转往一个与他的浏览兴趣牵强相关的付费广告页面上去。对于这种做法,他们往往辩称是为了提供更友好的浏览体验;当然真正的原因是为了赚取更多的钱。

        采用这种做法的互联网服务供应商包括Cablevision、Charter、Earthlink、TimeWarner和Verizon还有其他许多家。不幸的是,这种做法不但在道义上值得商榷,还带来了不少的安全隐患。如果在这些广告站点上有任何脚本注人漏洞,攻击者只要让受害者访问一个不存在的网址,如nonexistent.example.com,再利用这种广告站点上的漏洞,就能获得任意域的上下文环境执行权限。如果能再结合HTTPCookie的特性,这种做法实际上会损害互联网上任意一个Web服务的安全性。
       
        可以想象得到,要在这些胡乱设计的广告站点里找到脚本注人漏洞完全不费吹灰之力。例如,在2008年,Dan Kaminsky就找到并发表了通过Earthlink的广告页面进行跨站脚本攻击的文章。
       
        好了好了,就说到这里,我们不再絮叨Cookie了,来看点新东西吧。#t209:

#f192:
       
        5. 插件的安全规则
       
        浏览器没有为插件开发者提供一套统一可扩展的API,实现强制的统一的安全策略;而是由每个插件自己来确定要在执行环境里应用什么规则,以及具体怎么实现这些规则。可想而知,尽管插件的安全模型在某种程度上也受到同源策略的影响,但在许多方面又会各有变异。
       
        这种割裂可能会带来危险。我们讨论了插件往往依赖于检查JavaScript的location对象来确定插件的引用页面的源。这种错误的做法导致浏览器开发者必须限制JavaScript程序可以篡改某些实时运行环境的能力,以避免产生安全问题。另一个经常引发兼容性问题的地方是对URL的解析。

        例如,在2010年一位安全研究人员发现Adobe Flash在识别以下URL时会有问题:
       
        http://example.com:[email protected]/
       
        Flash插件认为该URL的域应该是example.com,但浏览器碰到这URL时,却会去bunnyoutlet.com取回数据,并把结果交给一头雾水的插件进行处理。
       
        尽管这一缺陷现已被修复,但类似的问题日后很可能还会再出现。所以重蹈前面关于URL解析的各种乱象,肯定是徒劳无益的,理想情况下压根就不应该自己发明轮?徒劳地做此类尝试。
       
        以这么灰暗的调子结束这一章也太令人失望了!除了系统级的问题以外,我们再来看看一些常见插件在安全策略加固方面的处理。
       
        5.1. Adobe Flash
       
        Flash的安全模型在2008年经过一次很彻底的检修,在那之后,Flash的安全性相对而言较为健壮了。现在系统会按照被加载的Flash程序自身的URL地址,指派一个SOP形式的源,并与JavaScript同源策略相类似地分配与之相应的权限。重点要说的是,Flash程序可以加载其原属站点(originating site)上由Cookie控制的授权内容,或者从其他非同源站点加载特定类型的受限数据,还可以用与XMLHttpRequest相类似的URLRequestAM,向同源站点发送HTTP请求。

        Flash对于URLRequest有权使用哪些方法和请求头,管理得可算相当不错,在本书写成之时,它比大多数浏览器对XMLHttpRequest的黑名单管理要更严格。
       
        在这个合理的基准线之上,还有3项很灵活但也容易用错的机制,这几种机制会使Flash插件的表现与上面提到常规情况有不同程度的差异,我们来详细讨论一下。
       
        a.标记语言里的安全控制
       
        加载Flash程序的页面可以在<embed>或<object>标签里设定3个特别的参数,来控制Flash程序和它所在页面以及浏览器之间的交互:
       
        AllowScriptAccess 参数 用于设置是否允许Flash程序可以用ExternalInter-face.call(...)桥接方式调用JavaScript,以便在引用站点的上下文环境里执行JavaScript代码。

        可设置的值包括:always、never和sameorigin;最后一个设置意味着只有引用页面和Flash程序同源时,才允许Flash程序执行JavaScript(在2008年的安全大检修之前,该插件这项默认设置为always;现在的默认设置是更安全的sameorigin)。
       
        AllowNetworking 参数 这个参数的命名实在不怎么样,其实这个参数用于限制Flash程序是否具有打开或定位浏览器窗口的权限,以及能否向该Flash程序所在服务器发送HTTP请求。

        如果设置成all(默认值),即Flash程序可以和浏览器交互;设置成internal,则只能通过Flash插件执行一些简单的危害不大的内部通信。把这个参数设置为none,会禁用大多数与网络功能相关的API(在最近这次大检修之前,如果设置allowNetworking=all,会导致好几种可以绕过allowScriptAccess=none的做法,例如,可以通过getURL(...)方式调用javascript:URL格式的JavaScript。但这种场景里所有脚本形式的URL地址都已被放到黑名单里了。)
       
        AllowFullScreen 参数 这个参数控制是否允许以全屏显示模式来执行Flash程序。可以设置的值为true和false,默认值为false。如前面说过的那样,如果允许全屏执行Flash程序,会导致UI界面欺骗的风险;所以除非确实有此必要,否则应该禁用此功能。
       
        b. Security.allowDomain(...)
       
        设置了Security.allowDomain(...),将允许任意JavaScript代码或非同源的Hash程序访问当前Flash程序的变量和函数。所以出手前务必考虑清楚:一旦允许了这种访问,就再没有可靠的方法能确保原Flash执行环境的完整性了。所以做这个决定一定要慎而重之,任何贸贸然使用allowDomaiW"*")的做法,通常都会受到严厉的惩罚。
       
        值得注意的是,另外还有一个命名颇为古怪的allowInsecureDomain(...)方法。但这个方法的存在可并不意味着allowDomain(...)方法就是安全的;这里的"insecure"含义是要兼容2003年以前的古老语义,因为那时还不区分HTTP/HTTPS呢。
       
        c. 跨域策略文件
       
        通过使用loadPolicyFile(...),Flash程序可以从几乎任意URL获取设置自己的运行环境的安全策略文这种XML文件通常名叫crossdomain.xml,通过检查这个策略文件URL里设定的跨域权限设定,可以获知服务器级别的跨域许可。这个策略文件的语法基本上一目了然,形式上类似这样:
       
[mw_shl_code=javascript,true]        <cross-domain-policy>
                <allow-access-from domain="foo.example.com"/>
                <allow-http-request-headers-from domain="*.example.com"
                        headers="X-Some-Header" />
        </cross-domain-policy>[/mw_shl_code]
       
        这个策略文件允许在浏览器的HTTP堆栈里,加载跨域的资源或在发送任意URLRequest时附加一些以白名单方式许可的请求头。Flash开发者们也在尝试实现某种程度上的路径隔离:原则上,放在特定子目录的策略文件就只对该路径下的文件有效。然而在实际使用中,由于涉及与同源策略的交互,还有浏览器和Web应用框架之间的各种路径映射机制,都使得完全依赖于这个边界并不靠谱。
       
        注意:Flash还可以通过XMLSocket发送原生TCP连接,这也需要通过XML格式的策略文件进行控制,在经过2008年的那次大检修之后,XMLSocket需要先与目标服务器的 TCP 843 端口建立连接,取回专用于XMLSocket的策略文件。这个机制已经相当安全了,因为这个端口上不会运行其他常用服务,在许多操作系统里也只有特权用户才可以在低于1024的端口绑定服务。但由于和某些网络防火墙上的机制可能有冲突,如FTP协议的帮助程序,这种设计还是可能会带来一些网络级别的干扰,当然这个话题已经远远超出这里的范围了。
       
        可以预想得到,配置得不合理的crossdomain.xml策略肯定会带来安全风险。特别是,不应该把没有十足把握的域名规则设置为allow-access-from。更进一步来说,如果把这个参数的值赋为"*",就差不多等于执行了document.domain="com"。这个,完全就是自寻死路了。
       
        d.策略文件假冒风险
       
        除了有可能出现配置错误之外,另一个安全风险是Adobe的安全模型策略使得由用户控制的随机文档也可能会被当作跨域策略文件来解析,这就与站点管理员的本意相违了。
       
        2008年以前Flash用的策略解析器是众所周知地不严密,它在用loadPolicyFile(...)处理策略文件时,会略过文件开头部分的垃圾信息,直接去找文件里的<cross-domain-policy>标签。在下载文件资源时,它还会忽略服务器返回的MIMEType信息。结果就是,只要放一个用户提供的有效JPEG图片就有可能产生重大的安全风险。另外那时候的Flash插件还会忽略HTTP重定向,所以即使只是简单地用HTTP重定向到某个不受控的地址,也可能蕴含危险性(这本该是无害的行为)。
       
        loadPolicyFile里这些有问题的处理显然亟待修复,在那次大检修之后确实纠正了许多错误,尽管还有某些默认处理仍然不够完美。一方面,现在的重定向处理较符合常识了,而加载的文件也必须是符合规范的XML文档。另一方面,现在允许的MIME类型包括text/*、application/xml和application/xhtml+xml,范围还是有点太宽泛。text/piain或text/csv也可能会误被当作策略文件解析,而实际上不应如此。
       
        谢天谢地,为消解问题,Adobe的工程师推出了元策略(meta policies)的机制,通过在根目录下的(/crossdomain.xml)文档里,预先定义好各种兀策略,这样就不会被攻击者再改写掉。在这个文件里设置的元策略,就能在全站范围内,限制由攻击者提供的URL所加载的其他策略文件的设定。这些限制里最重要的一项是<site-control permitted-cross-domain-policies="..."这个参数如果设置为master-only,会令插件直接忽略其他的子策略文件。另一个较为宽松的值是by-content-type,则只有策略文件的Content-Type响应头被设置为text/x-cross-domain-policy时,才能加载这个策略文件。
       
        不管怎么说,非常推荐在元策略里使用这两项指令。

#f192:
       
        5.2. Microsoft Silverlight

        我们的主题一下从Flash变到Silverlight貌似有点跳跃,因为两者非常容易混淆。Silverlight插件以极大的热忱照搬了很多Flash的特点;实际上可以很有把握地说,两者的安全模型只是在命名上略有差异而已。微软平台使用的同源确定方式,只是把allowScriptAccess替换为enableHtmlAccess,把crossdomain.xml换成略有差异的clientaccesspolicy.xml,提供System.Net.Sockets API而不是XMLSocket,在Flash用URLRequest的地方Silverlight则用HttpWebRequest——Silverlight做的就是把客厅里花花草草重新摆一道,把窗帘换一下。
       
        两者真是惊人地相似,甚至在HttpWebRequestAPI的禁用请求头列表里,还包括在Adobe规范里规定的X-Flash-Version。两者的高度一致不是问题,然而:如果有一个全新的安全模型实际上反而会更好些。.另外还要表扬一下微软,他们颇作了一些令人欣喜的改进,包括放弃不安全的allowDomain逻辑,并采用RegisterScriptableObject,这样只有明确设定的回调才会暴露给第三方的域。

#f192:
       
        5.3. Java
       
        Sun的Java(属于Oracle了)是个很有意思的例子。Java作为插件已经完全被弃用了,在过去10多年里,其安全架构也未得到认真的审视。然而,因为Java庞大的安装率,很难对它视而不见地就此不管。
       
        不幸的是,对Java研究得越深入,越能体会到它已经和现在的Web架构很不兼容了。例如,可以通过java.net.HttpURLConnection类向Java小程序的原属站点发送携带身份验证信息的HTTP请求,但按照java.net.URL.equals(...)里的安全检查,这个"原属站点"指的是特定IP地址上的所有网站。所以这个模型实际上完全抹杀了HTTP/1.1协议里的虚拟主机隔离——而这个隔离也是同源策略、HTTPCookie和现在各种主流浏览器安全机制的根基。
       
        沿着这个线路再往前看,在Java小程序里可以使用java.net.URLConnection这个类发送任意请求头,包括Host,而另一个类Socket则可以向Java小程序的原属服务器任意端口发送不受限制的TCP连接。现在的浏览器和其他常用插件对此类行为都是大摇其头的。
       
        Java小程序对同源是没有概念的,它通过所在页面里设置<applet>、<embed>和<object>标签的mayscript属性,来控制是否允许以JSObject机制与其所在的页面进行交互。Java小程序的文档里说这是一项安全措施呢:
       
        出于安全的考虑,Java插件默认不支持JSObject。要启用在Java插件里对JSObject的支持,需要在EMBED/OBJECT标签里,加入一项新的MAYSCRIPT属性。
       
        不幸的是,文档里没提到另一个密切相关的机制DOMSen/ice其实会忽略这个设置,使Java小程序能获得对其所在页面几乎完全不受限制的访问权限。尽管Firefox和Opera不支持DOMService,但其他的浏览器都支持,这使得加载第三方Java内容就相当于给它赋予了所在页面的全部权限。
       
        这可真够呛啊!#t247:
       
        注意有意思的是,Java在最新版本里,也幵始支持Flash里的crossdomain.xml机制了。

#f192:
       
        6. 如何处理格式含糊或意想不到的源信息
       
        对基础安全策略和知情同意隔离机制的讨论到这里就要收尾了。如果说还有什么需要再提一下的,当然就是这些机制几乎都依赖于符合规范的正式主机名,在此基础上才能构建后续操作所依赖的执行环境。但假如连这个信息都缺乏,或者格式与标准形式完全不同,那么又会怎样呢?
       
        这时候事情变得有意思了。让我们来看一下这些极端的情况吧,这里只为博各位小伙伴一笑。
       
        6.1. IP地址
       
        由于在设计HTTP Cookie和同源策略时并没有把IP地址考虑进去,所以几乎所有的浏览器在过去某个时期都曾经允许来自

        http://1.2.3.4/ 的页面对"域名"为*.3.4的站点设置Cookie。对document.domain的设置也与此同理。实际上,这些行为在较老的IE浏览器里仍然存在。
       
        这个行为对主流的Web应用应该不会有影响,因为这种应用一般不会通过IP形式的URL来访问,所以一般就直接无法执行了。但对许多其他系统来说,特别是给技术人员使用的系统,往往都是用IP地址访问的;这些系统可能就压根没有DNS配置。在这种情况下,http://1.2.3.4/ 可以对 http://123.234.3.4/ 进行Cookie注人就是个问题了。很多使用IP地址作为管理入口的家用路由器也可能会有此风险。
       
        6.2. 主机名里有额外的点号
       
        说到底,Cookie设置的算法仍然依赖于计算URL里点号的数量,来确定能否接受一个特定的域名参数。为了能作出正确的判断,这种计算通常都要关联一个由开发商维护的公共后缀列表,内有几百项记录( http://publicsuffix.org/ )。
       
        不幸的是,对这种算法来说,主机名里再加个额外的点号其实也仍能正常解析。有多余点号的非标准主机名通常是在操作系统级别进行解析的,但这种做法往往会把浏览器给搞糊涂。尽管浏览器不会自动把www.example.com.pl.(后面多了一个点号)完全等同于真正的域名www.example.com.pl,但即使是注意力非常集中的用户,也不会留意到URL里这一微小的看上去也不会有什么问题的差异。
       
        但在这种情况下,和最后带点号的URL交互可能会不安全,对那些和*.Com.pl.域名进行交互的页面来说,Cookie跨站注入会变得更容易。
       
        点号计算的问题在1998年首次被发现。在经过大概10年之后,许多浏览器开发商都在相关的代码里对这种情况作了特殊处理,已基本消除此问题.
       
        6.3. 不完整的主机名
       
        许多用户在浏览网站时往往并不知道,他们的DNS解析会对所有发现的主机名称,都自动地添加一个本地后缀名。这种配置往往由于ISP的网络接人强制,或在公司里使用自动网络配置(动态主机名配置协议,Dynamic Host Configuration Protocol,DHCP)所导致的。       
       
        对在这种环境里浏览网站的用户来说,DNS标签的解析可能会有歧义。如果DNS的搜索路径(searchpath)包含coredump.cx,那么www.example.com既有可能被解析到真正的[url]www.example.com[/url]站点,也有可能会被解析到www.example.com.coredump.cx,如果正好存在这条DNS记录。这个结果一部分取决于配置的设定,但某种程度上来说,攻击者也可以进行一定的干预。
       
        对浏览器来说,两个地址看起来是一样的,这可能引发某些有趣的副作用。考虑一下这个特别变态的例子:http://com 如果真的被解析到http://com.coredump.cx/ ,那么浏览器到底是否可以罔顾Cookie里的domain参数,把Cookie范围设置为*.com呢?
       
        6.4. 本地文件
       
        因为本地资源是通过file:协议加载的,并没有一个明显的主机名与之关联,浏览器也就不能按正常的方式来进行同源比较。很长时间以来,浏览器开发商们认为最好的方式就是在这种场景里放弃同源策略。

        因此,任何保存在磁盘上的HTML文件都自动地享有通过XMLHttpRequest或DOM访问任意其他本地文件的权限,更隐蔽的是,这种文件甚至照样可以访问任何来自互联网的内容。
       
        这种设计显然非常糟糕。没有人愿意看到仅仅因为下载了一个HTML文件,就可能导致用户的所有本地文件甚至在线身份信息都受到危害。因为通过Web方式访问同样的文件却是绝对安全的,所以这个漏洞实在令人难以接受。
       
        最近几年很多浏览器都在陆续弥补这个漏洞,当然各家达成的实际效果也不太一样:
       
        Chrome (扩展来说,也包括其他WebKit内核的浏览器)Chrome浏览器完全禁用file:源的跨文档DOM或XMLHttpRequest访问,并且Chrome还会忽略file:源的文档对document.cookie的调用或在页面里的<meta http-equiv="Set-Cookie"...>设置。目前Chrome还允许所有本地file:文件共享一个localStorage容器,但这条可能很快也会被改掉。
       
        Firefox Mozilla 浏览器 只允许file:源的文档访问位于同目录下的本地文件,以及直接的下一层子目录里的文件。这个策略还挺不错的,但对存放在此目录和之前下载到这个目录的文件来说,还是具有一定的风险。通过document.cookie能访问到Cookie,也可以在页面里通过<metahttp-equiv="Set-Cookie"...>方式设置Cookie,而所有file:源的Cookie对其他的本地JavaScript代码也都是可见的e。对本地存储localStorage的机制也是一样。
       
        Internet Explorer 7 和之后的版本 来自file:的源对本地和互联网内容都有完全不受限的访问,但需要用户先点击一个表达得很含糊的警告提示,明确允许本地JavaScript的执行。选择允许执行的后果也并没有说得很清楚(IE的帮助系统只有一些令人费解的信息,如"IE浏览器限制这些内容的访问,因为这些程序可能运行不正常,返回您不需要的内容",所以很多用户在这些提示的引导下都会糊里糊涂地选择了允许运行脚本。

        IE浏览器的Cookie用法和Hrefox类似。然而这些本地源的文件都不支持本地Web存储。
       
        Opera和Internet Explorer 6 这些浏览器都允许完全不受限制的DOM或XMLHttpRequest功能,不会进一步做更多检查。也允许file:的Cookie作为一个整体被访问到。
       
        注意:在file:的场景里,插件们有各ft独立的工作模式:例如Flash会使用local-with-filesystem的沙箱模式,无视浏览器本身的策略设定,Flash的这个模式对本地文件系统的访问几乎完全没有限制,而执行本地文件系统的Java或者Windows Presentation Framework插件程序,那就几乎和运行不可信的二进制执行文件相去无几了。


#f193:

        6.5. 伪URL
       
        伪URL如about:、data:和javascript:以前都会对同源策略带来重大的漏洞。因为所有这类URL都会被认为是同源的,所以通过同一种策略加载的任何资源,都有完全的跨域访问权限。但现在的处理就非常不同了,这将会是下一章的内容;简单来说,现在的状况是若干次匆匆忙忙的修补改进结果,每种浏览器的表现也各自不同,是比同源继承规则更为复杂的混合状态。
       
        6.6. 浏览器扩展和用户界面
       
        部分浏览器允许以提权的方式运行某些由JavaScript创建的UI界面元素或用户安装的某些浏览器扩展。这些特权可能会绕过相关的同源检查,或者在写文件、修改配置时调用到通常不对外开放的API。
       
        特权JavaScript是Firefox里一项突出的特征,用于和XUL—起创建大部分的浏览器用户界面Chrome对JavaScript的依赖程度虽然较低但也不少。
       
        同源策略对具有特权的执行环境并没有什么特殊的处理。这些额外的权限包括可以加载一些常规情况下不能访问到的特殊URL策略,如chrome:或res:,然后在浏览器其他部分的代码里可以再对这些策略做额外的特殊处理。另一种做法是不管实际的源是什么,一律对特权JavaScript的执行环境先设置一个二进制格式的标签,并在其后再检查是否有这个标签。

        但在这些情况下,标准API如localStorage、document.domain和document.cookie的行为就变得很难以预测了,所以不能把希望寄托在以上这些处理上:某些浏览器确实希望实现不同扩展之间的内容隔离,但大部分浏览器都不会这么做。
       
        注意:在开发浏览器扩展时,与任何非特权运行环境里的内容打交道时都需要非常小心。因为很难检查不受信任的执行环境,如果其中有eval(...)或innerHMTL,就很有可能打通连接特权运行环境的通道。

#f175:
       
        9.7. 源的其他应用
       
        浏览器级别的内容隔离说到这里就结束了。要注意的是,源的概念或基于Host或域名的安全机制并不仅仅限于内容隔离,实际上在浏览器的世界里处处都有它们的身影。其他各种准同源隐私和安全特性,包括与每个站点对应Cookie处理相关的配置选项和缓存信息,弹出窗口的拦截,地理位置的共享,密码管理,数码相机和麦克风访问(在Flash里),以及其他无数的功能。这些特性都与本章的内容有一定程度的关联;我们很快还会再继续探讨一些细节问题。


上一篇
下一篇
小执念乐于助人,奖励 1 个 金币.


巴黎环抱的花海 「龙战于野」 2017-8-31 17:38 来自手机 |显示全部楼层

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

众里寻他千百度,蓦然回首在这里!
故事,还未完、 「锋芒初露」 2018-4-30 20:59 |显示全部楼层

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

小白一个 顶一下
那一缕微光 「龙战于野」 2018-5-3 22:37 来自手机 |显示全部楼层

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

我只是路过,不发表意见……
您需要登录后才可以回帖 登录 | 免费注册  

本版积分规则

关于本站|大事记|小黑屋|古黑论 网站统计

GMT+8, 2021-7-24 00:02 , Processed in 0.039413 second(s), 20 queries , Redis On.

© 2015-2021 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表