O Chrome 67 no computador tem um novo recurso chamado Isolamento de sites ativado por padrão. Isso explica do que se trata o isolamento de sites, por que ele é necessário e por que os desenvolvedores da Web deveriam esteja ciente disso.
O que é o isolamento de sites?
A Internet é destinada a assistir vídeos de gatos e gerenciar carteiras de criptomoedas, entre outras coisas —
mas você não quer que fluffycats.example
tenha acesso às suas criptomoedas preciosas. Felizmente,
normalmente, os sites não podem acessar os dados uns dos outros dentro do navegador, graças à API Same-Origin
Política Ainda assim, sites maliciosos podem tentar burlar essa política para atacar outros sites, e
às vezes, bugs de segurança são encontrados no código do navegador que aplica a política de mesma origem. A
A equipe do Chrome pretende corrigir esses bugs o mais rápido possível.
O isolamento de sites é um recurso de segurança do Chrome que oferece uma linha de defesa adicional para com menor probabilidade de sucesso desses ataques. Ele garante que as páginas de diferentes sites sejam sempre colocadas em processos diferentes, cada um executado em uma sandbox que limita o que o processo pode fazer. Essa limitação também impede que o processo receba determinados tipos de dados sensíveis de outros sites. Como resultado. Com o isolamento de sites, é muito mais difícil que sites maliciosos usem ataques de canal lateral, como Spectre, para roubar dados de outros sites. Quando a equipe do Chrome terminar restrições adicionais, o isolamento de sites também será útil mesmo quando a página de um invasor puder causar falhas das regras no próprio processo.
Com o isolamento de sites, fica mais difícil para sites não confiáveis acessarem ou roubarem informações. das suas contas em outros sites. Ele oferece proteção adicional contra vários tipos de bugs de segurança, como os recentes ataques de canal lateral Meltdown e Spectre.
Para mais detalhes sobre o isolamento de sites, acesse nosso artigo no blog de segurança do Google (em inglês).
Bloqueio de leitura de origem cruzada
Mesmo quando todas as páginas entre sites são colocadas em processos separados, as páginas ainda podem solicitar legitimamente
alguns sub-recursos entre sites, como imagens e JavaScript. Uma página da Web maliciosa pode usar
<img>
para carregar um arquivo JSON com dados sensíveis, como seu saldo bancário:
<img src="https://your-bank.example/balance.json" />
<!-- Note: the attacker refused to add an `alt` attribute, for extra evil points. -->
Sem o isolamento de sites, o conteúdo do arquivo JSON seria armazenado na memória do renderizador , e o renderizador percebe que não é um formato de imagem válido e não renderiza uma imagem. Mas o invasor poderia explorar uma vulnerabilidade como o Spectre para potencialmente ler essa com um pedaço de memória.
Em vez de usar <img>
, o invasor também pode usar <script>
para comprometer os dados sensíveis com
memória:
<script src="https://your-bank.example/balance.json"></script>
O bloqueio de leitura de origem cruzada (CORB, na sigla em inglês) é um novo recurso de segurança que impede o conteúdo de
balance.json
de entrar na memória do renderizador de processo com base no tipo MIME.
Vamos analisar como a CORB funciona. Um site pode solicitar dois tipos de recursos de um servidor:
- recursos de dados, como documentos HTML, XML ou JSON
- recursos de mídia, como imagens, JavaScript, CSS ou fontes
Um site pode receber recursos de dados da própria origem ou de outras origens com
cabeçalhos CORS permissivos, como
Access-Control-Allow-Origin: *
. Por outro lado, recursos de mídia podem ser incluídos de qualquer
origem, mesmo sem cabeçalhos CORS permissivos.
O CORB impede que o processo do renderizador receba um recurso de dados de origem cruzada (por exemplo, HTML, XML ou JSON) se:
- o recurso tem um cabeçalho
X-Content-Type-Options: nosniff
; - O CORS não permite explicitamente o acesso ao recurso
Se o recurso de dados de origem cruzada não tiver o cabeçalho X-Content-Type-Options: nosniff
definido,
O CORB tenta detectar o corpo da resposta para determinar se é HTML, XML ou JSON. Isso é
necessário porque alguns servidores da Web estão configurados incorretamente e exibem imagens como text/html
, por exemplo.
Os recursos de dados bloqueados pela política do CORB são apresentados ao processo como vazios, embora ela ainda ocorre em segundo plano. Por isso, uma página da Web maliciosa tem dificuldade ou seja, extrair dados entre sites no processo para roubar.
Para ter a melhor segurança e aproveitar os benefícios do CORB, recomendamos o seguinte:
- Marque as respostas com o cabeçalho
Content-Type
correto. Por exemplo, os recursos HTML devem ser disponibilizados comotext/html
, os recursos JSON com um tipo JSON MIME e recursos XML com um tipo XML MIME). - Desative a detecção usando o cabeçalho
X-Content-Type-Options: nosniff
. Sem esse cabeçalho, O Chrome faz uma rápida análise de conteúdo para tentar confirmar se o tipo está correto, mas como esse prefere permitir respostas para evitar o bloqueio de itens como arquivos JavaScript, é melhor fazer a coisa certa por conta própria.
Para mais detalhes, consulte a Artigo do CORB para desenvolvedores Web ou explicação detalhada do CORB (em inglês).
Por que os desenvolvedores Web devem se preocupar com o isolamento de sites?
Em sua maioria, o isolamento de sites é um recurso do navegador que não é diretamente expostos a desenvolvedores Web. Por exemplo, não há nova API exposta à Web para aprender. Em geral, a Web as páginas não devem ser capazes de distinguir a diferença ao serem exibidas com ou sem o isolamento de sites.
No entanto, existem algumas exceções a essa regra. Para ativar o isolamento de sites, há algumas etapas que podem afetar seu site. Mantemos uma lista de problemas conhecidos de isolamento de sites; e detalhamos os mais importantes abaixo.
O layout de página inteira não é mais síncrono
Com o isolamento de sites, não há mais garantia de que o layout de página inteira seja síncrono, uma vez que os frames do uma página agora pode ser distribuída em vários processos. Isso pode afetar as páginas se elas presumirem que um a mudança de layout se propaga imediatamente para todos os frames da página.
Como exemplo, vamos considerar um site chamado fluffykittens.example
que se comunica com uma
widget de rede social hospedado em social-widget.example
:
<!-- https://fluffykittens.example/ -->
<iframe src="https://social-widget.example/" width="123"></iframe>
<script>
const iframe = document.querySelector('iframe');
iframe.width = 456;
iframe.contentWindow.postMessage(
// The message to send:
'Meow!',
// The target origin:
'https://social-widget.example'
);
</script>
Inicialmente, a largura da <iframe>
do widget social é de 123
pixels. Mas a página do FluffyKittens
muda a largura para 456
pixels (acionando o layout) e envia uma mensagem para o widget de rede social,
que tem o seguinte código:
<!-- https://social-widget.example/ -->
<script>
self.onmessage = () => {
console.log(document.documentElement.clientWidth);
};
</script>
Sempre que o widget social recebe uma mensagem pela API postMessage
, ele registra a largura de
seu elemento <html>
raiz.
Qual valor de largura é registrado? Antes de o Chrome ativar o isolamento de sites, a resposta era 456
. Acesso
document.documentElement.clientWidth
força o layout, que costumava ser síncrono antes do Chrome
o isolamento de sites. No entanto, com o isolamento de sites ativado, o widget de redes sociais de origem cruzada
o novo layout agora acontece de forma assíncrona em um processo separado. Dessa forma, a resposta agora também pode ser
123
, ou seja, o valor antigo de width
.
Se uma página mudar o tamanho de um <iframe>
de origem cruzada e enviar um postMessage
para ela com
Isolamento de site: o frame de destino ainda não sabe o novo tamanho ao receber a mensagem. Mais
em geral, isso pode causar falhas nas páginas se elas presumirem que uma mudança de layout é propagada imediatamente para todos
frames na página.
Nesse exemplo específico, uma solução mais robusta definiria width
no frame pai e
detectar essa mudança no <iframe>
detectando um evento resize
.
Gerenciadores de descarregamento podem expirar com mais frequência
Quando um frame navega ou fecha, o documento antigo e todos os subframes incorporados nele
executam o gerenciador unload
. Se a nova navegação ocorre no mesmo processo do renderizador (por exemplo, para
uma navegação de mesma origem), os gerenciadores unload
do documento antigo e dos subframes dele podem ser executados para
muito tempo antes de permitir o commit da nova navegação.
addEventListener('unload', () => {
doSomethingThatMightTakeALongTime();
});
Nessa situação, os gerenciadores unload
em todos os frames são muito confiáveis.
No entanto, mesmo sem o isolamento de sites, algumas navegações do frame principal são em processo cruzado, o que afeta
descarregamento do gerenciador. Por exemplo, se você navegar de old.example
para new.example
digitando
o URL na barra de endereço, a navegação pelo new.example
acontece em um novo processo. O comando de descarregamento
gerenciadores de old.example
e os subframes deles são executados no processo old.example
em segundo plano.
depois que a página new.example
for mostrada, e os gerenciadores de descarregamento antigos serão encerrados
terminar dentro de um determinado tempo limite. Como os gerenciadores de descarregamento podem não terminar antes do tempo limite,
o comportamento de descarregamento
é menos confiável.
Com o isolamento de sites, todas as navegações entre sites se tornam processos cruzados, de modo que os documentos de
sites diferentes não compartilham um processo entre si. Como resultado, a situação acima se aplica
mais casos, e descarregamento de gerenciadores em <iframe>
s geralmente têm os comportamentos em segundo plano e tempo limite.
descritas acima.
Outra diferença resultante do isolamento de sites é a nova ordem paralela de gerenciadores de descarregamento: sem o isolamento de sites, os gerenciadores de descarregamento são executados em uma ordem estrita de cima para baixo nos frames. Mas com o Site Os gerenciadores de isolamento e descarregamento são executados em paralelo em diferentes processos.
Estas são as principais consequências da ativação do isolamento de sites. A equipe do Chrome está trabalhando melhorando a confiabilidade dos gerenciadores de descarregamento para casos de uso comuns, quando possível. Também estamos cientes de bugs em que os gerenciadores de descarregamento de subframes ainda não conseguem utilizar determinados recursos e estão trabalhando para resolvê-los.
Um caso importante para gerenciadores de descarregamento é enviar pings de final da sessão. Isso é comumente feito da seguinte forma:
addEventListener('pagehide', () => {
const image = new Image();
img.src = '/end-of-session';
});
Uma abordagem melhor e mais robusta considerando essa mudança é usar navigator.sendBeacon
.
como alternativa:
addEventListener('pagehide', () => {
navigator.sendBeacon('/end-of-session');
});
Se você precisar de mais controle sobre a solicitação, use a opção keepalive
da API Fetch:
addEventListener('pagehide', () => {
fetch('/end-of-session', {keepalive: true});
});
Conclusão
Com o isolamento de sites, fica mais difícil para sites não confiáveis acessarem ou roubarem informações dos seus contas em outros sites isolando cada site em um processo próprio. Como parte disso, o CORB tenta para manter os recursos de dados sensíveis fora do processo do renderizador. Nossas recomendações acima garantem que você aproveitar ao máximo esses novos recursos de segurança.
Agradecimentos a Alex Moshchuk, Charlie Reis, Jason Miller, Nasko Oskov, Philip Walton, Shubhie Panicker e Thomas steiner por ler uma versão de rascunho deste artigo e dar seu feedback.