Saiba por que o isolamento de origem cruzada é necessário para usar recursos avançados, como SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
e timer de alta resolução, com melhor precisão.
Introdução
Em Como tornar seu site "isolado de origem cruzada" usando COOP e COEP, explicamos como adotar o estado "isolado de origem cruzada" usando COOP e COEP. Este é um artigo complementar que explica por que o isolamento de origem cruzada é necessário para ativar recursos avançados no navegador.
Contexto
A Web é criada com base na política
de mesma origem: um recurso de segurança que restringe
a forma como documentos e scripts podem interagir com recursos de outra origem. Esse
princípio restringe as maneiras como os sites podem acessar recursos de origem cruzada. 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 de origem cruzada
- Incluir recursos de origem cruzada, como imagens ou scripts
- Abrir janelas pop-up de origem cruzada com uma referência do DOM
Se a Web pudesse ser projetada do zero, essas exceções não existiriam. Infelizmente, quando a comunidade da Web percebeu os principais benefícios de uma política estrita de mesma origem, a Web já estava usando essas exceções.
Os efeitos colaterais de segurança dessa política de mesma origem foram corrigidos de duas maneiras. Uma delas era com a introdução de um novo protocolo chamado Compartilhamento de recursos entre origens (CORS, na sigla em inglês), com a finalidade de garantir que o servidor permita o compartilhamento de um recurso com determinada origem. A outra maneira é remover implicitamente o acesso direto ao script para
recursos de origem cruzada, preservando a compatibilidade com versões anteriores. Esses recursos de origem cruzada são chamados de recursos "opacos". Por exemplo, é por isso que
manipular os pixels de uma imagem de origem cruzada por CanvasRenderingContext2D
falha, a menos que o CORS seja aplicado à imagem.
Todas essas decisões sobre políticas estão acontecendo em um grupo de contexto de navegação.
Por muito tempo, a combinação de CORS e recursos opacos foi suficiente para tornar os navegadores seguros. Às vezes, casos extremos (como vulnerabilidades de JSON) foram descobertos e precisaram ser corrigidos, mas, no geral, o princípio de não permitir acesso direto de leitura aos bytes brutos dos recursos de origem cruzada foi bem-sucedido.
Tudo isso mudou com o
Spectre, que
torna todos os dados carregados no mesmo grupo de contexto de navegação que o código
potencialmente legível. Ao medir o tempo que certas operações levam, os invasores
podem adivinhar o conteúdo dos caches de CPU e, com isso, o conteúdo da
memória do processo. Esses ataques de tempo são possíveis com timers de baixa granularidade
que existem na plataforma, mas podem ser acelerados com timers de alta granularidade,
tanto explícitos (como performance.now()
) quanto implícitos (como
SharedArrayBuffer
s). Se a evil.com
incorporar uma imagem de origem cruzada, ela poderá usar um
ataque Spectre para ler os dados de pixel, o que torna as proteções que dependem de
"opacidade" ineficazes.
O ideal é que todas as solicitações de origem cruzada sejam explicitamente verificadas pelo servidor que detém o recurso. Se a verificação não for fornecida pelo servidor proprietário de recursos, os dados nunca vão entrar no grupo de contexto de navegação de um agente mal-intencionado e, portanto, ficarão fora do alcance de qualquer ataque do Spectre que possa ser realizado por uma página da Web. É o estado isolado de origem cruzada. Isso é exatamente o que significa COOP+COEP.
Em um estado isolado de origem cruzada, o site solicitante é considerado menos
perigoso e isso desbloqueia recursos avançados, como SharedArrayBuffer
,
performance.measureUserAgentSpecificMemory()
e timers de
alta resolução, com melhor precisão, que poderiam
ser usados para ataques do tipo Spectre. Isso também impede a modificação de
document.domain
.
Política de incorporador de origem cruzada
A Política de incorporação de origens (COEP, na sigla em inglês) impede que um documento carregue recursos de origem cruzada que não concedem explicitamente a permissão ao documento usando CORP ou CORS. Com esse recurso, você pode declarar que um documento não pode carregar esses recursos.
Para ativar essa política, anexe o seguinte cabeçalho HTTP ao documento:
Cross-Origin-Embedder-Policy: require-corp
A palavra-chave require-corp
é o único valor aceito para COEP. Isso aplica
a política de que o documento só pode carregar recursos da mesma origem ou
recursos explicitamente marcados 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, na sigla em inglês) ou à Política de recursos de origem cruzada (CORP, na sigla em inglês).
Compartilhamento de recursos entre origens
Se um recurso de origem cruzada for compatível com o Compartilhamento de recursos entre origens (CORS), será possível usar o atributo crossorigin
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 disponibilizado com cabeçalhos CORS, use o
atributo crossorigin
para que a solicitação de busca do recurso use o modo
CORS. Isso também
impede que a imagem seja carregada, a menos que ela defina cabeçalhos CORS.
Da mesma forma, é possível buscar dados de origem cruzada usando o método fetch()
, que
não requer tratamento especial, desde que o servidor responda com os cabeçalhos
HTTP
corretos.
Política de recursos de origem cruzada
A Política de recursos entre origens (CORP, na sigla em inglês) foi originalmente apresentada como uma ativaçã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
usa 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 na 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 com a COEP.
Política de abertura de origem cruzada
A política de abertura de origem cruzada (COOP, na sigla em inglês) permite garantir que uma janela de nível superior seja isolada de outros documentos, colocando-a em um grupo de contexto de navegação diferente, para que eles não possam interagir diretamente com a janela de nível superior. Por exemplo, se um documento com COOP abrir um pop-up, a
propriedade window.opener
dele será null
. Além disso, a propriedade .closed
da referência do usuário que o abriu retornará true
.
O cabeçalho Cross-Origin-Opener-Policy
usa 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 são explicitamente marcados como same-origin
.
Cross-Origin-Opener-Policy: same-origin-allow-popups
Um documento de nível superior com same-origin-allow-popups
retém referências a qualquer
um dos pop-ups que não definem a COOP ou que desativam o isolamento
configurando uma 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 usuário que o abriu, a menos que ele tenha uma COOP de same-origin
.
Resumo
Se você quiser acesso garantido a recursos avançados, como SharedArrayBuffer
,
performance.measureUserAgentSpecificMemory()
ou tempos de
alta resolução com maior precisão, lembre-se
de que seu documento precisa usar COEP com o valor de require-corp
e
COOP com o valor de same-origin
. Na ausência de ambos, o navegador não garantirá isolamento suficiente para ativar com segurança esses recursos avançados. Você
pode determinar a situação da sua página verificando se
self.crossOriginIsolated
retorna true
.
Aprenda as etapas para implementar isso em Como tornar seu site "isolado de origem cruzada" usando COOP e COEP.