可組合性是 Web 的非常強大的一項能力,你可以輕而易舉的加載來自不同來源的資源來增強網頁的功能,例如:font、image、video
等等。
這些服務非常強大,也很方便,但是這樣的策略同樣會加大信息泄漏的風險,攻擊者可以利用某些手段泄漏你的用戶信息。
瀏覽器在阻止這些攻擊上做的也很好。同源策略我們已經很熟悉了,它用於限制不同源的站點的資源訪問。詳細可以戳瀏覽器的同源策略,這里不再過多介紹。
但是同源策略也有一些例外,任何網站都可以不受限制的加載下面的資源:
- 嵌入跨域
iframe
image、script
等資源- 使用 DOM 打開跨域彈出窗口
對於這些資源,瀏覽器可以將各個站點的跨域資源分隔在不同的 Context Group
下,不同的 Context Group
下資源無法相互訪問。
瀏覽器 Context Group
是一組共享相同上下文的 tab、window或iframe。例如,如果網站(https://a.example
)打開彈出窗口(https://b.example
),則打開器窗口和彈出窗口共享相同的瀏覽上下文,並且它們可以通過 DOM API
相互訪問,例如 window.opener
。
Spectre 漏洞
長久以來,這些安全策略一直保護着網站的隱私數據,直到 Spectre
漏洞出現。
Spectre
是一個在 CPU
中被發現的漏洞,利用 Spectre
,攻擊者可以讀取到在統一瀏覽器下任意 Context Group
下的資源。
特別是在使用一些需要和計算機硬件進行交互的 API
時:
SharedArrayBuffer (required for WebAssembly Threads)
performance.measureMemory()
JS Self-Profiling API
為此,瀏覽器一度禁用了 SharedArrayBuffer
等高風險的 API
。
跨域隔離
為了能夠使用這些強大的功能,並且保證我們的網站資源更加安全,我們需要為瀏覽器創建一個跨域隔離環境。
下文會提到很多專有術語,我們先把所有跨域相關的名詞列出來,以防后面搞混:
COEP: Cross Origin Embedder Policy
:跨源嵌入程序策略COOP: Cross Origin Opener Policy
:跨源開放者政策CORP: Cross Origin Resource Policy
:跨源資源策略CORS: Cross Origin Resource Sharing
:跨源資源共享CORB: Cross Origin Read Blocking
:跨源讀取阻止
我們可以通過 COOP、COEP
來創建隔離環境。
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
下面我們來看一下,這兩個 Hedaer
的意義,以及如何進行配置。
COOP:Cross Origin Resource Policy
COOP:跨源開放者政策,對應的 HTTP Header
是 Cross-Origin-Opener-Policy
。
通過將 COOP
設置為 Cross-Origin-Opener-Policy: same-origin
,將把從該網站打開的其他不同源的窗口隔離在不同的瀏覽器 Context Group
,這樣就創建的資源的隔離環境。
例如,如果帶有 COOP
的網站打開一個新的跨域彈出頁面,則其 window.opener
屬性將為 null
。
除了 same-origin
、 COOP
還有另外兩個不同的值:
Cross-Origin-Opener-Policy: same-origin-allow-popups
帶有 same-origin-allow-popups
的頂級頁面會保留一些彈出窗口的引用,這些彈出窗口要么沒有設置 COOP
,要么通過將 COOP
設置為 unsafe-none
來選擇脫離隔離。
Cross-Origin-Opener-Policy: unsafe-none
unsafe-none
是默認設置,允許當前頁面和彈出頁面共享 Context Group
。
CORP、CORS
要啟用跨域隔離,你還首先需要明確所有跨域資源明確被允許加載。這有兩種實現方式,一種是CORP
,另一種是 CORS
。
CORS
(跨域資源共享)在我么日常解決跨域問題時經常會使用,這個我們已經非常熟悉了,我們再來看看 CORP
:
Cross-Origin-Resource-Policy: same-site
標記 same-site
的資源只能從同一站點加載。
Cross-Origin-Resource-Policy: same-origin
標記 same-origin
的資源只能從相同的來源加載。
Cross-Origin-Resource-Policy: cross-origin
標記 cross-origin
的資源可以由任何網站加載。
注意,如果是一些通用的 CDN
資源,例如 image、font、video
、等,一定要設置成 cross-origin
,否則可能會導致資源無法被正常加載。
對於你無法控制的跨域資源,可以手動在 html 標簽中添加 crossorigin
屬性。
COEP:Cross Origin Embedder Policy
COOP:跨源嵌入程序政策,對應的 HTTP Header
是 Cross-Origin-Embedder -Policy
。
啟用 Cross-Origin-Embedder-Policy: require-corp
,你可以讓你的站點僅加載明確標記為可共享的跨域資源,也就是我們上面剛剛提到的配置,或者是同域資源。
如果沒有設置 Cross-Origin-Resource-Policy
將會被阻止加載。
在完全啟用 COEP
之前,可以通過使用 Cross-Origin-Embedder-Policy-Report-Only
檢查策略是否能夠正常運行。如果有不符合規范的資源,將不會被禁止加載,而是上報到你的服務器日志中。
測試跨域隔離是否正常
當你的 COOP、COEP
都配置完成之后,現在你的站點應該處於跨域隔離狀態了,你可以通過使用 self.crossOriginIsolated
來判斷隔離狀態是否正常。
if(self.crossOriginIsolated){ // 跨域隔離成功 }
現在就可以愉快的使用 haredArrayBuffer
, performance.measureMemory
或者 JS Self-Profiling API
這些強大的 API 了~