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

É justo dizer que o SharedArrayBuffer teve um pouso um pouco difícil na Web, mas as coisas estão se acalmando. O que você precisa saber:

Em resumo

  • No momento, o SharedArrayBuffer é compatível com o Firefox 79 ou mais recente e será lançado no Chrome 88 para Android. 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, registre-se para um teste de origem e mantenha 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 posições de anúncio. Verifique se 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

Para isolar uma página de origem cruzada, veicule-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 explicitamente isso usando um cabeçalho Cross-Origin-Resource-Policy ou cabeçalhos CORS (Access-Control-Allow-* e assim por diante).

Há também uma API de relatórios para que você possa coletar dados sobre solicitações que falharam como resultado de Cross-Origin-Embedder-Policy e Cross-Origin-Opener-Policy.

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

Confira a seção Leitura complementar na parte de baixo desta página para mais orientações e informações sobre 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 seis meses.

Em janeiro de 2018, uma vulnerabilidade foi revelada em algumas CPUs populares. Confira o anúncio para mais detalhes. Basicamente, isso significa que o código pode usar timers de alta resolução para ler a memória a que não deveria ter acesso.

Isso era um problema para nós, fornecedores de navegadores, já que queremos permitir que os sites executem código na forma de JavaScript e WASM, mas controlar estritamente a memória que esse código pode acessar. Se você acessar meu site, não devo conseguir ler nada do site de Internet banking que você também tem aberto. Na verdade, não devo nem saber que você tem o site do internet banking aberto. Esses são os fundamentos 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 criar um timer de alta resolução usando SharedArrayBuffer. Para isso, modifique a memória em um loop apertado em um worker e leia de volta em outra linha de execução. Isso não pôde ser mitigado de forma eficaz sem afetar muito o código bem-intencionado. Por isso, o SharedArrayBuffer foi desativado por completo.

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 da história em quadrinhos?), 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 o uso de conteúdo de outras origens sem ativação da outra origem. Essas solicitações são feitas com os cookies da outra origem, então é uma solicitação completa de "login feito". Hoje em dia, as novas APIs exigem que a outra origem faça a ativação usando o CORS.

Para contornar essas APIs legadas, impedimos que o conteúdo entrasse no processo da página da Web se parecesse "incorreto" e chamamos isso de bloqueio de leitura cross-origin. Portanto, nos casos acima, não permitiríamos que o JSON entrasse no processo, já que não é um formato válido para nenhuma dessas APIs. Ou seja, exceto iframes. Para iframes, colocamos o conteúdo em um processo diferente.

Com essas mitigações, reintroduzimos o SharedArrayBuffer no Chrome 68 (julho de 2018), mas apenas em computadores. Os requisitos extras do processo impediram que fizéssemos 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 contenham dados particulares.

As pessoas que trabalham com padrões da Web se reuniram para criar uma solução mais completa entre 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 que elas ativem a opção". Essa declaração é feita por cabeçalhos COOP e COEP fornecidos com a página. O navegador faz isso e, em troca, a página ganha acesso a SharedArrayBuffer e outras APIs com recursos semelhantes. Outras origens podem ativar a incorporação de conteúdo usando Cross-Origin-Resource-Policy ou CORS.

O Firefox foi o primeiro a lançar o 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 é aí que estamos agora. O Chrome 88 traz o 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 alcançar o isolamento total de origem cruzada.

Adiar a mudança do 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 permite o uso de SharedArrayBuffer sem exigir que a página seja isolada entre origens. A exceção expira no Chrome 113 e se aplica apenas 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 origin-trial <meta> ao cabeçalho de cada página. Por exemplo, pode ter esta aparência:
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • Se for possível configurar o servidor, adicione o token usando um cabeçalho HTTP Origin-Trial. O cabeçalho de resposta resultante será parecido com este:
      Origin-Trial: TOKEN_GOES_HERE

Leitura adicional

Foto do banner de Daniel Gregoire no Unsplash