Chrome отключает изменение document.domain

Если ваш сайт зависит от настройки document.domain, требуется ваше действие.

Что меняется и почему?

Начиная с Chrome 115 , веб-сайты не смогут устанавливать document.domain : Chrome сделает document.domain неизменяемым. Для связи между источниками вам необходимо использовать альтернативные подходы, такие как postMessage() или API Channel Messaging.

Обратите внимание, что это изменение будет внедряться постепенно.

Мы ожидаем, что другие браузеры в конечном итоге устареют и удалят эту функцию. Ознакомьтесь с разделом совместимости браузеров для получения подробной информации.

Зачем делать document.domain неизменяемым?

document.domain был разработан для получения или установки имени хоста источника. Многие веб-сайты устанавливают document.domain для обеспечения связи между страницами одного сайта, но с кросс-источниками .

Хотя это удобный метод, он представляет угрозу безопасности, поскольку ослабляет политику одинакового происхождения . Проблемы безопасности вокруг document.domain привели к изменению спецификации, которая предупреждает пользователей о необходимости избегать его использования .

Подробно: Зачем делать document.domain неизменяемым?

Как document.domain используется сегодня

Многие веб-сайты устанавливают document.domain для обеспечения связи между страницами одного сайта, но с разным источником .

Сайты одного и того же сайта, но с разным происхождением, имеют одинаковый eTLD+1 , но разные поддомены.

Вот как document.domain использовался до сих пор:

Допустим, страница на https://parent.example.com встраивает страницу iframe из https://video.example.com . Эти страницы имеют одинаковый eTLD+1 ( example.com ) с разными поддоменами. Когда document.domain обеих страниц установлен на 'example.com' , браузер обрабатывает два источника как если бы они были одного происхождения.

Установите document.domain для https://parent.example.com :

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

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

Установите document.domain для https://video.example.com :

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

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

Теперь вы можете создать кросс-доменную манипуляцию DOM на https://parent.example.com и https://video.example.com .

Веб-сайты устанавливают document.domain , чтобы сделать возможным более легкое взаимодействие документов одного сайта. Поскольку это изменение ослабляет политику одного источника , родительская страница может получить доступ к документу iframe и пройти по дереву DOM, и наоборот.

Это удобный метод, однако он создает риск для безопасности.

Проблемы безопасности с document.domain

Проблемы безопасности вокруг document.domain привели к изменению спецификации, которая предупреждает пользователей о необходимости избегать его использования .

Например, когда две страницы устанавливают document.domain , они могут притворяться, что они имеют один и тот же источник. Это особенно критично, когда эти страницы используют общий хостинг с разными поддоменами. Установка document.domain открывает доступ ко всем другим сайтам, размещенным на том же сервисе, что упрощает злоумышленникам доступ к вашим сайтам. Это возможно, поскольку document.domain игнорирует часть номера порта домена.

Чтобы узнать больше о последствиях настройки document.domain для безопасности, прочитайте страницу «Document.domain» на MDN .

Совместимость с браузерами

Как узнать, затронут ли мой сайт?

Если это изменение затронет ваш сайт, Chrome предупредит вас на панели «Проблемы» DevTools — это предупреждение было добавлено в 2022 году. Обратите внимание на желтый флаг в правом верхнем углу DevTools.

Скриншот предупреждения о проблеме в DevTools

Вы также можете провести аудит устаревших API своего сайта с помощью LightHouse, чтобы найти все API, которые планируется удалить из Chrome.

Если вы настроили API отчетов, Chrome отправил вам отчеты об устаревании, чтобы уведомить вас об этом предстоящем устаревании. Узнайте больше о том, как использовать API отчетов с существующими службами сбора отчетов или путем создания собственного внутреннего решения.

Как я могу увидеть это изменение в действии?

Изменение будет внедряться постепенно, начиная с Chrome 115. Чтобы увидеть это изменение в действии, даже если оно еще не внедрено в вашем браузере Chrome, вы можете включить его следующим образом:

  1. Откройте chrome://flags/#origin-agent-cluster-default
  2. Выберите Включить.
  3. Перезапустите Chrome.

Какие альтернативы я могу использовать?

Лучший вариант — вообще не изменять document.domain , например, размещая страницу и все составляющие ее фреймы на одном источнике. Это работает во всех версиях всех браузеров. Но это может потребовать существенной переработки приложения, поэтому стоит также рассмотреть альтернативы, которые продолжают поддерживать доступ к кросс-источникам.

Используйте postMessage() или API Channel Messaging вместо document.domain

В большинстве случаев использования document.domain можно заменить кросс-доменным postMessage() или API обмена сообщениями по каналам .

В следующем примере:

  1. https://parent.example.com запрашивает https://video.example.com внутри iframe для управления DOM путем отправки сообщения через postMessage() .
  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() или API Channel Messaging, сообщите нам об этом в Twitter через @ChromiumDev или спросите на Stack Overflow с тегом document.domain .

В крайнем случае отправьте заголовок Origin-Agent-Cluster: ?0

Если у вас есть веские причины продолжить настройку document.domain , вы можете отправить заголовок ответа Origin-Agent-Cluster: ?0 вместе с целевым документом.

Origin-Agent-Cluster: ?0

Заголовок Origin-Agent-Cluster сообщает браузеру, должен ли документ обрабатываться кластером агентов с ключом origin или нет. Чтобы узнать больше о Origin-Agent-Cluster , прочитайте раздел Запрос изоляции производительности с заголовком Origin-Agent-Cluster .

При отправке этого заголовка ваш документ может продолжать устанавливать document.domain даже после того, как он станет неизменяемым по умолчанию.

Все остальные документы, требующие такого поведения, также должны будут отправить Origin-Agent-Cluster (обратите внимание, что document.domain не имеет никакого эффекта, если его задает только один документ).

Настройте OriginAgentClusterDefaultEnabled для корпоративной политики

При желании ваш администратор может настроить политику OriginAgentClusterDefaultEnabled на false , чтобы сделать document.domain настраиваемым по умолчанию на экземплярах Chrome в вашей организации. Чтобы узнать больше, прочитайте Chrome Enterprise Policy List & Management | Documentation .

Ресурсы

Благодарности

Фото Финана Акбара на Unsplash