使用 COOP 和 COEP 設定跨來源隔離環境,並啟用 SharedArrayBuffer
、performance.measureUserAgentSpecificMemory()
和高解析度計時器等精確度更高的強大功能。
更新
- 2022 年 6 月 21 日:啟用跨來源隔離功能時,也需要注意 worker 指令碼。新增一些說明。
- 2021 年 8 月 5 日:JS Self-Profiling API 曾被提及為需要跨來源隔離的 API 之一,但考量近期的方向變更,我們已將其移除。
- 2021 年 5 月 6 日:根據意見回饋和回報的問題,我們決定調整在 Chrome M92 中限制非跨來源隔離網站使用
SharedArrayBuffer
的時間表。 - 2021 年 4 月 16 日:新增有關新版 COEP 無憑證模式和COPA 同源允許彈出式視窗的鬆散條件的說明,以便跨來源隔離。
- 2021 年 3 月 5 日:移除
SharedArrayBuffer
、performance.measureUserAgentSpecificMemory()
和偵錯功能的限制,這些功能現在已在 Chrome 89 中全面啟用。新增即將推出的功能performance.now()
和performance.timeOrigin
,可提供更高的精確度。 - 2021 年 2 月 19 日:新增有關功能政策
allow="cross-origin-isolated"
和開發人員工具偵錯功能的附註。 - 2020 年 10 月 15 日:
self.crossOriginIsolated
可在 Chrome 87 以上版本使用。 因此,當self.crossOriginIsolated
傳回true
時,document.domain
就會變得不可變動。performance.measureUserAgentSpecificMemory()
來源試用已結束,並預設在 Chrome 89 中啟用。自 Chrome 88 起,Android Chrome 上的共用陣列緩衝區將可供使用。
部分網路 API 會提高 Spectre 等側通道攻擊的風險。為降低這類風險,瀏覽器會提供稱為跨來源隔離的選擇加入式隔離環境。有了跨來源隔離狀態,網頁就能使用特權功能,包括:
API | 說明 |
---|---|
SharedArrayBuffer
|
這是 WebAssembly 執行緒的必要條件。這項功能可在 Android Chrome 88 以上版本使用。電腦版目前預設會透過 網站隔離功能啟用,但需要跨來源隔離狀態,且 在 Chrome 92 版中預設會停用。 |
performance.measureUserAgentSpecificMemory()
|
適用於 Chrome 89 以上版本。 |
performance.now() ,performance.timeOrigin
|
目前許多瀏覽器都支援這項功能,但解析度上限為 100 微秒。使用跨來源隔離功能時,解析度可達 5 微秒或更高。 |
跨來源隔離狀態也會防止修改 document.domain
。(能夠變更 document.domain
可讓同網站文件之間進行通訊,並被視為相同來源政策中的漏洞)。
如要啟用跨來源隔離狀態,您必須在主要文件中傳送下列 HTTP 標頭:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
這些標頭會指示瀏覽器封鎖未選擇由跨來源文件載入的資源或 iframe,並防止跨來源視窗直接與您的文件互動。這也表示跨來源載入的資源需要選擇加入。
您可以檢查 self.crossOriginIsolated
,判斷網頁是否處於跨來源隔離狀態。
本文將說明如何使用這些新標頭。在後續文章中,我會提供更多背景資訊和相關說明。
部署 COOP 和 COEP,讓網站隔離跨來源
整合 COOP 和 COEP
1. 在頂層文件中設定 Cross-Origin-Opener-Policy: same-origin
標頭
在頂層文件中啟用 COOP: same-origin
後,具有相同來源的視窗和從文件開啟的視窗,都會設有個別的瀏覽內容群組,除非這些視窗位於相同來源且具有相同的 COOP 設定。因此,系統會強制執行已開啟視窗的隔離作業,並停用兩個視窗之間的相互通訊。
瀏覽內容群組是一組可互相參照的視窗。例如,透過 <iframe>
嵌入的頂層文件及其子文件。如果網站 (https://a.example
) 開啟彈出式視窗 (https://b.example
),開啟者視窗和彈出式視窗會共用相同的瀏覽內容,因此可透過 window.opener
等 DOM API 相互存取。
您可以透過開發人員工具,查看視窗開啟者和其開啟者是否位於不同的瀏覽內容群組。
2. 確認資源已啟用 CORP 或 CORS
請確認網頁中的所有資源皆使用 CORP 或 CORS HTTP 標頭載入。這是第四步驟 (啟用 COEP)的必要步驟。
請根據資源的性質採取以下行動:
- 如果預期資源只從相同來源載入,請設定
Cross-Origin-Resource-Policy: same-origin
標頭。 - 如果資源只會從同一個網站載入,但跨來源,請設定
Cross-Origin-Resource-Policy: same-site
標頭。 - 如果資源是從您控管的跨來源載入,請盡可能設定
Cross-Origin-Resource-Policy: cross-origin
標頭。 - 針對您無法控制的跨來源資源:
- 如果資源是透過 CORS 提供,請在載入 HTML 標記中使用
crossorigin
屬性。例如<img src="***" crossorigin>
。 - 請資源擁有者支援 CORS 或 CORP。
- 如果資源是透過 CORS 提供,請在載入 HTML 標記中使用
- 針對 iframe,請遵循上述相同原則,並設定
Cross-Origin-Resource-Policy: cross-origin
(或same-site
、same-origin
,視情況而定)。 - 使用
WebWorker
載入的指令碼必須從相同來源提供,因此您不需要 CORP 或 CORS 標頭。 - 如果是透過
COEP: require-corp
提供的文件或 worker,未透過 CORS 載入的跨來源子資源必須設定Cross-Origin-Resource-Policy: cross-origin
標頭,才能選擇嵌入。例如,這適用於<script>
、importScripts
、<link>
、<video>
、<iframe>
等。
3. 使用 COEP Report-Only HTTP 標頭評估嵌入式資源
在完全啟用 COEP 之前,您可以使用 Cross-Origin-Embedder-Policy-Report-Only
標頭進行模擬測試,檢查政策是否確實運作。您會收到報表,但不會封鎖內嵌內容。
將此做法遞迴套用至「所有」文件,包括頂層文件、iframe 和 worker 指令碼。如要瞭解僅供報表使用的 HTTP 標頭,請參閱「使用報表 API 觀察問題」一文。
4. 啟用 COEP
確認一切運作正常,且所有資源都能順利載入後,請將 Cross-Origin-Embedder-Policy-Report-Only
標頭切換為 Cross-Origin-Embedder-Policy
標頭,並將相同值套用至所有文件,包括透過 iframe 和 worker 指令碼嵌入的文件。
使用 self.crossOriginIsolated
判斷隔離作業是否成功
如果網頁處於跨來源隔離狀態,且所有資源和視窗都在相同的瀏覽內容群組中隔離,self.crossOriginIsolated
資源就會傳回 true
。您可以使用這個 API 判斷是否已成功隔離瀏覽內容群組,並取得 performance.measureUserAgentSpecificMemory()
等強大功能的存取權。
使用 Chrome 開發人員工具偵錯
對於在畫面上算繪的資源 (例如圖片),您可以輕鬆偵測 COEP 問題,因為系統會封鎖要求,且網頁會指出缺少圖片。不過,如果資源並非一定會產生視覺影響 (例如指令碼或樣式),則可能會發生 COEP 問題而未被發現的情況。請使用開發人員工具「網路」面板。如果 COEP 有問題,您應該會在「狀態」欄中看到 (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep)
。
接著按一下項目即可查看詳細資料。
您也可以透過「Application」面板判斷 iframe 和彈出式視窗的狀態。前往左側的「Frames」部分,展開「top」,即可查看資源結構的細目。
您可以查看 iframe 的狀態,例如 SharedArrayBuffer
是否可用等。
您也可以查看彈出式視窗的狀態,例如是否隔離跨來源。
使用 Reporting API 觀察問題
Reporting API 是另一種可用來偵測各種問題的機制。您可以設定 Reporting API,在 COEP 阻止資源載入或 COOP 隔離彈出式視窗時,指示使用者的瀏覽器傳送報表。自 69 版起,Chrome 就支援 Reporting API,可用於各種用途,包括 COEP 和 COOP。
如要瞭解如何設定報表 API 並設定伺服器以接收報表,請參閱「使用報表 API」一文。
COEP 報告範例
跨來源資源遭到封鎖時,COEP 報告酬載的範例如下所示:
[{
"age": 25101,
"body": {
"blocked-url": "https://third-party-test.glitch.me/check.svg?",
"blockedURL": "https://third-party-test.glitch.me/check.svg?",
"destination": "image",
"disposition": "enforce",
"type": "corp"
},
"type": "coep",
"url": "https://cross-origin-isolation.glitch.me/?coep=require-corp&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4249.0 Safari/537.36"
}]
COOP 報表範例
在彈出式視窗開啟時,COOP 報告酬載的範例如下:
[{
"age": 7,
"body": {
"disposition": "enforce",
"effectivePolicy": "same-origin",
"nextResponseURL": "https://third-party-test.glitch.me/popup?report-only&coop=same-origin&",
"type": "navigation-from-response"
},
"type": "coop",
"url": "https://cross-origin-isolation.glitch.me/coop?coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]
當不同的瀏覽內容群組嘗試彼此存取 (僅限於「僅回報」模式) 時,COOP 也會傳送報表。舉例來說,嘗試 postMessage()
時的報表會像這樣:
[{
"age": 51785,
"body": {
"columnNumber": 18,
"disposition": "reporting",
"effectivePolicy": "same-origin",
"lineNumber": 83,
"property": "postMessage",
"sourceFile": "https://cross-origin-isolation.glitch.me/popup.js",
"type": "access-from-coop-page-to-openee"
},
"type": "coop",
"url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
},
{
"age": 51785,
"body": {
"disposition": "reporting",
"effectivePolicy": "same-origin",
"property": "postMessage",
"type": "access-to-coop-page-from-openee"
},
"type": "coop",
"url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]
結論
使用 COOP 和 COEP HTTP 標頭的組合,將網頁選為特殊的跨來源隔離狀態。您可以檢查 self.crossOriginIsolated
,判斷網頁是否處於跨來源隔離狀態。
我們會在這個跨來源隔離狀態推出新功能,並進一步改善 DevTools 的 COOP 和 COEP 時,持續更新這篇文章。