跨源读取阻止 (CORB),这是一种算法,通过该算法能够辨认可疑的跨源资源加载,并在它们达到网页之前被 Web 浏览器阻止。CORB 通过使敏感数据远离跨源网页来升高泄露敏感数据的危险。在大多数浏览器中,它将此类数据排除在不受信赖的脚本执行上下文之外。在具备 Site Isolation 的浏览器中,它能够将此类数据齐全排除在不受信赖的渲染器过程之外,甚至有助于抵挡边信道攻打。
问题
同源策略通常会阻止一个源从另一个源读取任意网络资源。在实践中,执行此策略并不像阻止所有跨源加载那么简略:必须为 Web 性能建设例外,例如 <img>
或<script>
因为历史起因能够针对跨源资源,以及容许某些资源的 CORS 机制有选择地跨源浏览。
然而,某些类型的内容可能被证实与所有历史上容许的宽容上下文不兼容。JSON 就是这样一种类型:JSON 响应在标记为指标时会导致解码谬误 <img>
,在标记为指标时会导致空操作或语法错误<script>
,等等。网页能够加载具备可察看后果的 JSON 的惟一状况是通过fetch()
或XMLHttpRequest
;在这些状况下,跨源读取由 CORS 调节。
通过尽早检测和阻止受 CORB 爱护的资源的加载——也就是说,在响应进入图像解码器或 JavaScript 解析器阶段之前——CORB 能够进攻可能呈现在被跳过的阶段中的侧信道破绽。
CORB 加重了哪些攻打?
CORB 缓解以下攻打起源:
-
跨站点脚本蕴含 (XSSI)
<script>
XSSI 是将标记指向非 JavaScript 的指标资源,并在将后果资源解释为 JavaScript 时察看一些副作用的技术。2006 年发现了这种攻打的一个晚期示例:通过笼罩 JavaScript Array 构造函数,JSON 列表的内容能够像以下一样简略地被拦挡:<script src="https://example.com/secret.json">
。尽管数组构造函数攻打向量在以后浏览器中失去修复,但在随后的十年中发现并修复了许多相似的破绽利用。例如,请参阅此处的幻灯片。- CORB 可避免此类攻打,因为受 CORB 爱护的资源将被阻止传送到跨站点
<script>
元素。 - CORB 在没有其余 XSSI 进攻(如 XSRF 令牌和 / 或 JSON 平安前缀)的存在也能够用作 CORB 算法的信号,表明资源应该受 CORB 爱护。
-
嗅探性旁道攻打(例如 Spectre)。
- 例如,攻击者可能会应用一个
<img src="https://example.com/secret.json">
元素将跨站点机密拉入攻击者运行 JavaScript 的过程中,而后应用揣测性侧通道攻打(例如 Spectre)来读取该机密。 - 当与站点隔离一起应用时,CORB 能够避免此类攻打,办法是避免 JSON 资源呈现在托管跨站点页面的过程的内存中。
- 例如,攻击者可能会应用一个
CORB 如何“阻止”响应?
当 CORB 决定响应须要受 CORB 爱护时,响应被批改如下:
- 响应主体替换为空主体。
- 响应标头已删除。
[lukasza@chromium.org] Chromium 目前保留了 Access-Control-* 标头(这有助于为 CORS 生成更好的谬误音讯)。
为了无效抵挡揣测性旁路攻打,CORB 阻塞必须在响应达到托管申请的跨域发起者的过程之前产生。换句话说,CORB 阻止应该避免受 CORB 爱护的响应数据呈现在托管跨源网站的过程的内存中(即便是临时的或短期的)。这与过滤响应(例如 CORS 过滤响应或不通明过滤响应)的概念不同,过滤响应仅提供对残缺数据的无限视图,这些数据依然存储在外部响应中,并且能够在渲染器过程中实现。
此处提供了 CORB 演示页面。
哪些申请合乎 CORB 容许的条件?
以下类型的申请是 CORB 豁免的:
- 导航申请或申请指标为“对象”或“嵌入”的申请。跨源
<iframe>
s、<object>
s 和<embed>
s 创立一个独自的平安上下文,因而泄露数据的危险较小。在大多数浏览器中,这种独自的上下文意味着歹意页面在推断内容时比将内容加载到本人的执行上下文中并察看副作用(例如,XSSI、款式标签等)更麻烦。在具备站点隔离性能的浏览器中,此平安上下文应用一个独自的过程,将数据齐全排除在歹意页面的地址空间之外。
[lukasza@chromium.org] TODO:弄清楚 Edge 的基于 VM 的隔离是如何工作的(例如,如果某些起源在特定渲染器中是禁区,那么这将大大增加 CORB 在 Edge 中的实用性)。
- 下载申请(例如发起者为“下载”的申请)。在这种状况下,来自响应的数据将保留到磁盘(而不是共享到跨源上下文),因而不会受害于 CORB 爱护。
[lukasza@chromium.org] AFAIK,在 Chrome 中,对下载申请的响应永远不会通过渲染器过程的内存。不确定在其余浏览器中是否如此。
所有其余类型的申请可能合乎 CORB 条件。这包含:
- XHR 和 fetch()
ping
,navigator.sendBeacon()
<link rel="prefetch" ...>
-
具备以下
申请目的地的
申请:
- “图像”申请,如
<img>
标签/favicon.ico
、SVG<image>
、CSSbackground-image
等。 - 相似脚本的目的地,如,
<script>
, , 等importScripts()
`navigator.serviceWorker.register()`audioWorklet.addModule()
- “音频”、“视频”或“曲目”
- “字体”
- “格调”
- “报告”申请,如 CSP 报告、NEL 报告等。
- “图像”申请,如
CORB 的根本思维是思考特定资源是否可能不适宜在下面列出的 每个 上下文中应用。如果每一种可能的应用都会导致 CORS 谬误、语法 / 解码谬误或没有可察看到的后果,CORB 应该可能阻止跨源加载而不扭转加载的可察看到的后果。在 CORB 之前,详细信息曾经被克制跨域谬误,以避免信息泄露。因而,此类谬误的可察看结果曾经是无限的,并且能够在阻塞时保留。
哪些类型的内容受 CORB 爱护?
如下所述,以下类型的内容受 CORB 爱护:
- JSON
- HTML
- XML
这些将在以下各节中别离探讨。
JSON
JSON 是网络上宽泛应用的数据格式;Web 平台内置了对 JSON 的反对。JSON 响应很可能蕴含值得爱护的用户数据。此外,与 HTML 或图像格式不同,没有容许跨源嵌入 JSON 资源的遗留 HTML 机制(即早于 CORS)。
因为 JSON 语法源自 JavaScript 并与之重叠,因而必须留神解决 JavaScript/JSON 多语言的可能性。CORB 为 JSON 解决以下状况:
- 非空 JSON 对象字面量:非空 JSON 对象(例如
{"key": "value"}
)。这正是 JSON 语法的子集,它是有效的 JavaScript 语法——第一个字符串文字后的冒号会产生语法错误。CORB 能够通过嗅探响应主体来爱护这些状况,即便标有不同的内容类型。 -
其余 JSON 文字:JSON 语法的其余子集(例如,
null
or[1, 2, "3"]
)也恰好是无效的 JavaScript 语法。特地是,当作为脚本进行评估时,它们是应该没有副作用的值表达式。因而,如果能够检测到它们,则能够对它们进行 CORB 爱护。此处的检测是可能的,但须要实现一个了解残缺 JSON 语法的验证器:- 如果响应未标有 JSON 内容类型,CORB 可能会通过将整个响应主体缓冲和验证为 JSON 来检测这些状况;必须思考整个响应,因为无效的、有副作用的 JavaScript 程序(如
[1, 2, "3"].map(...)
. - 如果响应的确标有 JSON 内容类型,CORB 可能会决定嗅探响应以确认它是无效的 JSON,但最多只能达到肯定数量的字节。这将防止在无限量的内存中进行缓冲和解析。
- 如果响应未标有 JSON 内容类型,CORB 可能会通过将整个响应主体缓冲和验证为 JSON 来检测这些状况;必须思考整个响应,因为无效的、有副作用的 JavaScript 程序(如
-
JSON served with an XSSI-defeating prefix:作为过来浏览器破绽的缓解措施,许多理论的网站和框架采纳一种约定,在其可获取的资源后面加上一个旨在强制 JavaScript 谬误的字符串。这些前缀在 CORB 之前尚未标准化,但有几种办法仿佛很广泛:
- 字符序列
)]}'
内置于 angular.js 框架和 Java Spring 框架中,并在 google.com 域中失去宽泛应用。 - 字符序列在历史上
{} &&
被内置到 Java Spring 框架中。 - 有限循环,例如
for(;;);
,在 facebook.com 域中被宽泛应用。
这些公认的 XSSI 进攻的存在是对 CORB 算法的强烈信号,表明资源应该受 CORB 爱护。因而,这些前缀简直在所有状况下都应触发 CORB 爱护,无论它们前面是什么。这被认为是平安的,因为:
- 如果 JSON 平安前缀呈现在以 JavaScript MIME 类型(例如
text/javascript
. - JSON 平安前缀不会与图像、视频或字体等二进制资源发生冲突(通常须要将前几个字节硬编码为特定序列——例如
FF D8 FF
图像 /jpeg)。 - 与样式表的抵触
text/css
在实践上是可能的,因为能够结构一个以 JSON security prefix 结尾的文件,但同时能够像样式表一样很好地解析。text/css
因而被确定为例外,只管这种状况的理论可能性仿佛很低。无关此类样式表的示例,请参见下文:
- 字符序列
)]} '
{}
h1 {色彩:红色;}
一些网络性能也应用 JSON。一个示例是 <link rel="manifest">
,其href
属性指定一个 JSON 清单文件。侥幸的是,当清单指定为跨源时,此机制须要 CORS,因而其 CORB 解决与利用于 fetch() 的规定雷同。
[nick@chromium.org] TODO:当解释为脚本时,是否有 JSON 无副作用的标准链接?
HTML
<iframe>
HTML 能够通过(如上所述)嵌入跨源,但除此之外,HTML 文档只能通过 fetch() 和 XHR 加载,这两者都须要 CORS。HTML 嗅探曾经广为人知,因而(与 JSON 不同)能够绝对容易地以高置信度辨认 HTML 资源。
已确定 CORB 须要激进解决的一种不置可否的多语言状况:HTML 款式的正文,它是 JavaScript 语法的一部分。
- CORB 在嗅探以确认 HTML 内容类型时跳过 HTML 正文块。这意味着(与失常的 HTML 嗅探不同)“
<!--
”字符串的存在不会立刻确认嗅探资源是 HTML 文档 – HTML 正文依然必须跟在无效的 HTML 标记之后。 - 此外,在 HTML 正文完结后,CORB 嗅探器将跳过所有字符,直到行终止字符。这有助于适应
SingleLineHTMLCloseComment
能够在“”字符 之后 应用的规定。SingleLineCommentChars
-->
在实在网站上应用的 html/javascript 多语言示例:
<!--/*--><html><body><script type="text/javascript"><!--//*/
var x = "This is both valid html and valid javascript";
//--></script></body></html>
<!-- comment --> <script type='text/javascript'>
//<![CDATA[
var x = "This is both valid html and valid javascript";
//]]>--></script>
XML
与 JSON 一样,XML 是一种宽泛应用的数据交换格局,并且与 HTML 一样,是一种内置于 Web 平台中的文档格局(特地是通过 XmlHttpRequest)。
通过嗅探确认 XML 内容类型比 JSON 或 HTML 更间接:XML 由 pattern 示意<?xml
,可能后面有空格。
惟一标识的须要 CORB 非凡解决的 XML 案例是image/svg+xml
,它是一种图像类型。所有其余 XML mime 类型都被视为受 CORB 爱护。
确定响应是否受 CORB 爱护
CORB 依据以下内容决定响应是否须要爱护(即响应是 JSON、HTML 还是 XML 资源):
-
如果响应蕴含响应标头,并且响应标头是以下之一
X-Content-Type-Options: nosniff
,则响应将受 CORB 爱护:Content-Type
- HTML MIME 类型
- XML MIME 类型(
image/svg+xml
如上所述是 CORB 豁免的除外) - JSON MIME 类型
text/plain
-
Content-Type
如果响应是 206 响应,并且响应的标头是以下之一,则该响应将受 CORB 爱护:- HTML MIME 类型
- XML MIME 类型(
image/svg+xml
如上所述是 CORB 豁免的除外) - JSON MIME 类型
-
否则,CORB 会尝试嗅探响应主体:
- 嗅探为 HTML 的 HTML MIME 类型受 CORB 爱护
image/svg+xml
嗅探为 XML 的 XML MIME 类型(除了)受 CORB 爱护- 嗅探为 JSON 的 JSON MIME 类型受 CORB 爱护
text/plain
嗅探为 JSON、HTML 或 XML 受 CORB 爱护text/css
任何以 JSON 平安前缀结尾的响应(除了)都受 CORB 爱护
嗅探是必要的,以防止阻止依赖于谬误标记的跨源响应(例如,作为图像text/html
)的现有网页。如果不进行嗅探,CORB 将阻止大概 16 倍的响应。
- CORB 将仅嗅探以 确认 基于标头的分类
Content-Type
(即,如果Content-Type
标头是text/json
,则 CORB 将嗅探 JSON 而不会嗅探 HTML 或 XML)。 - 如果某些语法元素在受 CORB 爱护和不受 CORB 爱护的 MIME 类型之间共享,那么这些元素必须被 CORB 嗅探疏忽。例如,当嗅探(受 CORB 爱护的)HTML 时,CORB 会疏忽并跳过 HTML 正文,因为它们也可能呈现在(不受 CORB 爱护的)JavaScript 中。这与在其余上下文中应用的 HTML 嗅探规定不同。
- 嗅探是一种尽力而为的启发式办法,为了获得最佳平安后果,咱们倡议 Web 开发人员 1) 应用正确的
Content-Type
标头标记响应和 2) 应用标头抉择退出嗅探X-Content-Type-Options: nosniff
。
[nick@chromium.org] 本节须要强有力的理由来阐明为什么 text/plain 失去这种非凡解释。现实状况下,显示 text/plain 的数据通常用于提供 HTML、JSON 或 XML。咱们以后实现中对 text/plain 的解决实际上可能是晚期原型的产物,它在规范 mime 嗅探之后运行,并且当响应省略 Content- 时,可能曾经看到“text/plain”MIME 类型被利用为默认 MIME 类型类型题目。
请留神,以上意味着以下响应不受 CORB 爱护:
- 标记为 的响应
multipart/*
。这防止了必须解析嵌套局部的内容类型。咱们倡议不反对对敏感文档的多局部范畴申请。 - 没有题目的响应
Content-Type
。 - 带有 JavaScript MIME 类型的响应,例如
text/javascript
. 这包含 JSONP(“带填充的 JSON”),它与 JSON 不同的是要在跨源上下文中读取和执行。
附录:CORB 和网络规范
Fetch 标准中的 CORB 局部涵盖了自 2018 年 5 月以来解决 nosniff
和 206 个响应。
CORB 确认嗅探尚未标准化。
CORB 的某些方面正在探讨中,并且可能会随着工夫的推移而倒退。
附录:CORB 实现状态
跟踪谬误:
- Chrome: https://crbug.com/268640 and https://crbug.com/802835 and https://www.chromestatus.com/feature/5629709824032768
- Edge: https://developer.microsoft.com/en-us/microsoft-edge/platform…
- Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1459357
- Safari/WebKit: https://bugs.webkit.org/show_bug.cgi?id=185331
Status of Web Platform Tests:
- Experimental builds
- Stable releases
参考
- Cross-Origin Read Blocking (CORB)
- Web 开发人员的跨域读阻塞