為何需要 ";跨來源隔離" 以享有強大的功能

瞭解為何需要跨來源隔離,才能使用 SharedArrayBufferperformance.measureUserAgentSpecificMemory() 和高解析度計時器等強大功能,並提升精確度。

簡介

在「使用 COOP 和 COEP 將網站設為『跨來源隔離』」一文中,我們說明瞭如何使用 COOP 和 COEP 採用「跨來源隔離」狀態。這是一篇輔助文章,說明為何啟用瀏覽器的強大功能時,需要跨來源隔離。

背景

網路是建構在同源政策的基礎上,這項安全功能會限制文件和指令碼與其他來源資源的互動方式。這項原則會限制網站存取跨來源資源的方式。舉例來說,系統會禁止 https://a.example 的文件存取 https://b.example 代管的資料。

不過,相同來源政策過去曾有例外情況。任何網站都可以:

  • 嵌入跨來源 iframe
  • 包含圖片或指令碼等跨來源資源
  • 使用 DOM 參照開啟跨來源彈出式視窗

如果網頁是從頭設計,就不會有這些例外狀況。 很遺憾,當網路社群意識到嚴格同源政策的主要優點時,網路已開始依賴這些例外狀況。

我們透過兩種方式修補了這類寬鬆同源政策造成的安全性副作用。其中一種方式是導入名為跨源資源共享 (CORS) 的新通訊協定,確保伺服器允許與特定來源共用資源。另一種方法是隱含移除對跨源資源的直接指令碼存取權,同時保留回溯相容性。這類跨來源資源稱為「不透明」資源。舉例來說,除非對圖片套用 CORS,否則透過 CanvasRenderingContext2D 操控跨來源圖片的像素會失敗。

所有這些政策決策都是在瀏覽環境群組中進行。

瀏覽情境群組

長期以來,CORS 和不透明資源的組合足以確保瀏覽器安全。有時會發現極端情況 (例如 JSON 安全漏洞),需要修補,但整體而言,不允許直接讀取跨來源資源原始位元組的原則是成功的。

但隨著 Spectre 的出現,這一切都改變了,因為 Spectre 可能會讀取載入至與程式碼相同瀏覽環境群組的任何資料。藉由測量特定作業所需的時間,攻擊者可以猜測 CPU 快取的內容,進而猜測程序記憶體的內容。這類時間攻擊可透過平台中的低精細度計時器發動,但高精細度計時器 (包括明確 (如 performance.now()) 和隱含 (如 SharedArrayBuffers) 計時器) 可加快攻擊速度。如果 evil.com 嵌入跨來源圖片,他們可以使用 Spectre 攻擊讀取圖片的像素資料,導致依賴「不透明度」的防護措施失效。

Spectr

理想情況下,所有跨來源要求都應由擁有資源的伺服器明確審查。如果資源擁有伺服器未提供審查,資料就永遠不會進入惡意行為者的瀏覽內容群組,因此網頁執行的任何 Spectre 攻擊都無法存取資料。我們稱之為「跨來源隔離狀態」。這正是 COOP+COEP 的重點。

在跨來源隔離狀態下,要求網站被視為較不危險,因此可解鎖強大的功能,例如 SharedArrayBufferperformance.measureUserAgentSpecificMemory()高解析度計時器,這些功能具有更高的精確度,否則可能會用於類似 Spectre 的攻擊。此外,這項做法也能防止修改 document.domain

跨來源嵌入程式政策

跨來源嵌入者政策 (COEP) 可防止文件載入任何未明確授予文件權限 (使用 CORP 或 CORS) 的跨來源資源。這項功能可讓您聲明文件無法載入這類資源。

COEP 的運作方式

如要啟用這項政策,請在文件中附加下列 HTTP 標頭:

Cross-Origin-Embedder-Policy: require-corp

COEP 採用單一值 require-corp。這項政策會強制規定文件只能從相同來源載入資源,或明確標示為可從其他來源載入的資源。

如要從其他來源載入資源,資源必須支援跨源資源共享 (CORS) 或跨源資源政策 (CORP)。

跨源資源共享

如果跨來源資源支援跨來源資源共用 (CORS),您可以使用 crossorigin 屬性將資源載入網頁,而不會遭到 COEP 封鎖。

<img src="https://third-party.example.com/image.jpg" crossorigin>

舉例來說,如果這個圖片資源是透過 CORS 標頭放送,請使用 crossorigin 屬性,這樣擷取資源的要求就會使用 CORS 模式。這也會防止圖片載入,除非圖片設定了 CORS 標頭。

同樣地,您也可以透過 fetch() 方法擷取跨來源資料,只要伺服器回應正確的 HTTP 標頭,就不需要特殊處理。

跨來源資源政策

跨源資源政策 (CORP) 最初是做為選用功能推出,可保護資源不被其他來源載入。在 COEP 的脈絡中,CORP 可指定資源擁有者的政策,決定誰可以載入資源。

Cross-Origin-Resource-Policy 標頭可使用以下三個值:

Cross-Origin-Resource-Policy: same-site

標示 same-site 的資源只能從相同網站載入。

Cross-Origin-Resource-Policy: same-origin

標示 same-origin 的資源只能從相同來源載入。

Cross-Origin-Resource-Policy: cross-origin

標示為 cross-origin 的資源可由任何網站載入。(這個值已與 COEP 一併新增至 CORP 規格)。

跨來源開啟器政策

跨來源開啟者政策 (COOP) 可將頂層視窗與其他文件放在不同的瀏覽內容群組中,確保兩者彼此隔離,因此其他文件無法直接與頂層視窗互動。舉例來說,如果含有 COOP 的文件開啟彈出式視窗,其 window.opener 屬性會是 null。此外,開啟者對該視窗的參照的 .closed 屬性會傳回 true

COOP

Cross-Origin-Opener-Policy 標頭可使用以下三個值:

Cross-Origin-Opener-Policy: same-origin

標示 same-origin 的文件可以與同樣明確標示 same-origin 的同源文件共用相同的瀏覽環境群組。

COOP

Cross-Origin-Opener-Policy: same-origin-allow-popups

如果頂層文件含有 same-origin-allow-popups,且其中任何彈出式視窗未設定 COOP,或透過設定 unsafe-none 的 COOP 選擇不隔離,則頂層文件會保留對這些彈出式視窗的參照。

COOP

Cross-Origin-Opener-Policy: unsafe-none

unsafe-none 是預設值,除非開啟者本身的 COOP 為 same-origin,否則允許將文件新增至開啟者的瀏覽內容群組。

摘要

如要確保能存取 SharedArrayBufferperformance.measureUserAgentSpecificMemory()高解析度計時器等強大功能,請務必在文件中使用 COEP (值為 require-corp) 和 COOP (值為 same-origin)。如果缺少其中一項,瀏覽器就無法保證有足夠的隔離效果,安全啟用這些強大功能。您可以檢查 self.crossOriginIsolated 是否會傳回 true,判斷網頁的狀況。

如要瞭解實作步驟,請參閱「使用 COOP 和 COEP 將網站設為『跨來源獨立』」。

資源