Android Chrome 88 和電腦版 Chrome 92 中的 SharedArrayBuffer 更新

我們可以說 SharedArrayBuffer 在網路上的推出狀況不太理想,但目前情況已趨於穩定。以下是一些注意事項:

簡介

  • SharedArrayBuffer 目前支援 Firefox 79 以上版本,並會在 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-PolicyCross-Origin-Opener-Policy 而失敗的要求相關資料。

如果您認為無法在 Chrome 92 推出前完成這些變更,可以註冊原點測試,保留目前的 Chrome 電腦版行為,至少到 Chrome 113 為止。

如要進一步瞭解跨來源隔離功能,請參閱本頁底部的「參考資料」一節。

防禦者為何會陷入困境?

SharedArrayBuffer 在 Chrome 60 中推出 (如果您以日期而非 Chrome 版本來思考時間,那就是 2017 年 7 月),一切都運作良好。為期 6 個月。

2018 年 1 月,我們發現部分熱門 CPU 存在安全漏洞。詳情請參閱公告,但這基本上表示程式碼可以使用高解析度計時器,讀取不應存取的記憶體。

這對瀏覽器供應商來說是個問題,因為我們希望允許網站以 JavaScript 和 WASM 的形式執行程式碼,但嚴格控管此程式碼可存取的記憶體。如果你造訪我的網站,我應該無法讀取你同時開啟的網路銀行網站內容。事實上,我甚至不應該知道你已開啟網路銀行網站。這些是網路安全的基本概念。

為減輕這項影響,我們降低了 performance.now() 等高解析度計時器的解析度。不過,您可以使用 SharedArrayBuffer create高解析度計時器,方法是修改 worker 中緊密迴圈中的記憶體,然後在另一個執行緒中讀取記憶體。如要有效緩解此問題,就必須大幅影響善意程式碼,因此 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-PolicyCORS 選擇嵌入內容。

Firefox 在 79 版 (2020 年 7 月) 中率先推出含有這項限制的 SharedArrayBuffer

然後,我在 2021 年 1 月撰寫了這篇文章,您也閱讀了這篇文章。你好!

而這就是我們目前的情況。Chrome 88 會將 SharedArrayBuffer 帶回 Android 的跨來源隔離頁面,而 Chrome 92 則會將相同的規定帶入電腦,以便達到一致性並實現完整的跨來源隔離。

延後 Chrome 桌機版的變更

這是以「來源測試」形式提供的暫時例外狀況,可讓使用者有更多時間實作跨來源隔離的網頁。這項功能可啟用 SharedArrayBuffer,而不需要將網頁隔離為跨來源。這個例外狀況會在 Chrome 113 中到期,且僅適用於 Chrome 桌面版。

  1. 為來源要求權杖
  2. 將權杖加入網頁。您可以透過以下兩種方式完成:
    • 在每個網頁的標頭中加入 origin-trial <meta> 標記。例如:
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • 如果您能設定伺服器,也可以使用 Origin-Trial HTTP 標頭新增這個符記。產生的回應標頭應如下所示:
      Origin-Trial: TOKEN_GOES_HERE

延伸閱讀

橫幅相片來源:Daniel GregoireUnsplash 上提供