可以說 SharedArrayBuffer
在網路上推出時遇到了一些問題,但現在情況已趨於穩定。以下是一些注意事項:
簡介
- Firefox 79 以上版本目前支援
SharedArrayBuffer
,Android 版 Chrome 88 也將支援這項功能。不過,這項功能僅適用於已跨來源隔離的頁面。 SharedArrayBuffer
目前適用於電腦版 Chrome,但從 Chrome 92 開始,這項功能僅限於跨來源隔離頁面。如果您認為無法及時完成這項變更,可以註冊原始碼試用,至少在 Chrome 113 之前保留目前的行為。- 如果您打算啟用跨來源隔離,以繼續使用
SharedArrayBuffer
,請評估這項操作對網站上其他跨來源元素 (例如廣告刊登位置) 的影響。檢查是否有任何第三方資源使用SharedArrayBuffer
,瞭解影響和指引。
跨來源隔離總覽
您可以透過提供下列標頭,讓網頁跨來源獨立:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
完成這項操作後,除非資源透過 Cross-Origin-Resource-Policy
標頭或 CORS 標頭 (Access-Control-Allow-*
等) 明確允許,否則網頁將無法載入跨源內容。
此外,您也可以使用報表 API 收集因 Cross-Origin-Embedder-Policy
和 Cross-Origin-Opener-Policy
而失敗的要求資料。
如果您認為無法及時在 Chrome 92 版推出前完成這些變更,可以註冊原始碼試用,至少在 Chrome 113 版推出前,保留目前的電腦版 Chrome 行為。
如需跨來源隔離的更多指引和資訊,請參閱本頁底部的「延伸閱讀」一節。
防禦者為何會陷入困境?
SharedArrayBuffer
在 Chrome 60 中推出 (2017 年 7 月,如果您是以日期而非 Chrome 版本來計算時間),一切都很順利。為期 6 個月。
2018 年 1 月,我們發現部分熱門 CPU 存在安全漏洞。詳情請參閱公告,但基本上這表示程式碼可以使用高解析度計時器讀取不應存取的記憶體。
對我們這些瀏覽器供應商來說,這是一項問題,因為我們希望允許網站以 JavaScript 和 WASM 形式執行程式碼,但要嚴格控管這些程式碼可存取的記憶體。如果您來到我的網站,我應該無法讀取您同時開啟的網路銀行網站內容。事實上,我甚至不該知道你已開啟網路銀行網站。這些是網路安全的基本概念。
為解決這個問題,我們降低了高解析度計時器 (例如 performance.now()
) 的解析度。不過,您可以透過在工作站的緊密迴圈中修改記憶體,並在另一個執行緒中讀回記憶體,使用 SharedArrayBuffer
建立高解析度計時器。如果沒有對良性程式碼造成重大影響,就無法有效緩解這個問題,因此我們完全停用了 SharedArrayBuffer
。
一般來說,緩解方式是確保網頁的系統程序不包含來自其他位置的機密資料。Chrome 從一開始就投入多程序架構的開發 (還記得那則漫畫嗎?),但仍有來自多個網站的資料可能最終會進入同一程序的情況:
<iframe src="https://your-bank.example/balance.json"></iframe>
<script src="https://your-bank.example/balance.json"></script>
<link rel="stylesheet" href="https://your-bank.example/balance.json" />
<img src="https://your-bank.example/balance.json" />
<video src="https://your-bank.example/balance.json"></video>
<!-- …and more… -->
這些 API 具有「舊版」行為,允許使用其他來源的內容,無須其他來源選擇加入。這些要求是使用其他來源的 Cookie 提出,因此是完整的「已登入」要求。現在,新版 API 會要求其他來源使用 CORS 選擇加入。
我們透過防止內容進入網頁程序 (如果內容看起來「不正確」),解決了這些舊版 API 的問題,並將其稱為跨來源讀取封鎖。因此在上述情況中,我們不會允許 JSON 進入程序,因為 JSON 並非這些 API 的有效格式。也就是說,iframe 除外。如果是 iframe,我們會將內容放在不同的程序中。
完成這些緩解措施後,我們在 Chrome 68 (2018 年 7 月) 重新導入 SharedArrayBuffer
,但僅限於電腦版。由於行動裝置的程序要求較多,我們無法在行動裝置上執行相同操作。此外,Chrome 的解決方案並不完整,因為我們只封鎖「不正確」的資料格式,但可猜測的網址中可能含有有效的 CSS/JS/圖片,而這些內容可能包含私人資料 (雖然不常見)。
網路標準人員齊聚一堂,共同開發更完整的跨瀏覽器解決方案。解決方法是讓網頁聲明「我在此放棄將其他來源的內容帶入這個程序的能力,除非對方選擇加入」。這項聲明是透過網頁提供的 COOP 和 COEP 標頭完成。瀏覽器會強制執行這項操作,而網頁則可存取 SharedArrayBuffer
和其他類似的 API。其他來源可以透過 Cross-Origin-Resource-Policy
或 CORS 選擇加入內容嵌入。
Firefox 是第一個發布這項限制的瀏覽器,版本為 79 (2020 年 7 月)。SharedArrayBuffer
然後,我在 2021 年 1 月撰寫了這篇文章,而您讀了這篇文章。你好!
這就是我們現在的處境。Chrome 88 會在跨來源隔離的頁面上,將 SharedArrayBuffer
帶回 Android,而 Chrome 92 則會對電腦版提出相同要求,以確保一致性並實現完全的跨來源隔離。
延後 Desktop Chrome 變更
這是以「原始碼試用」形式提供的暫時例外狀況,可讓使用者有更多時間實作跨來源隔離頁面。啟用 SharedArrayBuffer
時,網頁不必跨來源隔離。這項例外情況會在 Chrome 113 中失效,且僅適用於電腦版 Chrome。
- 為來源要求權杖。
- 在網頁中加入權杖。有兩種做法:
- 在每個網頁的標頭中加入
origin-trial
<meta>
標記。舉例來說,這可能看起來像:
<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
- 如果可以設定伺服器,也可以使用
Origin-Trial
HTTP 標頭新增權杖。最終的回應標頭應如下所示:
Origin-Trial: TOKEN_GOES_HERE
- 在每個網頁的標頭中加入
延伸閱讀
橫幅相片來源:Daniel Gregoire 發表於 Unsplash 網站上