Como ganhar segurança e privacidade com o particionamento do cache

Em geral, o armazenamento em cache pode melhorar o desempenho armazenando dados para que as solicitações futuras deles sejam exibidas mais rapidamente. Por exemplo, um recurso armazenado em cache da rede pode evitar uma ida e volta ao servidor. Um resultado computacional armazenado em cache pode omitir o tempo para fazer o mesmo cálculo.

No Chrome, o mecanismo de cache é usado de várias maneiras, e o cache HTTP é um exemplo.

Como funciona o cache HTTP do Chrome atualmente

A partir da versão 85, o Chrome armazena em cache os recursos buscados na rede usando os respectivos URLs de recursos como chave de cache. Uma chave de cache é usada para identificar um recurso armazenado em cache.

O exemplo a seguir ilustra como uma única imagem é armazenada em cache e tratada em três contextos diferentes:

Chave de cache: https://x.example/doge.png
Chave de cache: { https://x.example/doge.png }

Um usuário visita uma página (https://a.example) que solicita uma imagem (https://x.example/doge.png). A imagem é solicitada da rede e armazenada em cache usando https://x.example/doge.png como a chave.

Chave de cache: https://x.example/doge.png
Chave de cache: { https://x.example/doge.png }

O mesmo usuário visita outra página (https://b.example), que solicita a mesma imagem (https://x.example/doge.png). O navegador verifica o cache HTTP para ver se ele já tem esse recurso armazenado em cache, usando o URL da imagem como a chave. O navegador encontra uma correspondência no cache e, portanto, usa a versão armazenada do recurso.

Chave de cache: https://x.example/doge.png
Chave de cache: { https://x.example/doge.png }

Não importa se a imagem é carregada de um iframe. Se o usuário visitar outro site (https://c.example) com um iframe (https://d.example) e o iframe solicitar a mesma imagem (https://x.example/doge.png), o navegador ainda poderá carregar a imagem do cache, porque a chave de cache é a mesma em todas as páginas.

Esse mecanismo tem funcionado bem do ponto de vista do desempenho há muito tempo. No entanto, o tempo que um site leva para responder a solicitações HTTP pode revelar que o navegador acessou o mesmo recurso no passado, o que abre o navegador a ataques de segurança e privacidade, como nos exemplos a seguir:

  • Detectar se um usuário visitou um site específico: um invasor pode detectar o histórico de navegação de um usuário verificando se o cache tem um recurso específico para um determinado site ou coorte de sites.
  • Ataque de pesquisa entre sites: um invasor pode detectar se uma string arbitrária está nos resultados da pesquisa do usuário verificando se uma imagem "Nenhum resultado da pesquisa" usada por um site específico está no cache do navegador.
  • Rastreamento entre sites: o cache pode ser usado para armazenar identificadores semelhantes a cookies como um mecanismo de acompanhamento entre sites.

Para reduzir esses riscos, o Chrome particionará seu cache HTTP a partir do Chrome 86.

Como o particionamento de cache afeta o cache HTTP do Google Chrome?

Com o particionamento de cache, os recursos em cache serão codificados usando uma nova "Chave de isolamento de rede", além do URL do recurso. A chave de isolamento de rede é composta pelo site de nível superior e pelo site de frame atual.

Confira novamente o exemplo anterior para entender como o particionamento de cache funciona em diferentes contextos:

Chave do cache { https://a.example, https://a.example, https://x.example/doge.png}
Chave de cache: { https://a.example, https://a.example, https://x.example/doge.png }

Um usuário visita uma página (https://a.example) que solicita uma imagem (https://x.example/doge.png). Nesse caso, a imagem é solicitada pela rede e armazenada em cache usando uma tupla que consiste em https://a.example (o site de nível superior), https://a.example (o site do frame atual) e https://x.example/doge.png (o URL do recurso) como a chave. Quando a solicitação de recurso é do frame de nível superior, o site de nível superior e o site do frame atual na chave de isolamento de rede são os mesmos.

Chave do cache { https://a.example, https://a.example, https://x.example/doge.png}
Chave de cache: { https://b.example, https://b.example, https://x.example/doge.png }

O mesmo usuário visita uma página diferente (https://b.example), que solicita a mesma imagem (https://x.example/doge.png). Ainda que a mesma imagem tenha sido carregada no exemplo anterior, como a chave não corresponde, não será uma ocorrência em cache.

A imagem é solicitada pela rede e armazenada em cache usando uma tupla que consiste em https://b.example, https://b.example e https://x.example/doge.png como a chave.

Chave do cache { https://a.example, https://a.example, https://x.example/doge.png}
Chave de cache: { https://a.example, https://a.example, https://x.example/doge.png }

Agora, o usuário volta para https://a.example, mas, desta vez, a imagem (https://x.example/doge.png) está incorporada em um iframe. Nesse caso, a chave é uma tupla contendo https://a.example, https://a.example e https://x.example/doge.png, e uma ocorrência em cache ocorre. Quando o site de nível superior e o iframe são o mesmo site, o recurso armazenado em cache com o frame de nível superior pode ser usado.

Chave do cache { https://a.example, https://a.example, https://x.example/doge.png}
Chave de cache: { https://a.example, https://c.example, https://x.example/doge.png }

O usuário está de volta em https://a.example, mas desta vez a imagem está hospedada em um iframe de https://c.example.

Nesse caso, a imagem é transferida por download a partir da rede, porque não há nenhum recurso no cache que corresponda à chave que consiste em https://a.example, https://c.example e https://x.example/doge.png.

Chave do cache { https://a.example, https://a.example, https://x.example/doge.png}
Chave de cache: { https://a.example, https://c.example, https://x.example/doge.png }

E se o domínio tiver um subdomínio ou um número de porta? O usuário visita https://subdomain.a.example, que incorpora um iframe (https://c.example:8080), que solicita a imagem.

Como a chave é criada com base em "scheme://eTLD+1", subdomínios e números de porta são ignorados. Portanto, uma ocorrência em cache ocorre.

Chave do cache { https://a.example, https://a.example, https://x.example/doge.png}
Chave de cache: { https://a.example, https://c.example, https://x.example/doge.png }

E se o iframe estiver aninhado várias vezes? O usuário acessa https://a.example, que incorpora um iframe (https://b.example), que incorpora outro iframe (https://c.example), que finalmente solicita a imagem.

Como a chave é extraída do frame superior (https://a.example) e do frame imediato que carrega o recurso (https://c.example), ocorre uma ocorrência em cache.

Perguntas frequentes

Ele já está ativado no meu Chrome? Como posso confirmar?

O recurso será lançado até o final de 2020. Para verificar se sua instância do Chrome já é compatível, faça o seguinte:

  1. Abra chrome://net-export/ e pressione Start Logging to Disk.
  2. Especifique onde salvar o arquivo de registro no seu computador.
  3. Navegue na Web usando o Chrome.
  4. Volte para chrome://net-export/ e pressione Stop Logging.
  5. Vá para https://netlog-viewer.appspot.com/#import.
  6. Pressione Escolher arquivo e transmita o arquivo de registro que você salvou.

A saída do arquivo de registro será exibida.

Na mesma página, localize SplitCacheByNetworkIsolationKey. Se ele for seguido por Experiment_[****], o particionamento de cache HTTP estará ativado no seu Chrome. Se for seguida por Control_[****] ou Default_[****], ela não estará ativada.

Como posso testar o particionamento de cache HTTP no meu Google Chrome?

Para testar o particionamento de cache HTTP no Chrome, inicie o Chrome com uma sinalização de linha de comando: --enable-features=SplitCacheByNetworkIsolationKey. Siga as instruções em Executar o Chromium com flags para saber como iniciar o Chrome com uma sinalização de linha de comando na sua plataforma.

Como desenvolvedor Web, o que eu preciso fazer em resposta a essa mudança?

Essa não é uma alteração interruptiva, mas pode impor considerações de desempenho para alguns serviços da Web.

Por exemplo, aqueles que disponibilizam grandes volumes de recursos altamente armazenáveis em cache em muitos sites (como fontes e scripts conhecidos) podem ter um aumento no tráfego. Além disso, os usuários desses serviços podem depender mais deles.

Há uma proposta para ativar as bibliotecas compartilhadas de uma forma que preserve a privacidade chamada Bibliotecas compartilhadas da Web (vídeo de apresentação), mas ainda está em consideração.

Qual é o impacto dessa mudança de comportamento?

A taxa geral de ausência no cache aumenta cerca de 3,6%, as alterações na FCP (First Contentful Paint) são modestas (aproximadamente 0,3%) e a fração total de bytes carregados pela rede aumenta em cerca de 4%. Saiba mais sobre o impacto no desempenho na explicação sobre o particionamento de cache HTTP.

Isso é padronizado? Os outros navegadores se comportam de maneira diferente?

As "partições de cache HTTP" são padronizadas na especificação de busca, embora os navegadores tenham um comportamento diferente:

  • Chrome: usa o schema://eTLD+1 de nível superior e o schema://eTLD+1 de frame
  • Safari: usa eTLD+1 de nível superior
  • Firefox: planejando implementar com o esquema de nível superior schema://eTLD+1 e considerando incluir uma segunda chave, como o Chrome

Como a busca de workers é tratada?

Workers dedicados usam a mesma chave do frame atual. Os service workers e workers compartilhados são mais complicados, porque podem ser compartilhados entre vários sites de nível superior. A solução para eles ainda está em discussão.

Recursos