Isolar seu site com "isolamento de origem cruzada" usando COOP e COEP

Use COOP e COEP para configurar um ambiente de isolamento de origem cruzada e ativar recursos avançados, como SharedArrayBuffer, performance.measureUserAgentSpecificMemory() e timer de alta resolução com melhor precisão.

Publicado em: 13 de abril de 2020, última atualização: 21 de junho de 2022

Este documento mostra como usar essas COOP e COEP. Leia mais sobre por que isso é importante em Tornar seu site "isolamento de origem cruzada" usando COOP e COEP.

Algumas APIs da Web aumentam o risco de ataques de canal lateral, como o Spectre. Para mitigar esse risco, os navegadores oferecem um ambiente isolado baseado em ativação, chamado de isolamento de origem cruzada. Com um estado de isolamento de origem cruzada, a página da Web poderá usar recursos privilegiados, incluindo:

API Descrição
SharedArrayBuffer Obrigatório para as linhas de execução do WebAssembly. Esse recurso está disponível no Chrome 88 para Android. A versão para computador é ativada por padrão com a ajuda do isolamento de sites, mas vai exigir o estado de isolamento de origem cruzada e será desativada por padrão no Chrome 92.
performance.measureUserAgentSpecificMemory() Disponível no Chrome 89.
performance.now(), performance.timeOrigin Disponível em muitos navegadores, com resolução limitada a 100 microssegundos ou mais. Com o isolamento de origem cruzada, a resolução pode ser de 5 microssegundos ou mais.
Recursos que vão estar disponíveis no estado de isolamento de origem cruzada.

O estado de isolamento de origem cruzada também impede modificações de document.domain. A capacidade de alterar document.domain permite a comunicação entre documentos do mesmo site e é considerada uma brecha na política de mesma origem.

Para ativar um estado de isolamento de origem cruzada, envie os seguintes cabeçalhos HTTP no documento principal:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

Esses cabeçalhos instruem o navegador a bloquear o carregamento de recursos ou iframes que não aceitaram ser carregados por documentos de origem cruzada e impedem que janelas de origem cruzada interajam diretamente com seu documento. Isso também significa que esses recursos carregados entre origens exigem ativações.

Para determinar se uma página da Web está em um estado de isolamento de origem cruzada, examine self.crossOriginIsolated.

Glossário

Este documento usa muitos termos abreviados e com nomes semelhantes. Para esclarecer, criamos um miniglossário:

Isolar seu site de origem cruzada

1. Defina Cross-Origin-Opener-Policy: same-origin no documento de nível superior

Ao ativar COOP: same-origin em um documento de nível superior, as janelas com a mesma origem e as janelas abertas pelo documento têm um grupo de contexto de navegação separado, a menos que estejam na mesma origem com a mesma configuração de COOP. Assim, o isolamento é aplicado às janelas abertas, e a comunicação mútua entre elas é desativada.

