Publicado em 4 de maio de 2020
Em Como tornar seu site com isolamento de origem cruzada usando COOP e COEP explicamos como adotar o estado com isolamento de origem cruzada usando COOP e COEP. Este é um artigo complementar que explica por que o isolamento entre origens é necessário para ativar recursos avançados no navegador.
Glossário
Este documento usa muitos termos abreviados e com nomes semelhantes. Para esclarecer, criamos um miniglossário:
- COEP: Política de incorporador entre origens
- COOP: Política de abertura entre origens
- CORP: Política de recursos entre origens
- CORS: Compartilhamento de recursos entre origens
- CORB: Bloqueio de leitura entre origens
Contexto
A Web é criada com base na política de mesma origem, um
recurso de segurança que restringe como documentos e scripts podem interagir com
recursos de outra origem. Esse princípio restringe as maneiras como os sites podem acessar recursos entre origens. Por exemplo, um documento de https://a.example é impedido de acessar dados hospedados em https://b.example.
No entanto, a política de mesma origem teve algumas exceções históricas. Qualquer site pode:
- Incorporar iframes entre origens
- Incluir recursos entre origens, como imagens ou scripts
- Abrir janelas de diálogo entre origens com uma referência DOM
Quando a comunidade da Web percebeu os benefícios de uma política de mesma origem estrita, a Web já dependia dessas exceções.
Os efeitos colaterais de segurança de uma política de mesma origem tão flexível foram corrigidos de duas maneiras:
- O protocolo de compartilhamento de recursos entre origens (CORS) garante que o servidor permita o compartilhamento de um recurso com uma determinada origem.
- Os desenvolvedores removem implicitamente o acesso direto de script a recursos entre origens, preservando a compatibilidade com versões anteriores. Esses recursos entre origens são chamados de recursos "opacos". É por isso que a manipulação de pixels entre origens com
CanvasRenderingContext2Dfalha, a menos que o CORS seja aplicado à imagem.
Todas essas decisões de política estão acontecendo em um grupo de contexto de navegação.

Por muito tempo, essa combinação foi suficiente para manter os navegadores seguros, com casos extremos limitados que precisavam de correção direta (como vulnerabilidades JSON).
Isso mudou com
Spectre, que
torna potencialmente legíveis todos os dados carregados no mesmo grupo de contexto de navegação que o código. Ao medir o tempo que determinadas operações levam, os invasores podem adivinhar o conteúdo dos caches da CPU e, portanto, o conteúdo da memória do processo. Esses ataques são possíveis com timers de baixa granularidade que existem na plataforma e podem ser acelerados com timers de alta granularidade, explícitos (como performance.now()) e implícitos (como SharedArrayBuffers).
Se evil.com incorporar uma imagem entre origens, ele poderá usar um ataque Spectre para ler os dados de pixel da imagem incorporada. Isso torna as proteções que dependem da "opacidade" ineficazes.

