瞭解為何需要跨來源隔離才能使用 SharedArrayBuffer
、performance.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 的目的。
在跨來源隔離狀態下,要求網站會被視為較不危險,這可解鎖 SharedArrayBuffer
、performance.measureUserAgentSpecificMemory()
和高解析度計時器等功能,這些功能的精確度較高,否則可能會用於 Spectre 類型的攻擊。這也能防止修改 document.domain
。
跨來源嵌入程式政策
跨來源嵌入者政策 (COEP) 可防止文件載入未明確授予文件權限 (使用 CORP 或 CORS) 的任何跨來源資源。您可以使用這項功能宣告文件無法載入這類資源。
如要啟用這項政策,請在文件中附加下列 HTTP 標頭:
Cross-Origin-Embedder-Policy: require-corp
require-corp
關鍵字是 COEP 唯一接受的值。這項政策會強制執行文件只能載入相同來源的資源,或是明確標示為可從其他來源載入的資源。
如要從其他來源載入資源,資源必須支援跨來源資源共享 (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
,可讓文件新增至開啟者的瀏覽內容群組,除非開啟者本身的 COOP 為 same-origin
。
摘要
如果您想確保可使用 SharedArrayBuffer
、performance.measureUserAgentSpecificMemory()
或高解析度計時器等強大功能,且精確度更高,請記住,您的文件必須同時使用 COEP 和 COOP,且 COEP 的值為 require-corp
,COOP 的值為 same-origin
。如果沒有這兩項功能,瀏覽器就無法保證足夠的隔離功能,無法安全啟用這些強大的功能。您可以檢查 self.crossOriginIsolated
是否會傳回 true
,藉此判斷網頁的情況。
如要瞭解實作步驟,請參閱「使用 COOP 和 COEP 讓網站『跨來源隔離』」一文。