Obtén información sobre 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 mejor precisión.
Introducción
En Cómo hacer que tu sitio web esté "aislado del origen cruzado" con COOP y COEP, explicamos cómo adoptar el estado de "aislado del 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.
Fondo
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 los recursos de otro origen. Este principio restringe las formas en que los sitios web pueden acceder a recursos de origen cruzado. 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 del mismo origen tuvo algunas excepciones históricas. Cualquier sitio web puede hacer lo siguiente:
- Incorpora iframes de origen cruzado
- Incluir recursos de origen cruzado, como imágenes o secuencias de comandos
- Abrir ventanas emergentes de origen cruzado con una referencia DOM
Si la Web se pudiera diseñar desde cero, estas excepciones no existirían. Lamentablemente, cuando la comunidad web se dio cuenta de los beneficios clave de una política estricta del mismo origen, 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 multiorigen (CORS), cuyo propósito es garantizar que el servidor permita compartir un recurso con un origen determinado. La otra forma es quitar de manera implícita el acceso directo de la secuencia de comandos a los recursos de origen cruzado y, al mismo tiempo, conservar la compatibilidad con versiones anteriores. Estos recursos de origen cruzado se denominan recursos "opacos". Por ejemplo, esta es la razón por la que la manipulación de los píxeles de una imagen de origen cruzado a través de CanvasRenderingContext2D
falla, a menos que se aplique CORS a la imagen.
Todas estas decisiones sobre políticas se toman dentro de un grupo de contextos de navegación.
Durante mucho tiempo, la combinación de CORS y recursos opacos fue suficiente para que los navegadores fueran seguros. En ocasiones, se descubrieron casos extremos (como vulnerabilidades de JSON) que debieron corregirse, pero, en general, el principio de no permitir el acceso de lectura directa 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. Al medir el tiempo que tardan ciertas operaciones, los atacantes pueden adivinar el contenido de las memorias caché de la CPU y, a través de eso, 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 los 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 de Spectre para leer sus datos de píxeles, lo que hace que las protecciones que dependen de la "opacidad" sean ineficaces.
Idealmente, el servidor propietario del recurso debería verificar explícitamente todas las solicitudes de origen cruzado. Si el servidor propietario del recurso 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 de Spectre que pueda llevar a cabo una página web. A esto lo llamamos estado aislado de origen cruzado. De eso se trata exactamente COOP+COEP.
En un estado aislado de origen cruzado, 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 usarse para ataques similares a Spectre. También impide la modificación de document.domain
.
Política de incorporaciones de origen cruzado
La política Cross-Origin Embedder Policy (COEP) impide que un documento cargue recursos multiorigen que no le otorguen permiso explícitamente (con CORP o CORS). Con esta función, puedes declarar que un documento no puede cargar esos recursos.
Para activar esta política, agrega el siguiente encabezado HTTP al documento:
Cross-Origin-Embedder-Policy: require-corp
COEP toma un solo valor de require-corp
. Esto aplica la política que indica que el documento solo puede cargar recursos del mismo origen o recursos marcados explícitamente como cargables desde otro origen.
Para que los recursos se puedan cargar desde otro origen, deben admitir el uso compartido de recursos multiorigen (CORS) o la política de recursos multiorigen (CORP).
Uso compartido de recursos entre dominios
Si un recurso de origen cruzado admite el uso compartido de recursos entre dominios (CORS), puedes usar el atributo crossorigin
para cargarlo en tu página web sin que 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 para recuperar el recurso use el modo CORS. Esto también evita que se cargue la imagen, a menos que se configuren encabezados de CORS.
Del mismo modo, puedes recuperar datos de origen cruzado a través del método fetch()
, que no requiere un manejo especial siempre que el servidor responda con los encabezados HTTP correctos.
Política de recursos de origen cruzado
La Política de recursos multiorigen (CORP) se introdujo originalmente como una opción para proteger tus recursos de que los cargue otro origen. En el contexto de COEP, CORP puede especificar la política del propietario del recurso sobre 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 con same-origin
solo se pueden cargar desde el mismo origen.
Cross-Origin-Resource-Policy: cross-origin
Los recursos marcados como cross-origin
pueden cargarse en cualquier sitio web. (Este valor se agregó a la especificación de CORP junto con COEP).
Política de abridor de origen cruzado
La política Cross-Origin Opener Policy (COOP) te permite garantizar 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 elemento que abrió la ventana a esta devolverá true
.
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
.
Cross-Origin-Opener-Policy: same-origin-allow-popups
Un documento de nivel superior con same-origin-allow-popups
conserva referencias a cualquiera de sus ventanas emergentes que no establezcan COOP o que inhabiliten el aislamiento estableciendo una COOP de unsafe-none
.
Cross-Origin-Opener-Policy: unsafe-none
unsafe-none
es el valor predeterminado y permite que el documento se agregue al grupo de contexto de navegación de su abridor, a menos que el abridor tenga un COOP de same-origin
.
Resumen
Si deseas garantizar el acceso a funciones potentes, como SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
o temporizadores 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
. En ausencia de cualquiera de los dos, el navegador no garantizará el aislamiento suficiente para habilitar de forma segura esas potentes funciones. Puedes determinar la situación de tu página verificando si self.crossOriginIsolated
devuelve true
.
Consulta los pasos para implementar esto en Cómo hacer que tu sitio web esté "aislado de origen cruzado" con COOP y COEP.