O ideal é que todas as solicitações entre origens sejam analisadas pelo servidor que possui o recurso. Se a análise não for realizada, os dados nunca deverão chegar ao grupo de contexto de navegação de um ator mal-intencionado. Assim, os dados ficam fora do alcance de possíveis ataques Spectre. Chamamos isso de estado de isolamento de origem cruzada.
Quando o código incorporado está em um estado de isolamento de origem cruzada, o site solicitante é considerado menos perigoso. Isso permite que o site solicitante use
SharedArrayBuffer, performance.measureUserAgentSpecificMemory() e
timers de alta resolução com melhor precisão,
evitando possíveis ataques Spectre. Esse estado também impede a modificação de document.domain.
Política de incorporador entre origens
A Política de incorporador entre origens (COEP) impede que um documento carregue recursos entre origens que não concedam permissão explicitamente ao documento com CORP ou CORS. Com esse recurso, é possível declarar que um documento não pode carregar esses recursos.
a.example,
definiu a política COEP como require-corp. a.example quer incorporar três recursos de b.example, mas apenas dois são bem-sucedidos.
As duas incorporações bem-sucedidas incluem um arquivo JavaScript com uma política CORP entre origens e uma imagem com CORS permitido. O terceiro recurso é um vídeo que tem uma política CORP que exige que o recurso seja incorporado apenas na mesma origem. Portanto, o vídeo não será carregado em a.example.
Para ativar essa política, anexe o seguinte cabeçalho HTTP ao documento:
Cross-Origin-Embedder-Policy: require-corp
O COEP usa um único valor de require-corp. Isso aplica a política de que o documento só pode carregar recursos da mesma origem ou recursos marcados explicitamente como carregáveis de outra origem.
Para que os recursos possam ser carregados de outra origem, eles precisam oferecer suporte ao compartilhamento de recursos entre origens (CORS) ou à Política de recursos entre origens (CORP).
Compartilhamento de recursos entre origens
Se um recurso entre origens oferece suporte ao compartilhamento de recursos entre origens
(CORS), você pode usar o
crossorigin
atributo
para carregá-lo na sua página da Web sem ser bloqueado pelo COEP.
<img src="https://third-party.example.com/image.jpg" crossorigin>
Por exemplo, se esse recurso de imagem for veiculado com cabeçalhos CORS, use o
crossorigin atributo para que a solicitação de busca do recurso use CORS
modo. Isso também impede que a imagem seja carregada, a menos que ela defina cabeçalhos CORS.
Da mesma forma, é possível buscar dados entre origens usando o método fetch(), que
não exige tratamento especial, desde que o servidor responda com os cabeçalhos
HTTP
corretos.
Política de recursos entre origens
A Política de recursos entre origens (CORP) foi originalmente introduzida como uma opção para proteger seus recursos contra o carregamento por outra origem. No contexto do COEP, o CORP pode especificar a política do proprietário do recurso para quem pode carregar um recurso.
O cabeçalho Cross-Origin-Resource-Policy aceita três valores possíveis:
Cross-Origin-Resource-Policy: same-site
Os recursos marcados como same-site só podem ser carregados do mesmo site.
Cross-Origin-Resource-Policy: same-origin
Os recursos marcados como same-origin só podem ser carregados da mesma origem.
Cross-Origin-Resource-Policy: cross-origin
Os recursos marcados como cross-origin podem ser carregados por qualquer site. (Esse
valor foi adicionado à
especificação CORP junto com o COEP.)
Política de abertura entre origens
A Política de abertura entre origens
(COOP) permite isolar uma
janela de nível superior de outros documentos, colocando os documentos em um grupo de contexto de navegação separado. Dessa forma, os documentos não podem interagir diretamente com a janela de nível superior. Por exemplo, se um documento com COOP abrir uma caixa de diálogo, a propriedade window.opener será null. A propriedade .closed da referência do abridor é true.

O cabeçalho Cross-Origin-Opener-Policy aceita três valores possíveis:
Cross-Origin-Opener-Policy: same-origin
Os documentos marcados como same-origin podem compartilhar o mesmo grupo de contexto de navegação com documentos de mesma origem que também estão marcados explicitamente como same-origin.

Cross-Origin-Opener-Policy: same-origin-allow-popups
Um documento de nível superior com same-origin-allow-popups mantém referências a todos os pop-ups que não definem o COOP ou que desativam o isolamento definindo um COOP de unsafe-none.

Cross-Origin-Opener-Policy: unsafe-none
unsafe-none é o padrão e permite que o documento seja adicionado ao grupo de contexto de navegação do abridor, a menos que o próprio abridor tenha um COOP de same-origin.
Resumo
Se você quiser acessar recursos como SharedArrayBuffer,
performance.measureUserAgentSpecificMemory(), ou timers de alta resolução com melhor precisão,
seu documento precisará usar o COEP com o valor de require-corp e
o COOP com o valor de same-origin. Na ausência de um deles, o navegador não vai garantir isolamento suficiente para ativar esses recursos avançados com segurança.
Você pode determinar a situação da sua página verificando se
self.crossOriginIsolated
retorna true.
Saiba como implementar isso em Como tornar seu site "isolado entre origens" usando COOP e COEP.