Chrome no permite modificar document.domain

Si tu sitio web depende de la configuración de document.domain, debes tomar medidas.

¿Qué cambiará y por qué?

A partir de Chrome 115, los sitios web no podrán establecer document.domain, ya que Chrome lo hará inmutable.document.domain Para comunicar orígenes cruzados, debes usar métodos alternativos, como postMessage() o la API de Channel Messaging.

Ten en cuenta que este cambio se lanzará de forma progresiva.

Esperamos que otros navegadores también quiten esta funcionalidad. Consulta la sección Compatibilidad con navegadores para obtener más detalles.

¿Por qué hacer que document.domain sea inmutable?

document.domain se diseñó para obtener o establecer el nombre de host del origen. Muchos sitios web establecen document.domain para permitir la comunicación entre páginas del mismo sitio, pero de origen cruzado.

Si bien esta es una técnica conveniente, presenta un riesgo para la seguridad, ya que disminuye la rigidez de la política del mismo origen. Las preocupaciones de seguridad en torno a document.domain provocaron un cambio en la especificación que advierte a los usuarios que eviten usarla.

En detalle: ¿Por qué hacer que document.domain sea inmutable?

Cómo se usa document.domain hoy en día

Muchos sitios web configuran document.domain para permitir la comunicación entre páginas del mismo sitio, pero de origen cruzado.

Los sitios del mismo sitio, pero de origen cruzado, tienen el mismo eTLD+1, pero diferentes subdominios.

Así se usó document.domain hasta ahora:

Supongamos que una página en https://parent.example.com incorpora una página de iframe de https://video.example.com. Estas páginas tienen el mismo eTLD+1 (example.com) con diferentes subdominios. Cuando el document.domain de ambas páginas se establece en 'example.com', el navegador trata los dos orígenes como si fueran del mismo origen.

Establece el document.domain para 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);

Establece el document.domain para 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);

Ahora puedes crear una manipulación del DOM de origen cruzado en https://parent.example.com contra https://video.example.com.

Los sitios web configuran document.domain para que los documentos del mismo sitio puedan comunicarse con mayor facilidad. Dado que este cambio relaja la política del mismo origen, la página principal puede acceder al documento del iframe y recorrer el árbol DOM, y viceversa.

Esta es una técnica conveniente, pero introduce un riesgo de seguridad.

Preocupaciones de seguridad con document.domain

Las preocupaciones de seguridad en torno a document.domain provocaron un cambio en la especificación que advierte a los usuarios que eviten usarlo.

Por ejemplo, cuando dos páginas establecen document.domain, pueden simular que tienen el mismo origen. Esto es especialmente importante cuando estas páginas usan un servicio de hosting compartido con diferentes subdominios. Establecer document.domain abre el acceso a todos los demás sitios alojados por el mismo servicio, lo que facilita que los atacantes accedan a tus sitios. Esto es posible porque document.domain ignora la parte del número de puerto del dominio.

Para obtener más información sobre las implicaciones de seguridad de establecer document.domain, consulta la página"Document.domain" en MDN.

Compatibilidad del navegador

¿Cómo sé si mi sitio se ve afectado?

Si tu sitio web se ve afectado por este cambio, Chrome te mostrará una advertencia en el panel Issues de las Herramientas para desarrolladores, que se agregó en 2022. Observa la marca amarilla en la parte superior derecha de Herramientas para desarrolladores.

Captura de pantalla de la advertencia del problema en Herramientas para desarrolladores

También puedes ejecutar tu sitio a través de la auditoría de la API obsoleta de Lighthouse para encontrar todas las APIs que se quitarán de Chrome.

Si configuraste la API de Reporting, Chrome te envió informes de baja para notificarte sobre esta próxima baja. Obtén más información para usar la API de Informes con los servicios de recopilación de informes existentes o creando tu propia solución interna.

¿Cómo puedo ver este cambio en acción?

El cambio se lanzará de forma progresiva a partir de Chrome 115. Para ver este cambio en acción, incluso si aún no se lanzó en tu navegador Chrome, puedes activarlo de la siguiente manera:

  1. Abrir chrome://flags/#origin-agent-cluster-default
  2. Selecciona Habilitar.
  3. Reinicia Chrome.

¿Qué alternativas puedo usar?

La mejor opción es no modificar document.domain en absoluto, por ejemplo, alojando la página y todos los marcos constituyentes en el mismo origen. Esto funciona en todas las versiones de todos los navegadores. Sin embargo, esto puede requerir una reelaboración sustancial de una aplicación, por lo que también vale la pena analizar alternativas que sigan admitiendo accesos de origen cruzado.

Usa postMessage() o la API de Channel Messaging en lugar de document.domain

En la mayoría de los casos de uso, postMessage() de origen cruzado o la API de Channel Messaging pueden reemplazar a document.domain.

En el siguiente ejemplo:

  1. https://parent.example.com solicita https://video.example.com dentro de un iframe para manipular el DOM enviando un mensaje a través de postMessage().
  2. https://video.example.com manipula el DOM en cuanto recibe el mensaje y notifica el éxito a su elemento superior.
  3. https://parent.example.com reconoce el éxito.

En https://parent.example.com, haz lo siguiente:

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

En https://video.example.com, haz lo siguiente:

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

Pruébalo y observa cómo funciona. Si tienes requisitos específicos que no funcionan con postMessage() o la API de Channel Messaging, infórmanos en Twitter a través de @ChromiumDev o haz una pregunta en Stack Overflow con una etiqueta document.domain.

Como último recurso, envía el encabezado Origin-Agent-Cluster: ?0.

Si tienes motivos sólidos para seguir configurando document.domain, puedes enviar el encabezado de respuesta Origin-Agent-Cluster: ?0 junto con el documento de destino.

Origin-Agent-Cluster: ?0

El encabezado Origin-Agent-Cluster indica al navegador si el documento debe controlarse con el clúster de agentes con clave de origen o no. Para obtener más información sobre Origin-Agent-Cluster, consulta Cómo solicitar aislamiento del rendimiento con el encabezado Origin-Agent-Cluster.

Cuando envías este encabezado, tu documento puede seguir estableciendo document.domain incluso después de que se vuelva inmutable de forma predeterminada.

Todos los demás documentos que requieran ese comportamiento también deberán enviar un Origin-Agent-Cluster (ten en cuenta que document.domain no tiene ningún efecto si solo un documento lo establece).

Configura OriginAgentClusterDefaultEnabled para la política empresarial

De manera opcional, tu administrador puede configurar la política OriginAgentClusterDefaultEnabled en false para que document.domain se pueda configurar de forma predeterminada en las instancias de Chrome de toda tu organización. Para obtener más información, consulta Lista y administración de políticas de Chrome Enterprise | Documentación.

Recursos

Agradecimientos

Foto de Finan Akbar en Unsplash