Por qué necesitas el "aislamiento de origen cruzado" para obtener funciones potentes

Descubre por qué se necesita el aislamiento de origen cruzado para usar funciones potentes, como SharedArrayBuffer, performance.measureUserAgentSpecificMemory() y el temporizador de alta resolución con mayor precisión.

Domenic Denicola
Domenic Denicola

Introducción

En Cómo hacer que tu sitio web sea "aislado de origen cruzado" con COOP y COEP, explicamos cómo adoptar el estado "aislado de origen cruzado" con COOP y COEP. Este es un artículo complementario que explica por qué se requiere el aislamiento de origen cruzado para habilitar funciones potentes en el navegador.

Segundo plano

La Web se basa en la política de mismo origen: una función de seguridad que restringe la forma en que los documentos y las secuencias de comandos pueden interactuar con recursos de otro origen. Este principio restringe las formas en que los sitios web pueden acceder a recursos de varios orígenes. Por ejemplo, se impide que un documento de https://a.example acceda a los datos alojados en https://b.example.

Sin embargo, la política de origen tiene algunas excepciones históricas. Cualquier sitio web puede hacer lo siguiente:

  • Cómo incorporar iframes de origen cruzado
  • Incluye recursos de varios orígenes, como imágenes o secuencias de comandos
  • Cómo abrir ventanas emergentes de origen cruzado con una referencia de DOM

Si la Web se pudiera diseñar desde cero, no existirían estas excepciones. Lamentablemente, cuando la comunidad web se dio cuenta de los beneficios clave de una política de origen estricto, la Web ya dependía de estas excepciones.

Los efectos secundarios de seguridad de una política de mismo origen tan laxa se corrigieron de dos maneras. Una forma fue a través de la introducción de un nuevo protocolo llamado uso compartido de recursos entre dominios (CORS), cuyo propósito es garantizar que el servidor permita compartir un recurso con un origen determinado. La otra forma es quitar de forma implícita el acceso directo de la secuencia de comandos a los recursos de origen cruzado mientras se conserva la retrocompatibilidad. Estos recursos de origen cruzado se denominan recursos “opacos”. Por ejemplo, esta es la razón por la que manipular los píxeles de una imagen entre dominios a través de CanvasRenderingContext2D falla, a menos que se aplique CORS a la imagen.

Todas estas decisiones de políticas se toman dentro de un grupo de contexto de navegación.

Grupo de contexto de navegación

Durante mucho tiempo, la combinación de CORS y recursos opacos fue suficiente para que los navegadores fueran seguros. A veces, se descubrieron casos extremos (como vulnerabilidades de JSON) que debían corregirse, pero, en general, el principio de no permitir el acceso de lectura directo a los bytes sin procesar de los recursos de origen cruzado fue exitoso.

Todo esto cambió con Spectre, que hace que cualquier dato que se cargue en el mismo grupo de contexto de navegación que tu código sea potencialmente legible. Cuando se mide el tiempo que tardan ciertas operaciones, los atacantes pueden adivinar el contenido de las cachés de la CPU y, a través de ellas, el contenido de la memoria del proceso. Estos ataques de sincronización son posibles con los temporizadores de baja granularidad que existen en la plataforma, pero se pueden acelerar con temporizadores de alta granularidad, tanto explícitos (como performance.now()) como implícitos (como SharedArrayBuffer). Si evil.com incorpora una imagen de origen cruzado, puede usar un ataque Spectre para leer sus datos de píxeles, lo que hace que las protecciones que dependen de la "opacidad" sean ineficaces.

Spectr

Idealmente, el servidor que es propietario del recurso debe revisar de forma explícita todas las solicitudes entre orígenes. Si el servidor propietario de los recursos no proporciona la verificación, los datos nunca llegarán al grupo de contexto de navegación de un actor malicioso y, por lo tanto, permanecerán fuera del alcance de cualquier ataque Spectre que pueda realizar una página web. Lo llamamos un estado aislado de origen cruzado. De eso se trata COOP+COEP.

En un estado aislado de varios orígenes, el sitio solicitante se considera menos peligroso, lo que desbloquea funciones potentes, como SharedArrayBuffer, performance.measureUserAgentSpecificMemory() y temporizadores de alta resolución con mejor precisión, que de otro modo podrían utilizarse para ataques similares a Spectre. También evita que se modifique document.domain.

