使用 COOP 和 COEP 建立網站 "跨來源隔離

使用 COOP 和 COEP 設定跨來源的隔離環境,並啟用 SharedArrayBufferperformance.measureUserAgentSpecificMemory() 和高解析度計時器等強大功能,準確度更高。

Eiji Kitamura
Eiji Kitamura

更新

  • 2022 年 6 月 21 日:啟用跨來源隔離時,工作站指令碼也需要留意。新增一些說明。
  • 2021 年 8 月 5 日:我們曾提及 JS Self-Profiling API,因為此 API 需要跨來源隔離,但是反映近期方向的變更,現已移除。
  • 2021 年 5 月 6 日:根據意見回饋和回報的問題,我們已決定針對沒有任何跨來源隔離網站在 Chrome M92 中限制使用 SharedArrayBuffer 的時間表。
  • 2021 年 4 月 16 日:新增有關無憑證模式的全新 COEP 無憑證模式COOP same-origin-allow-popups 是跨來源隔離的放鬆條件的附註。
  • 2021 年 3 月 5 日:移除 SharedArrayBufferperformance.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 標頭載入頁面中的所有資源。步驟 4:啟用 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。
  • 至於 iframe,請遵守上述原則,並依照上述原則設定 Cross-Origin-Resource-Policy: cross-origin (或 same-sitesame-origin視情境而定)。
  • 使用 WebWorker 載入的指令碼必須從相同來源提供,因此您不需要使用 CORP 或 CORS 標頭。
  • 針對使用 COEP: require-corp 提供的文件或工作站,在沒有 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 和工作站指令碼。如需報表專用 HTTP 標頭的相關資訊,請參閱「使用 Reporting API 觀察問題」。

4. 啟用 COEP

確認一切運作正常且所有資源都能順利載入後,請將 Cross-Origin-Embedder-Policy-Report-Only 標頭切換為 Cross-Origin-Embedder-Policy 標頭 (包括透過 iframe 和工作站指令碼嵌入的文件),以及具有相同值的 Cross-Origin-Embedder-Policy 標頭。

判斷是否成功透過 self.crossOriginIsolated 執行隔離

如果網頁處於跨來源的獨立狀態,且所有資源和視窗都屬於同一個瀏覽內容群組,self.crossOriginIsolated 屬性會傳回 true。您可以使用這個 API 判斷是否已成功區隔瀏覽結構定義群組,並取得 performance.measureUserAgentSpecificMemory() 等強大功能的存取權。

使用 Chrome 開發人員工具偵錯

如果資源 (例如圖片) 顯示於螢幕上,很容易偵測到 COEP 問題,因為要求將會遭到封鎖,而頁面也會指出缺少圖片。但是,對於那些不需要造成視覺影響的資源 (例如指令碼或樣式),COEP 問題可能會不易察覺。如果是這種情況,請使用開發人員工具網路面板。如果 COEP 發生問題,你應該會在「Status」欄中看到 (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep)

「網路」面板「狀態」欄中的 COEP 問題。

按一下該項目即可查看詳細資料。

在「網路」面板中點選網路資源後,「標頭」分頁就會顯示 COEP 問題的詳細資料。

您也可以透過「Application」(應用程式) 面板,判斷 iframe 和彈出式視窗的狀態。前往左側的「Frames」(頁框) 部分,展開「頂部」,查看資源結構的細目。

您可以檢查 iframe 的狀態,���如 SharedArrayBuffer 的可用性等。

Chrome 開發人員工具 iframe 檢查器

您也可以檢查彈出式視窗的狀態,例如是否為跨來源隔離。

Chrome 開發人員工具彈出式視窗檢查器

使用 Reporting API 觀察問題

Reporting API 是另一種可讓您偵測各種問題的機制。您可以設定 Reporting API,指示使用者的瀏覽器在每次 COEP 封鎖資源載入,或是 COOP 隔離彈出式視窗時傳送報表。Chrome 自 69 版起開始支援 Reporting API,適用於 COEP 和 COOP 等各種用途。

如要瞭解如何設定 Reporting API 及設定伺服器來接收報表,請參閱使用 Reporting 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,判斷網頁是否處於跨來源隔離狀態。

隨著這項跨來源隔離狀態推出新功能,我們也將持續更新本文,並針對 COOP 和 COEP 改善開發人員工具。

資源