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

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

在「使用 COOP 和 COEP 讓網站採用『跨來源隔離』狀態」一文中,我們說明瞭如何使用 COOP 和 COEP 採用「跨來源隔離」狀態。本文是相關文章,說明為何需要跨來源隔離,才能在瀏覽器中啟用強大功能。

背景

網路是建立在同源政策之上:這項安全性功能會限制文件和指令碼與其他來源的資源互動的情形。這項原則會限制網站存取跨來源資源的方式。舉例來說,https://a.example 中的文件無法存取 https://b.example 代管的資料。

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

  • 嵌入跨來源 iframe
  • 加入跨來源資源,例如圖片或指令碼
  • 使用 DOM 參照開啟跨來源彈出式視窗

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

我們以兩種方式修補這種鬆散的同源政策的安全性副作用。其中一種方式是引入名為「跨來源資源共享 (CORS)」的新通訊協定,目的是確保伺服器允許與特定來源共用資源。另一種方法是隱含地移除跨來源資源的直接指令碼存取權,同時保留向後相容性。這類跨來源資源稱為「不透明」資源。舉例來說,如果未將 CORS 套用至圖片,透過 CanvasRenderingContext2D 操控跨來源圖片的像素就會失敗。

所有政策決策都是在瀏覽內容群組中做出。

瀏覽情境群組

長久以來,只要結合 CORS 和不透明資源,就能確保瀏覽器安全無虞。有時會發現邊緣案例 (例如 JSON 安全漏洞),需要進行修補,但整體而言,我們不允許直接讀取跨來源資源的原始位元組的做法已成功。

這一切都隨著 Spectre 而改變,讓任何載入至與程式碼相同瀏覽內容群組的資料都可能可讀。攻擊者可以測量特定作業所需的時間,進而猜測 CPU 快取的內容,並透過這些內容猜測程序記憶體的內容。這類時間攻擊可能會使用平台中低精細度的計時器,但可以透過高精細度的計時器加快速度,包括明確的 (例如 performance.now()) 和隱含的 (例如 SharedArrayBuffer) 計時器。如果 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 讓網站『跨來源隔離』」一文。

資源