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

瞭解為何需要使用跨來源隔離功能,才能運用準確度更高的 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 攻擊讀取其像素資料,導致依賴「不透明」的保護措施無法發揮作用。

光譜

在理想情況下,所有跨來源要求都應該由擁有資源的伺服器明確審查。如果受資源控管的伺服器未提供審查,資料便永遠不會進入邪惡執行者的瀏覽情境群組,因此受限於網頁可能執行的任何 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

哥倫比亞

Cross-Origin-Opener-Policy 標頭接受三個可能的值:

Cross-Origin-Opener-Policy: same-origin

標示為 same-origin 的文件,可與明確標示為 same-origin 的相同來源文件共用相同的瀏覽結構定義群組。

哥倫比亞

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

具有 same-origin-allow-popups 的頂層文件會保留對任何彈出式視窗的參照,原因是未設定 COOP 或藉由設定 unsafe-none 的 COOP 來選擇不採用隔離狀態。

哥倫比亞

Cross-Origin-Opener-Policy: unsafe-none

unsafe-none 是預設值,可允許將文件新增至其開啟者的瀏覽環境群組,除非開啟者本身俱有 same-origin 的 COOP。

摘要

如要保證可以使用更精準的 SharedArrayBufferperformance.measureUserAgentSpecificMemory()高解析度計時器等強大的功能,請注意文件需要同時使用 require-corp 和 COOP 值為 same-origin 的 COEP。不管採用哪一種做法,瀏覽器都無法保證能夠安全啟用這些強大的功能。您可以檢查 self.crossOriginIsolated 是否傳回 true,藉此判斷網頁的情況。

請參閱使用 COOP 和 COEP 讓網站「跨來源獨立」一文瞭解實作步驟。

資源