COOP、COEP 与 CORP 跨源隔离
COOP、COEP、CORP 三个响应头协作建立 cross-origin isolated 环境,隔离跨源窗口、控制资源加载授权。
#type / concept
#status / evergreen
#tech / security
#resource / http
#platform / browser
[!info] related notes
- 所属 MOC: security-moc
- 总览: http-response-headers
- 前置概念: 跨域, same-origin
- 并列安全头: CSP, HSTS, x-frame-options, referrer-policy, permissions-policy
COOP、COEP 与 CORP 跨源隔离
一句话定义
- COOP(Cross-Origin-Opener-Policy):控制跨源窗口之间的隔离关系
- COEP(Cross-Origin-Embedder-Policy):要求页面加载的跨源资源必须明确授权
- CORP(Cross-Origin-Resource-Policy):资源自己声明”谁可以跨源加载我”
三者协作可以建立 cross-origin isolated 环境,这是使用 SharedArrayBuffer、performance.measureUserAgentSpecificMemory() 等高敏感能力的前提。
为什么需要跨源隔离
Spectre 漏洞让浏览器意识到:同一进程中的跨源资源可能被恶意代码通过侧信道攻击读取。解决方案是:
- 让页面明确声明”我不和跨源窗口共享浏览上下文”(COOP)
- 让页面明确声明”我加载的跨源资源都必须授权”(COEP)
- 让资源自己声明”谁可以加载我”(CORP)
三者配合后,浏览器可以把页面放进一个隔离的进程中运行。
Cross-Origin-Opener-Policy (COOP)
Cross-Origin-Opener-Policy: same-origin
效果
设了 same-origin 后:
- 通过
window.open打开的跨源页面不会获得对你的window.opener引用 - 你也不会获得对它的引用
- 两个窗口在不同的浏览上下文组中
值
| 值 | 效果 |
|---|---|
unsafe-none | 默认值,不做隔离 |
same-origin | 同源窗口共享浏览上下文,跨源隔离 |
same-origin-allow-popups | 同源窗口共享,且允许弹出窗口保持关联 |
对 SharedArrayBuffer 的影响
Chrome 从 2021 年起要求页面处于 cross-origin isolated 状态才能使用 SharedArrayBuffer。COOP + COEP 是建立这个状态的必要条件。
Cross-Origin-Embedder-Policy (COEP)
Cross-Origin-Embedder-Policy: require-corp
效果
设了 require-corp 后:
- 页面加载的所有跨源资源都必须携带 CORP 头或通过 CORS 显式授权
- 没有授权的跨源资源会被阻止加载
值
| 值 | 效果 |
|---|---|
unsafe-none | 默认值,不做限制 |
require-corp | 所有跨源资源必须有 CORP 或 CORS 授权 |
credentialless | 跨源请求不带凭证,响应需 CORP 或 no-cors 加载 |
常见问题
设了 require-corp 后,CDN 上的图片、字体、脚本如果没有 CORP 头,会加载失败。解决方案:
- 让 CDN 资源返回
Cross-Origin-Resource-Policy: cross-origin - 或者用
<img crossorigin>等属性走 CORS - 或者用
credentialless替代require-corp(宽松一些)
Cross-Origin-Resource-Policy (CORP)
Cross-Origin-Resource-Policy: same-origin
效果
资源自己声明谁可以加载它。浏览器在加载跨源资源时会检查这个头。
值
| 值 | 效果 |
|---|---|
same-origin | 只有同源页面可以加载 |
same-site | 同站页面可以加载(包括不同子域) |
cross-origin | 任何页面都可以加载(显式授权跨源) |
适用资源类型
图片、脚本、字体、样式、媒体等静态资源。特别适合防止其他站点”偷用”你的图片或字体。
最小场景
CDN 上的图片需要被跨源页面使用:
# CDN 图片响应
Cross-Origin-Resource-Policy: cross-origin
或者配合 CORS:
<img src="https://cdn.example.com/photo.jpg" crossorigin>
建立 cross-origin isolated 环境
要让页面处于 cross-origin isolated 状态(可以使用 SharedArrayBuffer 等),需要:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
两者的配合效果:
COOP: same-origin
→ 你的窗口和跨源窗口隔离
→ 浏览器可以把你的页面放进独立进程
COEP: require-corp
→ 你加载的所有跨源资源都经过授权
→ 浏览器确认没有未授权的跨源数据在同一进程中
两者缺一不可。只有 COOP 没有 COEP,浏览器无法确认跨源资源的安全性;只有 COEP 没有 COOP,窗口关联仍然存在。
检查是否成功
console.log(window.crossOriginIsolated);
// true → 已建立跨源隔离
// false → 未建立
边界与易混淆点
- COOP 不等于 CSP 的 frame-ancestors:COOP 控制的是窗口关联(opener),frame-ancestors 控制的是 iframe 嵌入。
- COEP 会让没有 CORP 头的跨源资源加载失败:这是迁移 COEP 时最常见的坑,需要逐一检查所有跨源资源。
- CORP 不是 CORS 的替代品:CORP 是资源端声明,CORS 是服务器响应授权。两者可以同时使用。
- cross-origin isolated 状态有性能影响:COOP 会断开窗口关联,某些跨窗口通信场景(如 OAuth 弹窗回调)需要额外处理。
credentialless是require-corp的宽松替代:Chrome 引入,跨源请求不带凭证,降低 COEP 的迁移成本。