Chrome 停用了 document.domain 的修改功能

如果您的網站需要設定 document.domain,則必須採取行動。

異動內容和原因

Chrome 115起,網站將無法設定 document.domain:Chrome 會讓 document.domain 不可變更。如要進行跨來源通訊,您必須使用其他方法,例如 postMessage() 或 Channel Messaging API。

請注意,這項異動會逐步推出。

我們預期其他瀏覽器最終也會淘汰並移除這項功能。詳情請參閱「瀏覽器相容性」一節。

為什麼要將 document.domain 設為不可變?

document.domain 旨在取得或設定來源的主機名稱。許多網站都會設定 document.domain,允許同網站但不同原點的網頁之間進行通訊。

雖然這項做法相當方便,但會引發安全性風險,因為它會放寬同源政策。由於 document.domain 存在安全性疑慮,因此我們已修改規格,提醒使用者避免使用

詳細說明:為何要將 document.domain 設為不可變動?

document.domain 目前的使用方式

許多網站都會設定 document.domain,允許同網站但不同原點的網頁之間進行通訊。

同網站但跨來源的網站具有相同的 eTLD+1,但子網域不同。

以下是 document.domain 到目前為止的使用情形:

假設 https://parent.example.com 上的網頁嵌入 https://video.example.com 中的 iframe 頁面。這些網頁具有相同的 eTLD+1 (example.com),但子網域不同。如果兩個網頁的 document.domain 都設為 'example.com',瀏覽器會將這兩個來源視為同源。

https://parent.example.com 設定 document.domain

// Confirm the current origin of "parent.example.com"
console.log(document.domain);

// Set the document.domain
document.domain = 'example.com';
console.log(document.domain);

https://video.example.com 設定 document.domain

// Confirm the current origin of "video.example.com"
console.log(document.domain);

// Set the document.domain
document.domain = 'example.com';
console.log(document.domain);

您現在可以在 https://parent.example.com 上針對 https://video.example.com 建立跨來源 DOM 操作。

網站會設定 document.domain,讓同網站的文件更容易進行通訊。由於這項變更放寬了同源政策,因此父項頁面可以存取 iframe 的文件,並遍歷 DOM 樹狀結構,反之亦然。

這項技巧雖然方便,但會帶來安全風險。

document.domain 的安全疑慮

由於 document.domain 存在安全性疑慮,因此規格已變更,提醒使用者避免使用

舉例來說,如果兩個網頁都設定 document.domain,則兩者可以假裝為同源網頁。當這些網頁使用不同子網域的共用代管服務時,這一點就格外重要。設定 document.domain 會開放使用者存取同一個服務代管的所有其他網站,讓攻擊者更容易存取您的網站。這是因為 document.domain 會忽略網域的通訊埠號碼部分。

如要進一步瞭解設定 document.domain 的安全性影響,請參閱 MDN 上的 "Document.domain" 頁面

瀏覽器相容性

如何得知我的網站是否受到影響?

如果您的網站受到這項異動影響,Chrome 會在開發人員工具「Issues」面板中發出警告,這項警告已在 2022 年新增。請注意開發人員工具右上方的黃色標記。

開發人員工具中問題警告的螢幕截圖

你也可以透過 Lighthouse 已淘汰的 API 稽核執行網站,找出所有已排定從 Chrome 中移除的 API。

如果您已設定 Reporting API,Chrome 會傳送淘汰報表,通知您即將淘汰的功能。進一步瞭解如何使用 Reporting API 搭配現有的報表收集服務,或是自行建構內部解決方案。

如何查看這項異動?

這項異動將從 Chrome 115 開始逐步推出。如要查看這項變更 (即使尚未在 Chrome 瀏覽器中推出),請按照下列步驟啟用:

  1. 開啟「chrome://flags/#origin-agent-cluster-default
  2. 選取「啟用」
  3. 重新啟動 Chrome。

我可以使用哪些替代方案?

最佳做法是不修改 document.domain,例如在相同來源中代管網頁和所有構成的框架。這項功能適用於所有瀏覽器的所有版本。不過,這可能需要大幅重新處理應用程式,因此建議您也查看其他可繼續支援跨來源存取的替代方案。

使用 postMessage() 或 Channel Messaging API 而非 document.domain

在大多數情況下,跨來源 postMessage()Channel Messaging API 可以取代 document.domain

在下列範例中:

  1. https://parent.example.com 會在 iframe 中要求 https://video.example.com,藉由透過 postMessage() 傳送訊息來操控 DOM。
  2. https://video.example.com 收到訊息後,就會操控 DOM,並將成功通知傳回至父項。
  3. https://parent.example.com 會確認成功。

https://parent.example.com 中:

// Send a message to https://video.example.com
iframe.postMessage('Request DOM manipulation', 'https://video.example.com');

// Receive messages
iframe.addEventListener('message', (event) => {
  // Reject all messages except ones from https://video.example.com
  if (event.origin !== 'https://video.example.com') return;

  // Filter success messages
  if (event.data === 'succeeded') {
    // DOM manipulation is succeeded
  }
});

https://video.example.com 中:

// Receive messages
window.addEventListener('message', (event) => {
  // Reject all messages except ones from https://parent.example.com
  if (event.origin !== 'https://parent.example.com') return;

  // Do a DOM manipulation on https://video.example.com.

  // Send a success message to https://parent.example.com
  event.source.postMessage('succeeded', event.origin);
});

試試看,瞭解運作方式。如果您有特定需求,但無法搭配 postMessage() 或 Channel Messaging API 使用,請透過 Twitter 上的 @ChromiumDev 與我們聯絡,或在 Stack Overflow 上提出問題,並加上 document.domain 標籤

如非萬不得已,請傳送 Origin-Agent-Cluster: ?0 標頭

如果您有充分理由繼續設定 document.domain,可以將 Origin-Agent-Cluster: ?0 回應標頭與目標文件一起傳送。

Origin-Agent-Cluster: ?0

Origin-Agent-Cluster 標頭會指示瀏覽器是否應由 origin-keyed 代理程式叢集處理文件。如要進一步瞭解 Origin-Agent-Cluster,請參閱「使用 Origin-Agent-Cluster 標頭要求效能隔離」。

傳送這個標頭後,即使 document.domain 預設為不可變更,文件仍可繼續設定 document.domain

所有需要此行為的其他文件也必須傳送 Origin-Agent-Cluster (請注意,如果只有一個文件設定 document.domain,則不會生效)。

設定企業政策的 OriginAgentClusterDefaultEnabled

管理員可以選擇將 OriginAgentClusterDefaultEnabled 政策設為 false,讓 document.domain 預設為可在貴機構的 Chrome 執行個體上設定。如需更多資訊,請參閱「Chrome Enterprise 政策清單與管理服務 | 說明文件」。

資源

特別銘謝

相片來源:Finan Akbar 提供,取自 Unsplash