Política de incorporaciones de origen cruzado

La política de incorporación entre orígenes (COEP) evita que un documento cargue recursos entre orígenes que no otorguen permiso al documento de forma explícita (con CORP o CORS). Con esta función, puedes declarar que un documento no puede cargar esos recursos.

Cómo funciona el COEP

Para activar esta política, agrega el siguiente encabezado HTTP al documento:

Cross-Origin-Embedder-Policy: require-corp

La palabra clave require-corp es el único valor aceptado para COEP. Esto aplica la política de que el documento solo puede cargar recursos del mismo origen o recursos marcados de forma explícita como cargables desde otro origen.

Para que los recursos se puedan cargar desde otro origen, deben admitir el uso compartido de recursos entre orígenes (CORS) o la política de recursos entre orígenes (CORP).

Uso compartido de recursos entre dominios

Si un recurso multiorigen admite el uso compartido de recursos entre dominios (CORS), puedes usar el atributo crossorigin para cargarlo en tu página web sin que el COEP lo bloquee.

<img src="https://third-party.example.com/image.jpg" crossorigin>

Por ejemplo, si este recurso de imagen se entrega con encabezados de CORS, usa el atributo crossorigin para que la solicitud de recuperación del recurso use el modo de CORS. Esto también evita que se cargue la imagen, a menos que se establezcan encabezados CORS.

Del mismo modo, puedes recuperar datos de varios orígenes a través del método fetch(), que no requiere un manejo especial, siempre y cuando el servidor responda con los encabezados HTTP correctos.

Política de recursos de origen cruzado

La política de recursos entre dominios (CORP) se presentó originalmente como una opción para evitar que otro origen cargue tus recursos. En el contexto de la COEP, CORP puede especificar la política del propietario del recurso para determinar quién puede cargar un recurso.

El encabezado Cross-Origin-Resource-Policy toma tres valores posibles:

Cross-Origin-Resource-Policy: same-site

Los recursos marcados como same-site solo se pueden cargar desde el mismo sitio.

Cross-Origin-Resource-Policy: same-origin

Los recursos marcados como same-origin solo se pueden cargar desde el mismo origen.

Cross-Origin-Resource-Policy: cross-origin

Cualquier sitio web puede cargar los recursos marcados como cross-origin. (Este valor se agregó a la especificación de CORP junto con COEP).

Política de abridor de origen cruzado

La política de apertura de origen cruzado (COOP) te permite asegurarte de que una ventana de nivel superior esté aislada de otros documentos colocándolos en un grupo de contexto de navegación diferente, de modo que no puedan interactuar directamente con la ventana de nivel superior. Por ejemplo, si un documento con COOP abre una ventana emergente, su propiedad window.opener será null. Además, la propiedad .closed de la referencia del abridor a ella mostrará true.

COOP

El encabezado Cross-Origin-Opener-Policy toma tres valores posibles:

Cross-Origin-Opener-Policy: same-origin

Los documentos marcados como same-origin pueden compartir el mismo grupo de contexto de navegación con documentos del mismo origen que también estén marcados de forma explícita como same-origin.

COOP

Cross-Origin-Opener-Policy: same-origin-allow-popups

Un documento de nivel superior con same-origin-allow-popups retiene referencias a cualquiera de sus ventanas emergentes que no establezcan la COOP o que inhabiliten el aislamiento configurando una COOP de unsafe-none.

COOP

Cross-Origin-Opener-Policy: unsafe-none

unsafe-none es la opción predeterminada y permite que el documento se agregue al grupo de contexto de navegación del activador, a menos que el activador tenga un COOP de same-origin.

Resumen

Si deseas tener acceso garantizado a funciones potentes, como SharedArrayBuffer, performance.measureUserAgentSpecificMemory() o cronómetros de alta resolución con mejor precisión, recuerda que tu documento debe usar COEP con el valor de require-corp y COOP con el valor de same-origin. Si no se cuenta con ninguno de ellos, el navegador no garantizará un aislamiento suficiente para habilitar de forma segura esas funciones potentes. Para determinar la situación de tu página, verifica si self.crossOriginIsolated muestra true.

Obtén información sobre los pasos para implementar esta función en Cómo hacer que tu sitio web esté "aislado de varios orígenes" con COOP y COEP.

Recursos