Atualizações de SharedArrayBuffer no Chrome 88 para Android e Chrome 92 para computador

É justo dizer que o SharedArrayBuffer teve uma chegada um pouco difícil na Web, mas as coisas estão se acalmando. Veja o que é necessário saber:

Resumo

  • No momento, o SharedArrayBuffer tem suporte no Firefox 79 ou mais recente e vai chegar ao Chrome para Android 88. No entanto, ele só está disponível para páginas isoladas de origem cruzada.
  • No momento, o SharedArrayBuffer está disponível no Chrome para computador, mas, a partir do Chrome 92, ele será limitado a páginas isoladas de origem cruzada. Se você não conseguir fazer essa mudança a tempo, faça um teste de origem para manter o comportamento atual até pelo menos o Chrome 113.
  • Se você pretende ativar o isolamento entre origens para continuar usando SharedArrayBuffer, avalie o impacto que isso terá em outros elementos entre origens no seu site, como posicionamentos de anúncios. Verifique se o SharedArrayBuffer é usado por algum dos seus recursos de terceiros para entender o impacto e as orientações.

Visão geral do isolamento de origem cruzada

É possível tornar uma página isolada entre origens servindo-a com estes cabeçalhos:

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

Depois disso, a página não poderá carregar conteúdo de origem cruzada, a menos que o recurso permita isso explicitamente usando um cabeçalho Cross-Origin-Resource-Policy ou CORS (Access-Control-Allow-* e assim por diante).

Também há uma API de relatórios para coletar dados sobre solicitações que falharam devido a Cross-Origin-Embedder-Policy e Cross-Origin-Opener-Policy.

Se você não conseguir fazer essas mudanças a tempo para o Chrome 92, poderá se inscrever para um teste de origem para manter o comportamento atual do Chrome para computador até pelo menos o Chrome 113.

Consulte a seção Mais informações na parte de baixo desta página para mais orientações e informações sobre o isolamento entre origens.

Como chegamos aqui?

O SharedArrayBuffer chegou no Chrome 60 (julho de 2017, para quem pensa em datas em vez de versões do Chrome), e tudo estava ótimo. Por 6 meses.

Em janeiro de 2018, uma vulnerabilidade foi revelada em algumas CPUs populares. Consulte o anúncio para conferir todos os detalhes, mas, basicamente, isso significa que o código pode usar timers de alta resolução para ler a memória a que não tem acesso.

Isso era um problema para os fornecedores de navegadores, porque queremos permitir que os sites executem códigos em JavaScript e WASM, mas controlamos estritamente a memória que esse código pode acessar. Se você chegar no meu site, não vou conseguir ler nada do site de Internet banking que você também tem aberto. Na verdade, eu nem preciso saber que você tem o site do seu banco on-line aberto. Esses são os princípios básicos da segurança da Web.

Para atenuar isso, reduzimos a resolução dos nossos timers de alta resolução, como performance.now(). No entanto, é possível create um timer de alta resolução usando SharedArrayBuffer, modificando a memória em um loop apertado em um worker e lendo-o em outra linha de execução. Isso não poderia ser mitigado de forma eficaz sem afetar muito o código bem intencionado. Por isso, o SharedArrayBuffer foi desativado completamente.

Uma mitigação geral é garantir que o processo do sistema de uma página da Web não contenha dados sensíveis de outro lugar. O Chrome investiu em uma arquitetura multiprocesso desde o início (lembra do quadrinho?), mas ainda havia casos em que dados de vários sites podiam acabar no mesmo processo:

<iframe src="https://your-bank.example/balance.json"></iframe>
<script src="https://your-bank.example/balance.json"></script>
<link rel="stylesheet" href="https://your-bank.example/balance.json" />
<img src="https://your-bank.example/balance.json" />
<video src="https://your-bank.example/balance.json"></video>
<!-- …and more… -->

Essas APIs têm um comportamento "legado" que permite que o conteúdo de outras origens seja usado sem ativar a outra origem. Essas solicitações são feitas com os cookies da outra origem, então é uma solicitação completa "logada". Atualmente, as novas APIs exigem que a outra origem ative o uso do CORS.

Para contornar esse problema, impedimos que o conteúdo entrasse no processo da página da Web se parecesse "incorreto" e chamamos isso de bloqueio de leitura entre origens. Portanto, nos casos acima, não permitimos que o JSON entre no processo, porque ele não é um formato válido para nenhuma dessas APIs. Exceto iframes. Para iframes, colocamos o conteúdo em um processo diferente.

Com essas mitigações em vigor, reintroduzimos SharedArrayBuffer no Chrome 68 (julho de 2018), mas apenas em computadores. Os requisitos de processo extras significaram que não foi possível fazer o mesmo em dispositivos móveis. Também foi observado que a solução do Chrome estava incompleta, já que estávamos bloqueando apenas formatos de dados "incorretos", enquanto é possível (embora incomum) que CSS/JS/imagens válidos em URLs adivinháveis possam conter dados particulares.

As pessoas responsáveis pelos padrões da Web se reuniram para criar uma solução mais completa para vários navegadores. A solução foi dar às páginas uma maneira de dizer "Renuncio à minha capacidade de trazer conteúdo de outras origens para este processo sem ativar o recurso". Essa declaração é feita por cabeçalhos COOP e COEP transmitidos com a página. O navegador impõe isso, e, em troca, a página ganha acesso a SharedArrayBuffer e outras APIs com poderes semelhantes. Outras origens podem ativar a incorporação de conteúdo usando Cross-Origin-Resource-Policy ou CORS.

O Firefox foi o primeiro a enviar SharedArrayBuffer com essa restrição, na versão 79 (julho de 2020).

Em janeiro de 2021, escrevi este artigo, e você o leu. Olá.

E é isso que estamos fazendo agora. O Chrome 88 traz SharedArrayBuffer de volta ao Android para páginas isoladas de origem cruzada, e o Chrome 92 traz os mesmos requisitos para computadores, tanto para consistência quanto para isolamento total de origem cruzada.

Como atrasar a mudança no Chrome para computador

Essa é uma exceção temporária na forma de um "teste de origem" que dá às pessoas mais tempo para implementar páginas isoladas de origem cruzada. Ele ativa SharedArrayBuffer sem exigir que a página seja isolada entre origens. A exceção expira no Chrome 113 e só se aplica ao Chrome para computador.

  1. Solicite um token para sua origem.
  2. Adicione o token às suas páginas. Há duas maneiras de fazer isso:
    • Adicione uma tag <meta> origin-trial ao cabeçalho de cada página. Por exemplo, ele pode ser parecido com este:
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • Se você puder configurar o servidor, também poderá adicionar o token usando um cabeçalho HTTP Origin-Trial. O cabeçalho de resposta resultante vai parecer mais ou menos assim:
      Origin-Trial: TOKEN_GOES_HERE

Leitura adicional

Foto do banner de Daniel Gregoire no Unsplash