Use COOP e COEP para configurar um ambiente isolado entre origens e ativar recursos poderosos, como SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
e timer de alta resolução, com maior precisão.
Atualizações
- 21 de junho de 2022: os scripts de worker também precisam de cuidado quando o isolamento entre origens está ativado. Inclusão de 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 recente mudança de direção, 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 nenhum site isolado de origem cruzada seja restrito no Chrome M92. - 16 de abril de 2021: adicionamos notas sobre um novo modo sem credenciais da COEP e COOP same-origin-allow-popups para ser uma condição relaxada para isolamento entre origens.
- 5 de março de 2021: foram removidas as limitações de
SharedArrayBuffer
,performance.measureUserAgentSpecificMemory()
e funcionalidades de depuração, que agora estão totalmente ativadas no Chrome 89. Foram adicionados novos recursos,performance.now()
eperformance.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:
self.crossOriginIsolated
está disponível no Chrome 87.document.domain
é imutável quandoself.crossOriginIsolated
retornatrue
. Operformance.measureUserAgentSpecificMemory()
está encerrando o teste de origem e está ativado por padrão no Chrome 89. O buffer de matriz compartilhada no Chrome para Android vai estar disponível a partir do Chrome 88.
Algumas APIs da Web aumentam o risco de ataques de canal lateral, como Spectre. Para mitigar esse risco, os navegadores oferecem um ambiente isolado baseado em ativação chamado isolado de origem cruzada. Com um estado isolado entre origens, a página da Web poderá usar recursos privilegiados, incluindo:
API | Descrição |
---|---|
SharedArrayBuffer
|
Obrigatório para linhas de execução do WebAssembly. Esse recurso está disponível no Android Chrome 88. No momento, a versão para computador é ativada por padrão com a ajuda do isolamento de sites, mas vai exigir o estado isolado de origem cruzada e será desativado por padrão no Chrome 92. |
performance.measureUserAgentSpecificMemory()
|
Disponível no Chrome 89. |
performance.now() , performance.timeOrigin
|
Disponível atualmente em muitos navegadores com a resolução limitada a 100 microssegundos ou mais. Com o isolamento entre origens, a resolução pode ser de 5 microssegundos ou mais. |
O estado isolado 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 foi considerada uma brecha na
política de mesma origem.
Para ativar um estado isolado entre origens, 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 foram carregados por documentos de origem cruzada e impedem que janelas de origem cruzada interajam diretamente com seu documento. Isso também significa que os recursos carregados entre origens exigem ativações.
Para determinar se uma página da Web está em um estado isolado de origem cruzada,
examine
self.crossOriginIsolated
.
Este artigo mostra como usar esses novos cabeçalhos. Em um artigo de acompanhamento, vou fornecer mais contexto e informações.
Implantar COOP e COEP para isolar o site entre origens diferentes
Integrar COOP e COEP
1. Defina o cabeçalho 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 a partir do documento terão 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
ambas é 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 por <iframe>
.
Se um site (https://a.example
) abrir uma janela pop-up (https://b.example
),
a janela de abertura e a janela pop-up vão compartilhar o mesmo contexto de navegação. Portanto,
elas terão acesso uma à outra por APIs DOM, como window.opener
.
É possível verificar se o abridor de janelas e o aberto estão em grupos de contexto de navegação separados nas Ferramentas do desenvolvedor.
2. Verifique se os recursos têm CORP ou CORS ativados
Verifique se todos os recursos na página são carregados com cabeçalhos CORP ou CORS HTTP. Esta etapa é necessária para a etapa quatro, que ativa a COEP.
Confira o que você precisa fazer dependendo da natureza do recurso:
- Se for esperado que o recurso seja carregado apenas da mesma origem, defina
o cabeçalho
Cross-Origin-Resource-Policy: same-origin
. - Se for esperado que o recurso seja carregado apenas do mesmo site, mas com origem cruzada, defina o cabeçalho
Cross-Origin-Resource-Policy: same-site
. - Se o recurso for carregado de várias origens sob seu controle, defina o
cabeçalho
Cross-Origin-Resource-Policy: cross-origin
, se possível. - Para recursos de origem cruzada sobre os quais você não tem controle:
- Use o atributo
crossorigin
na tag HTML de carregamento se o recurso for encaminhado com CORS. Por exemplo,<img src="***" crossorigin>
. - Peça ao proprietário do recurso para oferecer suporte ao CORS ou CORP.
- Use o atributo
- Para iframes, siga os mesmos princípios acima e defina o
Cross-Origin-Resource-Policy: cross-origin
(ousame-site
,same-origin
, dependendo do contexto). - Os scripts carregados com um
WebWorker
precisam ser disponibilizados da mesma origem. Portanto, você não precisa de um CORP ou cabeçalhos do CORS. - Para um documento ou um worker exibido com
COEP: require-corp
, os sub-recursos de origem cruzada carregados sem CORS precisam definir o cabeçalhoCross-Origin-Resource-Policy: cross-origin
para ativar a incorporação. Por exemplo, isso se aplica a<script>
,importScripts
,<link>
,<video>
,<iframe>
etc.
3. Usar o cabeçalho HTTP somente para relatório COEP para avaliar recursos incorporados
Antes de ativar totalmente a COEP, você pode fazer um teste simulado usando o
cabeçalho Cross-Origin-Embedder-Policy-Report-Only
para examinar se a política
realmente funciona. Você vai receber relatórios sem bloquear conteúdo incorporado.
Aplique isso de forma recursiva a todos os documentos, incluindo o documento de nível superior, frames 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
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 por iframes e scripts de worker.
Determinar se o isolamento foi bem-sucedido com self.crossOriginIsolated
A propriedade self.crossOriginIsolated
retorna true
quando a página da Web está em um
estado isolado entre origens e todos os recursos e janelas estão isolados no
mesmo grupo de contexto de navegação. É possível usar essa API para determinar se você
isolou o grupo de contexto de navegação e obteve acesso a
recursos poderosos, como performance.measureUserAgentSpecificMemory()
.
Depurar problemas usando 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
necessariamente têm um impacto visual, como scripts ou estilos, os problemas de COEP podem
passar despercebidos. Para esses casos, use o painel "Network" do DevTools. Se
houver um problema com a COEP, você verá
(blocked:NotSameOriginAfterDefaultedToSameOriginByCoep)
na coluna
Status.
Clique na entrada para conferir mais detalhes.
Também é possível determinar o status de iframes e janelas pop-up no painel Application. Acesse a seção "Frames" no lado esquerdo e abra "top" para conferir o detalhamento da estrutura de recursos.
É possível verificar o status do iframe, como a disponibilidade de SharedArrayBuffer
etc.
Também é possível verificar o status da janela pop-up, por exemplo, se ela é isolada de origem cruzada.
Observar problemas usando a API Reporting
A API Reporting é outro mecanismo que pode ser usado 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 o COEP bloquear o carregamento de um recurso ou o COOP isolar uma janela pop-up. O Chrome oferece suporte à API Reporting desde a versão 69 para vários usos, incluindo COEP e COOP.
Para saber como configurar a API Reporting e configurar um servidor para receber relatórios, acesse Como usar a API Reporting.
Exemplo de relatório do COEP
Um exemplo de payload de relatório COEP quando o recurso entre origens é bloqueado tem esta aparência:
[{
"age": 25101,
"body": {
"blocked-url": "https://third-party-test.glitch.me/check.svg?",
"blockedURL": "https://third-party-test.glitch.me/check.svg?",
"destination": "image",
"disposition": "enforce",
"type": "corp"
},
"type": "coep",
"url": "https://cross-origin-isolation.glitch.me/?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 COOP
Um exemplo de payload de relatório COOP quando uma janela pop-up é aberta isoladamente é semelhante a este:
[{
"age": 7,
"body": {
"disposition": "enforce",
"effectivePolicy": "same-origin",
"nextResponseURL": "https://third-party-test.glitch.me/popup?report-only&coop=same-origin&",
"type": "navigation-from-response"
},
"type": "coop",
"url": "https://cross-origin-isolation.glitch.me/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ório"), o COOP também envia um relatório. Por exemplo, um relatório quando
postMessage()
é tentado tem esta aparência:
[{
"age": 51785,
"body": {
"columnNumber": 18,
"disposition": "reporting",
"effectivePolicy": "same-origin",
"lineNumber": 83,
"property": "postMessage",
"sourceFile": "https://cross-origin-isolation.glitch.me/popup.js",
"type": "access-from-coop-page-to-openee"
},
"type": "coop",
"url": "https://cross-origin-isolation.glitch.me/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.glitch.me/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"
}]
Conclusão
Use uma combinação de cabeçalhos HTTP COOP e COEP para colocar uma página da Web em um estado especial
isolado entre origens. Você poderá examinar
self.crossOriginIsolated
para determinar se uma página da Web está em um estado isolado
de várias origens.
Vamos manter esta postagem atualizada à medida que novos recursos forem disponibilizados para esse estado isolado de origem cruzada e outras melhorias forem feitas nas DevTools em relação a COOP e COEP.
Recursos
- Por que você precisa de "isolamento entre origens" para recursos avançados
- Um guia para ativar o isolamento de origem cruzada
- Atualizações do SharedArrayBuffer no Chrome 88 para Android e Chrome 92 para computador
- Monitorar o uso total de memória da sua página da Web com
measureUserAgentSpecificMemory()