使用 Origin-Agent-Cluster 標頭進行效能隔離

新的 HTTP 回應標頭可限制全網域指令碼,並要求瀏覽器提供專屬資源。

Domenic Denicola
Domenic Denicola

Origin-Agent-Cluster 是新的 HTTP 回應標頭,可指示瀏覽器防止在相同網站跨來源網頁之間使用同步指令碼存取。瀏覽器也可能會使用 Origin-Agent-Cluster 做為提示,來源應取得專屬的獨立資源,例如專用程序。

瀏覽器相容性

目前 Origin-Agent-Cluster 標頭只能在 Chrome 88 以上版本中實作。這個版本與 Mozilla Firefox 的代表密切合作設計,後者將這項技術標示為價值原型,並來自 Safari 瀏覽器引擎 WebKit 代表的初步正面評價

但在此期間,您可以為所有使用者部署 Origin-Agent-Cluster 標頭。無法理解它的瀏覽器只會忽略它。此外,由於 origin-keyed 代理程式叢集中的頁面,實際執行的項目「較少」,比 Site-keyed 代理程式 (預設值) 還少,因此不會需要擔心互通性問題。

為什麼瀏覽器無法自動隔離同網站來源

網路是根據同來源政策建構而成,這項安全性功能會限製文件和指令碼與其他來源的資源互動方式。舉例來說,由 https://a.example 代管的網頁與 https://b.example 的某個來源不同,或另一個位於 https://sub.a.example 的網頁。

瀏覽器在幕後採用來源提供的區隔方式有所不同。在過去一天內,即使不同的來源無法存取彼此的資料,仍會共用作業系統執行緒、程序和記憶體分配等資源。這表示如有單一分頁的速度過慢,就會拖慢所有其他分頁的速度。或者,如果某個分頁使用過多記憶體 就會導致整個瀏覽器當機

現今的瀏覽器較為複雜,並且嘗試將不同的來源分成不同的程序。確切運作方式因瀏覽器而異:多數瀏覽器在分頁之間有一定程度的區隔,但單一分頁中的不同 iframe 則可能共用處理程序。此外,程序會耗用些許記憶體負擔,因此會利用經驗法則,避免產生過多的記憶體:例如 Firefox 設有可由使用者設定的程序限制,而 Chrome 在電腦 (記憶體較多) 和行動裝置 (儲存空間不多) 之間的行為會有所不同。

這些經驗法則並非完美。而且存在一項重要限制:因為相同來源政策允許 https://sub.a.examplehttps://a.example 等子網域互相通訊的例外狀況,因此瀏覽器無法自動隔離子網域。

這個預設行為稱為「site-keyed 代理程式叢集」,亦即瀏覽器會根據其「網站」將頁面分組。新的 Origin-Agent-Cluster 標頭會要求瀏覽器變更特定頁面的預設行為,將其放入 origin-keyed 代理程式叢集,這樣就只會與來源相同的其他頁面組成群組。特別是,代理程式叢集會將相同網站的跨來源網頁排除。

有了這項選擇區隔功能,瀏覽器就能為這些新的 origin-keyed 代理程式叢集提供專屬的專屬資源,而不會與其他來源的資源合併。舉例來說,這類頁面可以有自己的程序,或是在不同的執行緒上排程。在網頁中加入 Origin-Agent-Cluster 標頭後,瀏覽器就能知道網頁能善用這類專屬資源。

然而,為了做出區隔並享受這些優勢,瀏覽器必須停用部分舊版功能。

來源輸入頁面不可執行的功能

當您的網頁位於 origin-keyed 代理程式叢集時,您可以賦予與之前可用的同網站跨來源網頁通訊的功能。請特別注意以下幾點:

  • 您無法再設定 document.domain,這是一項舊版功能,通常允許同網站跨來源頁面同步存取彼此的 DOM,但在 origin-keyed 代理程式叢集中會停用。

  • 您無法再透過 postMessage()WebAssembly.Module 物件傳送至其他同網站跨來源頁面。

  • (僅限 Chrome) 無法再傳送 SharedArrayBufferWebAssembly.Memory 物件到其他同網站跨來源頁面。

