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

發布日期:2020 年 5 月 4 日

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

詞彙解釋

這份文件使用許多名稱相似且縮寫的術語。為求清楚明瞭,我們整理了迷你詞彙表:

背景

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

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

  • 嵌入跨來源 iframe
  • 加入圖片或指令碼等跨來源資源
  • 使用 DOM 參照開啟跨源對話方塊視窗

當網路社群意識到嚴格同源政策的好處時,網路已依賴這些例外狀況。

我們透過兩種方式,修補了寬鬆同源政策造成的安全性副作用:

  • 跨源資源共享 (CORS) 通訊協定可確保伺服器允許與特定來源共用資源。
  • 開發人員會隱含移除對跨源資源的直接指令碼存取權,同時保留回溯相容性。這類跨來源資源稱為「不透明」資源。因此,除非圖片套用 CORS,否則使用 CanvasRenderingContext2D 進行跨源像素操控會失敗。

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

瀏覽情境群組包含主要網站和內嵌網站的資產。

長期以來,這種組合足以確保瀏覽器安全,只有少數需要直接修補的極端情況 (例如 JSON 漏洞)。

這項行為在 Spectre 中有所改變,因為這項功能會讓載入至與程式碼相同瀏覽環境群組的任何資料,都有可能遭到讀取。攻擊者可以測量特定作業所需的時間,藉此猜測 CPU 快取的內容,進而得知程序記憶體的內容。這類攻擊可透過平台中的低精細度計時器發動,並可透過高精細度計時器加快速度,包括明確 (例如 performance.now()) 和隱含 (例如 SharedArrayBuffers) 計時器。

如果 evil.com 嵌入跨來源圖片,攻擊者就能使用 Spectre 攻擊讀取嵌入圖片的像素資料。這會導致依賴「不透明度」的保護措施失效。

Evil.com 是主要網站,會使用 Spectre 攻擊內嵌的 b.example iframe 和圖片。

理想情況下,所有跨源要求都會由擁有資源的伺服器審查。如果沒有執行審查,資料就不會傳送至惡意行為者的瀏覽環境群組。因此,資料不會受到可能的 Spectre 攻擊。這就是所謂的「已跨來源隔離狀態」

如果內嵌程式碼處於跨來源隔離狀態,要求網站的危險程度就會降低。這可讓要求網站使用 SharedArrayBufferperformance.measureUserAgentSpecificMemory()高解析度計時器,且精確度更高,同時防範可能的 Spectre 攻擊。這個狀態也會禁止修改 document.domain

跨來源嵌入程式政策

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

這張圖表顯示哪些內嵌資產因 CORS 政策而允許或禁止。
父項網站 a.example會將 COEP 政策設為 require-corpa.example 想要從 b.example 嵌入 3 項資產,但只有 2 項成功。這兩個成功嵌入的項目包括具有跨源 CORP 政策的 JavaScript 檔案,以及允許 CORS 的圖片。第三個素材資源是影片,但該影片的 CORP 政策規定素材資源只能內嵌在同源網站,因此影片不會載入 a.example

如要啟用這項政策,請在文件中附加下列 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

a.example 無法在對話方塊中開啟 b.example。

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,或透過將 COOP 設為 unsafe-none 選擇不隔離,則頂層文件會保留對這些彈出式視窗的參照。

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 將網站設為『跨來源獨立』」。

資源