瞭解為何需要跨來源隔離,才能使用 SharedArrayBuffer
、performance.measureUserAgentSpecificMemory()
和高解析度計時器等強大功能,並提升精確度。
簡介
在「使用 COOP 和 COEP 將網站設為『跨來源隔離』」一文中,我們說明瞭如何使用 COOP 和 COEP 採用「跨來源隔離」狀態。這是一篇輔助文章,說明為何啟用瀏覽器的強大功能時,需要跨來源隔離。
背景
網路是建構在同源政策的基礎上,這項安全功能會限制文件和指令碼與其他來源資源的互動方式。這項原則會限制網站存取跨來源資源的方式。舉例來說,系統會禁止 https://a.example
的文件存取 https://b.example
代管的資料。
不過,相同來源政策過去曾有例外情況。任何網站都可以:
- 嵌入跨來源 iframe
- 包含圖片或指令碼等跨來源資源
- 使用 DOM 參照開啟跨來源彈出式視窗
如果網頁是從頭設計,就不會有這些例外狀況。 很遺憾,當網路社群意識到嚴格同源政策的主要優點時,網路已開始依賴這些例外狀況。
我們透過兩種方式修補了這類寬鬆同源政策造成的安全性副作用。其中一種方式是導入名為跨源資源共享 (CORS) 的新通訊協定,確保伺服器允許與特定來源共用資源。另一種方法是隱含移除對跨源資源的直接指令碼存取權,同時保留回溯相容性。這類跨來源資源稱為「不透明」資源。舉例來說,除非對圖片套用 CORS,否則透過 CanvasRenderingContext2D
操控跨來源圖片的像素會失敗。
所有這些政策決策都是在瀏覽環境群組中進行。
長期以來,CORS 和不透明資源的組合足以確保瀏覽器安全。有時會發現極端情況 (例如 JSON 安全漏洞),需要修補,但整體而言,不允許直接讀取跨來源資源原始位元組的原則是成功的。
但隨著 Spectre 的出現,這一切都改變了,因為 Spectre 可能會讀取載入至與程式碼相同瀏覽環境群組的任何資料。藉由測量特定作業所需的時間,攻擊者可以猜測 CPU 快取的內容,進而猜測程序記憶體的內容。這類時間攻擊可透過平台中的低精細度計時器發動,但高精細度計時器 (包括明確 (如 performance.now()
) 和隱含 (如 SharedArrayBuffer
s) 計時器) 可加快攻擊速度。如果 evil.com
嵌入跨來源圖片,他們可以使用 Spectre 攻擊讀取圖片的像素資料,導致依賴「不透明度」的防護措施失效。
理想情況下,所有跨來源要求都應由擁有資源的伺服器明確審查。如果資源擁有伺服器未提供審查,資料就永遠不會進入惡意行為者的瀏覽內容群組,因此網頁執行的任何 Spectre 攻擊都無法存取資料。我們稱之為「跨來源隔離狀態」。這正是 COOP+COEP 的重點。
在跨來源隔離狀態下,要求網站被視為較不危險,因此可解鎖強大的功能,例如 SharedArrayBuffer
、performance.measureUserAgentSpecificMemory()
和高解析度計時器,這些功能具有更高的精確度,否則可能會用於類似 Spectre 的攻擊。此外,這項做法也能防止修改 document.domain
。
跨來源嵌入程式政策
跨來源嵌入者政策 (COEP) 可防止文件載入任何未明確授予文件權限 (使用 CORP 或 CORS) 的跨來源資源。這項功能可讓您聲明文件無法載入這類資源。
如要啟用這項政策,請在文件中附加下列 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
是預設值,除非開啟者本身的 COOP 為 same-origin
,否則允許將文件新增至開啟者的瀏覽內容群組。
摘要
如要確保能存取 SharedArrayBuffer
、performance.measureUserAgentSpecificMemory()
或高解析度計時器等強大功能,請務必在文件中使用 COEP (值為 require-corp
) 和 COOP (值為 same-origin
)。如果缺少其中一項,瀏覽器就無法保證有足夠的隔離效果,安全啟用這些強大功能。您可以檢查 self.crossOriginIsolated
是否會傳回 true
,判斷網頁的狀況。
如要瞭解實作步驟,請參閱「使用 COOP 和 COEP 將網站設為『跨來源獨立』」。