使用 origin-keyed 代理程式叢集的時機

下列來源最能受惠於 Origin-Agent-Cluster 標頭:

  • 如果情況允許,請盡可能使用專屬資源取得最佳效能。例如需要耗用大量效能的遊戲、視訊會議網站,或多媒體創作應用程式。

  • 包含來源不同但來源不同,且資源密集型 iframe。舉例來說,如果 https://mail.example.com 嵌入 https://chat.example.com iframe,來源鍵鍵 https://mail.example.com/ 可確保即時通訊團隊撰寫的程式碼不會意外幹擾到郵件團隊撰寫的程式碼,還能提示瀏覽器為這些程式碼提供個別的程序,以便獨立排程,並降低對彼此的效能影響。

  • 預期能夠嵌入到不同來源的相同網站頁面,但知道本身需要大量資源。舉例來說,如果 https://customerservicewidget.example.com 預期會使用許多資源進行視訊通訊,並且會在整個 https://*.example.com 中的各種來源嵌入,那麼維護該小工具的團隊可以使用 Origin-Agent-Cluster 標頭,嘗試降低對嵌入器的效能影響。

此外,您也必須確認可以停用上述不常使用的跨來源通訊功能,且您的網站使用 HTTPS

但最後,這些只是規範。無論 origin-keyed 代理程式叢集是否有助於網站改善網站,最終還是無法根據測量結果做出最佳判斷。您尤其需要評估網站體驗指標以及記憶體用量,瞭解來源鍵功能的影響。(記憶體用量尤其重要,因為增加處理中的程序數量會增加每個程序的記憶體負擔)。請不要只推出來源鍵功能,並希望一切順利。

這與跨來源隔離有何關係?

透過 Origin-Agent-Cluster 標頭執行的代理程式叢集的來源金鑰與透過 Cross-Origin-Opener-PolicyCross-Origin-Embedder-Policy 標頭進行跨來源隔離相關,但兩者並不相同。

針對本身進行跨來源隔離的網站,也會停用與使用 Origin-Agent-Cluster 標頭時相同的同網站跨來源通訊功能。不過,除了跨來源隔離之外,Origin-Agent-Cluster 標頭仍可做為額外提示,方便瀏覽器修改資源分配經驗法則。因此,您還是建議您套用 Origin-Agent-Cluster 標頭並評估結果,即使頁面已隔離跨來源網頁也一樣。

如何使用 Origin-Agent-Cluster 標頭

如要使用 Origin-Agent-Cluster 標頭,請將網路伺服器設為傳送下列 HTTP 回應標頭:

Origin-Agent-Cluster: ?1

?1 的值是布林值 true 值的結構化標頭語法。

請務必針對來自來源的「所有」回應傳送這個標頭,而不只是部分網頁。 否則,您可能會取得不一致的結果,此時瀏覽器會「記住」來源鍵要求,因此甚至在未要求請求的頁面中,也會「記錄」來源鍵。反之:如果使用者造訪的第一頁沒有標頭,瀏覽器就會記住來源不想使用 origin-key,並忽略後續頁面的標頭。

為什麼瀏覽器無法一直採用標頭?

之所以顯示這個「記憶體」,是為了確保來源的索引鍵一致性。如果來源中有部分網頁是以 origin-key 輸入,其他則沒有,則您可以將兩個相同來源網頁放入不同的代理程式叢集,因而不允許彼此通訊。無論是網頁程式開發人員或瀏覽器內部,這個問題都會相當奇怪。因此,如果標頭與先前針對特定來源顯示的內容不一致,Origin-Agent-Cluster 的規格會改為忽略該標頭。而在 Chrome 中,則會收到控制台警告。

