O Chrome desativa a modificação de document.domain

Caso seu site dependa da configuração de document.domain, você precisa fazer isso.

Maud Nalpas
Maud Nalpas
Eiji Kitamura
Eiji Kitamura

.

O que vai mudar e por quê?

A partir do Chrome 115, os sites não poderão definir document.domain: o Chrome vai tornar document.domain imutável. Para comunicar o tráfego de origem cruzada, você precisa usar abordagens alternativas, como postMessage() ou a API Channel Messaging.

Observação: a mudança vai ser lançada aos poucos.

Esperamos que outros navegadores descontinuam e removam essa funcionalidade. Consulte a seção de compatibilidade do navegador para mais detalhes.

Por que tornar document.domain imutável?

document.domain foi projetado para receber ou definir o nome do host da origem. Muitos sites definem document.domain para permitir a comunicação entre páginas do mesmo site, mas de origem cruzada.

Essa é uma técnica conveniente, mas apresenta um risco de segurança porque relaxa a política de mesma origem. As preocupações de segurança com relação ao document.domain levaram a uma mudança na especificação que avisa aos usuários para evitar o uso dela (link em inglês).

Em detalhes: por que tornar document.domain imutável?

Como o document.domain é usado hoje

Muitos sites configuram o document.domain para permitir a comunicação entre páginas do mesmo site, mas de origem cruzada.

Os sites do mesmo site, mas de origem cruzada, têm o mesmo eTLD+1, mas subdomínios diferentes.

Veja como o document.domain era usado até agora:

Digamos que uma página em https://parent.example.com incorpore uma página de iframe de https://video.example.com. Essas páginas têm o mesmo eTLD+1 (example.com) com subdomínios diferentes. Quando o document.domain das duas páginas é definido como 'example.com', o navegador trata as duas como se fossem da mesma origem.

Defina document.domain como 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);

Defina document.domain como 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);

Agora é possível criar uma manipulação de DOM de origem cruzada em https://parent.example.com em relação a https://video.example.com.

Os sites definem document.domain para permitir que documentos do mesmo site se comuniquem mais facilmente. Como essa alteração relaxa a política de mesma origem, a página pai pode acessar o documento do iframe e percorrer a árvore DOM e vice-versa.

Essa é uma técnica conveniente, mas apresenta um risco de segurança.

Preocupações de segurança com o app document.domain

As preocupações com a segurança em torno de document.domain levaram a uma mudança na especificação que alerta os usuários para evitar o uso dela (link em inglês).

Por exemplo, quando duas páginas definem document.domain, elas podem fingir que sejam da mesma origem. Isso é especialmente importante quando essas páginas usam um serviço de hospedagem compartilhado com subdomínios diferentes. Definir document.domain abre o acesso a todos os outros sites hospedados pelo mesmo serviço, facilitando o acesso de invasores. Isso é possível porque document.domain ignora a parte do número da porta do domínio.

Para saber mais sobre as implicações de segurança da configuração de document.domain, leia a página"Document.domain" no MDN.

Compatibilidade com navegadores

Como saber se meu site será afetado?

Se seu site for afetado por essa mudança, o Chrome vai enviar um aviso no painel "Issues" do DevTools. Esse aviso foi adicionado em 2022. Observe o sinal amarelo no canto superior direito do DevTools.

Captura de tela do aviso de problema no DevTools

Também é possível analisar o site com a auditoria de APIs descontinuadas do LightHouse para encontrar todas as APIs programadas para serem removidas do Chrome.

Se você configurou a API Reporting, o Chrome enviou relatórios de descontinuação para avisar sobre essa suspensão de uso que está para frente. Saiba mais sobre como usar a API Reporting com os serviços de coleta de relatórios atuais ou criando sua própria solução interna.

Como vejo essa mudança em ação?

A alteração será lançada progressivamente a partir do Chrome 115. Para conferir essa mudança em ação, mesmo que ela ainda não tenha sido lançada no seu navegador Chrome, ative-a da seguinte maneira:

  1. Abrir chrome://flags/#origin-agent-cluster-default
  2. Selecione Ativar.
  3. Reinicie o Chrome.

Quais alternativas posso usar?

A melhor opção é não modificar document.domain, por exemplo, hospedando a página e todos os frames constituintes na mesma origem. Isso funciona em todas as versões de todos os navegadores. No entanto, isso pode exigir um grande retrabalho de um aplicativo. Por isso, vale a pena analisar alternativas que continuem a oferecer suporte a acessos de origem cruzada.

Use postMessage() ou a API Channel Messaging em vez de document.domain

Na maioria dos casos de uso, a postMessage() de origem cruzada ou a API Channel Messaging pode substituir document.domain.

Estes são os elementos do exemplo a seguir:

  1. https://parent.example.com solicita https://video.example.com em um iframe para manipular o DOM enviando uma mensagem via postMessage().
  2. https://video.example.com manipula o DOM assim que recebe a mensagem e notifica o sucesso de volta ao pai.
  3. https://parent.example.com confirma o sucesso.

Em 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
  }
});

Em 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);
});

Faça um teste e veja como funciona. Se você tiver requisitos específicos que não funcionem com o postMessage() ou a API Channel Messaging, deixe seu comentário no Twitter via @ChromiumDev ou faça uma pergunta no Stack Overflow com uma tag document.domain.

Como último recurso, envie o cabeçalho Origin-Agent-Cluster: ?0

Se você tiver fortes motivos para continuar configurando document.domain, envie o cabeçalho de resposta Origin-Agent-Cluster: ?0 com o documento de destino.

Origin-Agent-Cluster: ?0

O cabeçalho Origin-Agent-Cluster instrui o navegador se o documento precisa ser manipulado pelo cluster de agente com origin-key. Para saber mais sobre Origin-Agent-Cluster, leia Como solicitar isolamento de desempenho com o cabeçalho Origin-Agent-Cluster.

Ao enviar esse cabeçalho, seu documento pode continuar definindo document.domain mesmo depois que ele se tornar imutável por padrão.

Todos os outros documentos que exigem esse comportamento também precisarão enviar um Origin-Agent-Cluster. Observe que document.domain não terá efeito se apenas um documento o definir.

Configurar o OriginAgentClusterDefaultEnabled para a política corporativa

Se preferir, o administrador pode configurar a política OriginAgentClusterDefaultEnabled como false para tornar a configuração document.domain padrão nas instâncias do Chrome em toda a organização. Saiba mais na Lista e gerenciamento de políticas do Chrome Enterprise | Documentação.

Recursos

Agradecimentos

Foto de Finan Akbar no Unsplash (links em inglês)