Um grupo de contexto de navegação é um conjunto de janelas que podem se referenciar. Por exemplo, um documento de nível superior e os documentos filhos incorporados com <iframe>. Se um site (https://a.example) abrir uma janela de diálogo (https://b.example), a janela de abertura e a janela de diálogo vão compartilhar o mesmo contexto de navegação. Portanto, elas terão acesso uma à outra com APIs DOM, como window.opener.

Ilustração que representa o grupo de conteúdo de navegação com o usuário interagindo com elementos da página.

É possível verificar se o abridor de janelas e o que foi aberto estão em grupos de contexto de navegação separados no DevTools.

2. Ativar CORP ou CORS em recursos

Verifique se todos os recursos na página são carregados com cabeçalhos HTTP CORP ou CORS. Essa etapa é necessária para a etapa quatro, que ativa a COEP.

Veja o que você precisa fazer, dependendo da natureza do recurso:

  • Se o recurso for carregado apenas da mesma origem, defina o cabeçalho Cross-Origin-Resource-Policy: same-origin.
  • Se o recurso for carregado apenas do mesmo site, mas entre origens, defina o cabeçalho Cross-Origin-Resource-Policy: same-site.
  • Se o recurso for carregado de origens diferentes sob seu controle, defina o cabeçalho Cross-Origin-Resource-Policy: cross-origin, se possível.
  • Para recursos de origem cruzada que você não controla:
    • Use o atributo crossorigin na tag HTML de carregamento se o recurso for disponibilizado com CORS. Por exemplo, <img src="***" crossorigin>.
    • Peça ao proprietário do recurso para oferecer suporte ao CORS ou ao CORP.
  • Para iframes, siga os mesmos princípios e defina o Cross-Origin-Resource-Policy: cross-origin (ou same-site, same-origin, dependendo do contexto).
  • Os scripts carregados com um WebWorker precisam ser disponibilizados na mesma origem. Portanto, não é necessário usar cabeçalhos CORP ou CORS.
  • Para um documento ou worker disponibilizado com COEP: require-corp, os sub-recursos entre origens carregados sem CORS precisam definir o cabeçalho Cross-Origin-Resource-Policy: cross-origin para serem incorporados. Por exemplo, isso se aplica a <script>, importScripts, <link>, <video>, <iframe> etc.

Isolamento em iframes

É possível ativar o isolamento de origem cruzada em um documento incorporado em um iframe aplicando a política de permissões allow="cross-origin-isolated" à tag <iframe> e atendendo a estas condições. Toda a cadeia de documentos, incluindo frames pai e filho, também precisa ter isolamento de origem cruzada.

3. Usar o cabeçalho HTTP somente para relatórios da COEP para avaliar recursos incorporados

Antes de ativar totalmente a COEP, faça uma simulação usando o cabeçalho Cross-Origin-Embedder-Policy-Report-Only para verificar se a política realmente funciona. Você vai receber relatórios sem bloquear o conteúdo incorporado.

Aplique isso de forma recursiva a todos os documentos, incluindo o documento de nível superior, iframes e scripts de worker. Para informações sobre o cabeçalho HTTP somente para relatórios, consulte Observar problemas usando a API Reporting.

4. Ativar COEP

Essa etapa só pode ser realizada depois que você garantir que os recursos tenham CORP ou CORS ativados.

Depois de confirmar que tudo funciona e que todos os recursos podem ser carregados, mude o cabeçalho Cross-Origin-Embedder-Policy-Report-Only para o cabeçalho Cross-Origin-Embedder-Policy com o mesmo valor para todos os documentos, incluindo aqueles incorporados com iframes e scripts de worker.

Determinar se o isolamento foi bem-sucedido

A propriedade self.crossOriginIsolated retorna true quando a página da Web está em um estado de isolamento de origem cruzada e todos os recursos e janelas estão isolados no mesmo grupo de contexto de navegação. Use essa API para determinar se você isolou o grupo de contexto de navegação e ganhou acesso a recursos como performance.measureUserAgentSpecificMemory().

Depurar problemas

Você pode encontrar problemas com COOP e COEP. Você pode usar as ferramentas para desenvolvedores do navegador ou a API Reporting para depurar.

Depurar com o Chrome DevTools

Para recursos renderizados na tela, como imagens, é bastante fácil detectar problemas de COEP, porque a solicitação é bloqueada e a página indica uma imagem ausente. No entanto, para recursos que não têm necessariamente um impacto visual, como scripts ou estilos, os problemas de COEP podem passar despercebidos. Para isso, use o painel Network do DevTools.

Se houver um problema com a COEP, você vai encontrar (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep) na coluna Status.

Problemas de COEP na coluna &quot;Status&quot; do painel Network.

Em seguida, clique na entrada para ver mais detalhes.

Os detalhes do problema da COEP são mostrados na guia &quot;Cabeçalhos&quot; depois de clicar em um recurso de rede no painel Network.

Também é possível determinar o status de iframes e janelas de diálogo no painel Aplicativo. Acesse a seção "Frames" no lado esquerdo e expanda "top" para ver a estrutura de recursos detalhada.

É possível verificar o status do iframe, como a disponibilidade de SharedArrayBuffer, etc.

Inspetor de iframe do Chrome DevTools.

Também é possível verificar o status da janela de diálogo, por exemplo, se ela tem isolamento de origem cruzada.

Inspetor de janela de diálogo do Chrome DevTools

Observar problemas usando a API Reporting

A API Reporting é outro mecanismo que você pode usar para detectar vários problemas. É possível configurar a API Reporting para instruir o navegador dos usuários a enviar um relatório sempre que a COEP bloquear o carregamento de um recurso ou a COOP isolar uma janela de diálogo. O Chrome oferece suporte à API Reporting desde a versão 69 para vários usos, incluindo COEP e COOP.

Saiba como configurar a API Reporting e um servidor para receber relatórios.

Exemplo de relatório COEP

Um exemplo de payload de relatório COEP quando o recurso entre origens é bloqueado:

[{
  "age": 25101,
  "body": {
    "blocked-url": "https://third-party-test.example.org/check.svg?",
    "blockedURL": "https://third-party-test.example.org/check.svg?",
    "destination": "image",
    "disposition": "enforce",
    "type": "corp"
  },
  "type": "coep",
  "url": "https://cross-origin-isolation.example.com/?coep=require-corp&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4249.0 Safari/537.36"
}]

Exemplo de relatório de COOP

Veja um exemplo de payload de relatório COOP quando uma caixa de diálogo é aberta de forma isolada:

[{
  "age": 7,
  "body": {
    "disposition": "enforce",
    "effectivePolicy": "same-origin",
    "nextResponseURL": "https://third-party-test.example.org/popup?report-only&coop=same-origin&",
    "type": "navigation-from-response"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.example.com/coop?coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

Quando diferentes grupos de contexto de navegação tentam acessar uns aos outros (somente no modo "somente relatórios"), o COOP também envia um relatório. Por exemplo, um relatório quando postMessage() é tentado seria assim:

[{
  "age": 51785,
  "body": {
    "columnNumber": 18,
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "lineNumber": 83,
    "property": "postMessage",
    "sourceFile": "https://cross-origin-isolation.example.com/popup.js",
    "type": "access-from-coop-page-to-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.example.com/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
},
{
  "age": 51785,
  "body": {
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "property": "postMessage",
    "type": "access-to-coop-page-from-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.example.com/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

Aprendizados

Use uma combinação de cabeçalhos HTTP COOP e COEP para ativar um estado especial de isolamento de origem cruzada em uma página da Web. É possível examinar self.crossOriginIsolated para determinar se uma página da Web está em um estado de isolamento de origem cruzada.

Vamos manter esta postagem atualizada à medida que novos recursos forem disponibilizados para esse estado de isolamento de origem cruzada e outras melhorias forem feitas no DevTools em relação à COOP e à COEP.

Recursos

Atualizações de documentos

  • 21 de junho de 2022: os scripts de worker também precisam de atenção quando o isolamento de origem cruzada está ativado. Adicionamos algumas explicações.
  • 5 de agosto de 2021: a API JS Self-Profiling foi mencionada como uma das APIs que exigem isolamento de origem cruzada, mas, refletindo a mudança recente de direção, ela foi removida.
  • 6 de maio de 2021: com base no feedback e nos problemas relatados, decidimos ajustar o cronograma para que o uso de SharedArrayBuffer em sites sem isolamento de origem cruzada seja restrito no Chrome M92.
  • 16 de abril de 2021: adicionamos observações sobre o modo sem credenciais da COEP e a COOP same-origin-allow-popups como uma condição flexível para o isolamento de origem cruzada.
  • 5 de março de 2021: as limitações para SharedArrayBuffer, performance.measureUserAgentSpecificMemory() e as funcionalidades de depuração foram removidas, e agora estão totalmente ativadas no Chrome 89. Adicionamos os recursos futuros, performance.now() e performance.timeOrigin, que terão maior precisão.
  • 19 de fevereiro de 2021: adicionamos uma observação sobre a política de recursos allow="cross-origin-isolated" e a funcionalidade de depuração no DevTools.
  • 15 de outubro de 2020: o self.crossOriginIsolated está disponível no Chrome 87. Por isso, document.domain é imutável quando self.crossOriginIsolated retorna true. O performance.measureUserAgentSpecificMemory() está encerrando o teste de origem e está ativado por padrão no Chrome 89. O Shared Array Buffer no Chrome para Android vai estar disponível a partir do Chrome 88.