這項一致性的範圍適用於瀏覽結構定義群組,這個群組是指一組分頁、視窗或 iframe,而且全都可透過 window.openerframes[0]window.parent 等機制互相存取。這表示在設定來源或網站鍵設定之後 (瀏覽器查看或不顯示標頭後),如要進行變更,就必須開啟全新的分頁,而非以任何方式連線至舊分頁。

測試 Origin-Agent-Cluster 標頭時,這些詳細資料非常重要。首次將網頁新增至網站時,只重新載入網頁是沒有作用的。你必須關閉分頁,然後開啟新的分頁。

如要檢查是否套用 Origin-Agent-Cluster 標頭,請使用 JavaScript window.originAgentCluster 屬性。如果標頭 (或其他機制,例如跨來源隔離) 觸發來源鍵功能,這就會是 true;如果不是,則為 false;如果瀏覽器未實作 Origin-Agent-Cluster 標頭,則會是 undefined。將這些資料記錄到數據分析平台後,即可進行有價值的檢查,確認伺服器設定正確。

最後請注意,Origin-Agent-Cluster 標頭僅適用於安全內容,也就是在 HTTPS 網頁或 http://localhost 上。非 localhost 的 HTTP 網頁「不」支援 origin-keyed 代理程式叢集。

來源金鑰並非安全防護功能

使用 origin-keyed 代理程式叢集會將來源與同網站跨來源頁面的同步存取隔離,並不會提供Cross-Origin-Resource-PolicyCross-Origin-Opener-Policy 等安全性相關標頭的保護。尤其是像 Spectre 這類側邊頻道攻擊,並非絕對可靠的防護。

這聽起來有點令人意外,因為來源鍵有時可能會導致來源取得自己的程序,而獨立的程序是抵禦旁路攻擊的重要關鍵。但請注意,Origin-Agent-Cluster 標頭只是相關提示。瀏覽器沒有義務向來源提供獨立程序,且基於各種原因而可能不會進行此程序:

  • 瀏覽器可能不會實作這方面的技術。例如,目前 Safari 和 Firefox 可以將不同的分頁放入各自的程序,但目前還無法針對 iframe 這麼做。

  • 瀏覽器可能會判定並非值得另外執行程序的負擔。舉例來說,在低記憶體 Android 裝置或 Android WebView 中,Chrome 使用的程序會盡可能少。

  • 瀏覽器可能會想遵循 Origin-Agent-Cluster 標頭指出的要求,但可以使用與程序不同的隔離技術來達成這個目的。例如,Chrome 正在探索使用執行緒,而不是使用執行緒進行這類效能隔離的作業。

  • 使用者或執行於其他網站的程式碼,可能已前往來源上的網站輸入頁面頁面,導致一致性保證生效,並完全忽略 Origin-Agent-Cluster 標頭。

因此,請勿將 origin-keyed 代理程式叢集視為安全防護功能。相反地,這種方法可讓瀏覽器透過一種方式,協助瀏覽器優先分配資源,方法是指出來源可善用專屬資源 (而且您願意放棄交換特定功能)。

意見回饋:

如果您使用或考慮使用 Origin-Agent-Cluster 標頭,Chrome 團隊都很樂意傾聽您的心聲。您的公眾興趣與支援可協助我們優先開發各項功能,並向其他瀏覽器供應商說明這些功能的重要性。在 @ChromiumDev 推文,讓 Chrome DevRel 分享您的想法和經驗。

如果您對規格或功能運作方式有其他疑問,可以在 HTML 標準 GitHub 存放區中回報問題。如果您在實作 Chrome 時遇到任何問題,請前往 new.crbug.com 回報錯誤,並將「元件」欄位設為 Internals>Sandbox>SiteIsolation

瞭解詳情

如要進一步瞭解 origin-keyed 代理程式叢集,請點選下列連結來瞭解詳情: