使用COOP、COEP为浏览器创建更安全的环境
一个正式上线的web网站,可以利用很多资源来丰富你的网站,通过web的可组合性,可以非常轻而易举的加载来自不同来源的资源来增强网页的功能:例如font
、image
、video
等等。
这些服务非常的强大,也很方便,但是这样的策略同样会加大信息泄露的风险,攻击者可以利用一些手段来泄露你的用户信息。
浏览器在阻止这些攻击上做的也很好。同源策略我们已经很熟悉了,它用于限制不同源的站点的资源访问。详细可以看浏览器的同源策略
但是,同源策略也有一些意外:任何的网站都可以不受限制的加载如下的资源:
- 嵌入跨域
iframe
image、script
等资源- 使用DOM打开跨域弹出窗口
对于这些资源,浏览器可以将各个站点的跨域资源分隔在不同的Context Group
,不同的Context Group
下资源无法相互访问
浏览器Context Group
是一组共享相同上下文的tab、Window、iframe。例如:如果网站https://a.example
打开https://b.example
,那么打开器窗口和弹出窗口共享相同的浏览器上下文,并且它们可以通过DOM API相互访问,例如:window.opener
。
Spectre漏洞
长久以来,以上的安全策略一直保护着网站的隐私数据,直到Spectre
漏洞的出现
Spectre
是一个在CPU
中被发现的漏洞,利用它,攻击者可以读取到统一浏览器下任意Context Group
下的资源。
特别是在使用一些需要与计算机交互的API时
ShareArrayBuffer(required for WebAssembly Threads)
performance.measureMemory()
JS Self-Profiling API
为此,浏览器一度禁用了这些高风险的API。
跨域隔离
为了能够使用这些强大的功能,并且保证我们的网站资源更加安全,我们需要为浏览器创建一个跨域隔离的环境
接下来有很多专业术语的使用,先把这些专业术语的词汇汇总在这里:
COEP: Cross Origin Embedder Policy
:跨源嵌入程序策略COOP: Cross Origin Opener Policy
:跨源开放者政策CORP: Cross Origin Resource Policy
:跨源资源策略CORS: Cross Origin Resource Sharing
:跨源资源共享CORB: Cross Origin Read Blocking
:跨源读取阻止
我们可以通过COOP
和COEP
来创建隔离环境
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
接下来我们来看看,这两个Header
的意义,以及如何进行配置。
COOP:Cross Origin Opener Policy
COOP:跨源开放者政策,对应的是HTTP Header
是Cross-Origin-Opener-Policy
通过将COOP
设置为Cross-Origin-Opener-Policy: same-origin
,将把从该网站打开的其他不同源的窗口隔离在不同的浏览器Context Group
,这样就创建的资源的隔离环境
例如,如果带有COOP
的网站打开一个新的跨域弹出页面,那么其window.opener
为null
除了same-origin
、COOP
还有另外两个不同的值:
Cross-Origin-Opener-Policy: same-origin-allow-popups
带有same-origin-allow-popups的顶级页面会保留一些弹出窗口的引用,这些弹出窗口要么没有设置COOP
,要么通过将COOP
设置为unsafe-none
来选择脱离隔离。
Cross-Origin-Opener-Policy: unsafe-none
unsafe-none
是默认设置,允许当前页面和弹出页面共享 Context Group
。
CORP、CORS
要启用跨域隔离,首先需要明确所有跨域资源明确被允许加载。这有两种方式,一种是CORP
,另一种是CORS
。
CORS
(跨域资源共享)在我们日常解决跨域问题的时候,经常会用到,非常熟悉了。来看看CORP
:
Cross-Origin-Resource-Policy: same-site
标记same-site
的资源只能从同一站点加载
Cross-Origin-Resource-Policy: same-origin
标记same-origin
的资源只能从相同的来源加载
Cross-Origin-Resource-Policy: cross-origin
标记cross-origin
的资源可以由任何网站加载
注意,如果是一些通用的 CDN
资源,例如 image
、font
、video
、等,一定要设置成cross-origin
,否则可能会导致资源无法被正常加载。
对于无法控制的跨域资源,可以手动在html标签中添加crossorigin
属性
COEP:Cross Origin Embedder Policy
COEP:跨源嵌入程序策略,对应的 HTTP Header
是 Cross-Origin-Embedder -Policy
。
启用Cross-Origin-Embedder-Policy: require-corp
,就可以让站点仅仅加载明确标记为可共享的跨域资源,也就是我们上面提到的配置,或者是同域资源。
比如说:上面的图片资源如果没有设置 Cross-Origin-Resource-Policy
将会被阻止加载。
在完全启用 COEP
之前,可以通过使用 Cross-Origin-Embedder-Policy-Report-Only
检查策略是否能够正常运行。如果有不符合规范的资源,将不会被禁止加载,而是上报到服务器日志中。
测试跨域隔离是否正常
当COOP
和COEP
都配置完成之后,现在站点应该处于跨域隔离状态,可以通过使用self.crossOriginIsolated
来判断隔离状态是否正常。
if (self.crossOriginIsolated) {
// 跨域隔离成功
}
搞定,现在可以自由的使用 haredArrayBuffer
, performance.measureMemory
或者 JS Self-Profiling API
这些强大的 API 了。