Como melhorar a privacidade do usuário e a experiência do desenvolvedor com as dicas de cliente HTTP do user agent

As dicas de cliente HTTP do user agent são uma nova expansão da API Client Hints. Com elas, os desenvolvedores podem acessar informações sobre o navegador de um usuário de maneira ergonômica e que preserva a privacidade.

As dicas de cliente permitem que os desenvolvedores solicitem ativamente informações sobre o dispositivo ou as condições do usuário, em vez de precisar analisá-las fora da string do user agent (UA). Fornecer essa rota alternativa é a primeira etapa para reduzir a granularidade da string do user agent.

Aprenda a atualizar a funcionalidade existente que depende da análise da string do user agent para usar as dicas de cliente do user agent.

Contexto

Quando os navegadores da Web fazem solicitações, eles incluem informações sobre o navegador e o ambiente dele para que os servidores possam ativar análises e personalizar a resposta. Isso foi definido desde 1996 (RFC 1945 para HTTP/1.0), em que você encontra a definição original da string do user agent, que inclui um exemplo:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

Esse cabeçalho serve para especificar, em ordem de importância, o produto (por exemplo, navegador ou biblioteca) e um comentário (por exemplo, versão).

O estado da string do user agent

Nas décadas intermediárias, essa string acumulou vários detalhes adicionais sobre o cliente que fez a solicitação, além de itens indesejados, devido à compatibilidade com versões anteriores. Podemos ver que, ao analisar a string do user agent atual do Chrome:

Mozilla/5.0 (Linux; Android 10; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4076.0 Mobile Safari/537.36

A string acima contém informações sobre o sistema operacional e a versão do usuário, o modelo do dispositivo, a marca e a versão completa do navegador, pistas suficientes para inferir que é um navegador para dispositivos móveis e sem mencionar várias referências a outros navegadores por motivos históricos.

A combinação desses parâmetros com a grande diversidade de valores possíveis significa que a string do user agent pode conter informações suficientes para permitir que os usuários individuais sejam identificados de maneira exclusiva.

A string do user agent permite muitos casos de uso legítimos e serve a um propósito importante para desenvolvedores e proprietários de sites. No entanto, também é fundamental que a privacidade dos usuários seja protegida contra métodos de rastreamento oculto, e o envio de informações do UA por padrão vai contra essa meta.

Também é necessário melhorar a compatibilidade com a Web quando se trata da string do user agent. Ele é desestruturado, portanto, a análise resulta em complexidade desnecessária, que geralmente é a causa de bugs e problemas de compatibilidade de sites que prejudicam os usuários. Esses problemas também prejudicam de maneira desproporcional os usuários de navegadores menos comuns, porque os sites podem não ter sido testados em relação à configuração.

Apresentação das novas dicas de cliente HTTP do user agent

As dicas de cliente HTTP do user agent permitem acessar as mesmas informações, mas preservando a privacidade, permitindo que os navegadores reduzam o padrão de transmissão de tudo da string do user agent. As dicas de cliente aplicam um modelo em que o servidor precisa solicitar ao navegador um conjunto de dados sobre o cliente (as dicas) e o navegador aplica as próprias políticas ou configuração de usuário para determinar quais dados são retornados. Isso significa que, em vez de expor todas as informações do user agent por padrão, o acesso agora é gerenciado de maneira explícita e auditável. Os desenvolvedores também se beneficiam de uma API mais simples, sem as expressões regulares.

O conjunto atual de dicas do cliente descreve principalmente os recursos de exibição e conexão do navegador. Confira os detalhes em Como automatizar a seleção de recursos com dicas de cliente, mas vamos relembrar o processo rapidamente.

O servidor solicita dicas de cliente específicas por meio de um cabeçalho:

⬇️ Resposta do servidor

Accept-CH: Viewport-Width, Width

Ou uma metatag:

<meta http-equiv="Accept-CH" content="Viewport-Width, Width" />

O navegador pode optar por enviar os cabeçalhos abaixo de volta nas solicitações subsequentes:

⬆️ Solicitação posterior

Viewport-Width: 460
Width: 230

O servidor pode optar por variar as respostas, por exemplo, exibindo imagens em uma resolução apropriada.

As dicas de cliente HTTP do user agent ampliam o intervalo de propriedades com o prefixo Sec-CH-UA que pode ser especificado pelo cabeçalho de resposta do servidor Accept-CH. Para conferir todos os detalhes, comece com a explicação e se aprofunde na proposta completa.

Dicas de cliente HTTP do user agent do Chromium 89

As dicas de cliente HTTP do user agent são ativadas por padrão no Chrome desde a versão 89.

Por padrão, o navegador retorna a marca do navegador, a versão significativa / principal, a plataforma e um indicador se o cliente for um dispositivo móvel:

⬆️ Todos os pedidos

Sec-CH-UA: "Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "macOS"

Cabeçalhos de solicitação e resposta do user agent

⬇️ Resposta Accept-CH
⬆️ Cabeçalho da solicitação
⬆️ Valor
de solicitação
Descrição
Sec-CH-UA "Chromium";v="84",
"Google Chrome";v="84"
Lista de marcas de navegadores e as versões relevantes delas.
Sec-CH-UA-Mobile ?1 Booleano que indica se o navegador está em um dispositivo móvel (?1 para verdadeiro) ou não (?0 para falso).
Sec-CH-UA-Full-Version "84.0.4143.2" [Descontinuado]A versão completa do navegador.
Sec-CH-UA-Full-Version-List "Chromium";v="84.0.4143.2",
"Google Chrome";v="84.0.4143.2"
Lista de marcas de navegador e a versão completa delas.
Sec-CH-UA-Platform "Android" A plataforma do dispositivo, geralmente o sistema operacional (SO).
Sec-CH-UA-Platform-Version "10" A versão da plataforma ou do SO.
Sec-CH-UA-Arch "arm" A arquitetura subjacente do dispositivo. Embora isso possa não ser relevante para a exibição da página, o site pode oferecer um download com o formato correto por padrão.
Sec-CH-UA-Model "Pixel 3" O modelo do dispositivo.
Sec-CH-UA-Bitness "64" A quantidade de bits da arquitetura subjacente (ou seja, o tamanho em bits de um número inteiro ou endereço de memória)

Exemplo de troca

Confira um exemplo de troca:

⬆️ Solicitação inicial do navegador
O navegador está solicitando a página /downloads do site e envia o user agent básico padrão.

GET /downloads HTTP/1.1
Host: example.site

Sec-CH-UA: "Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"
Sec-CH-UA-Mobile: ?1
Sec-CH-UA-Platform: "Android"

⬇️ Resposta do servidor
O servidor envia a página de volta e solicita a versão completa do navegador e a plataforma.

HTTP/1.1 200 OK
Accept-CH: Sec-CH-UA-Full-Version-List

⬆️ Solicitações subsequentes
O navegador concede ao servidor acesso às informações adicionais e as envia de volta em todas as solicitações subsequentes.

GET /downloads/app1 HTTP/1.1
Host: example.site

Sec-CH-UA: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"
Sec-CH-UA-Mobile: ?1
Sec-CH-UA-Full-Version-List: " Not A;Brand";v="99.0.0.0", "Chromium";v="98.0.4738.0", "Google Chrome";v="98.0.4738.0"
Sec-CH-UA-Platform: "Android"

JavaScript API

Além dos cabeçalhos, o user agent também pode ser acessado em JavaScript via navigator.userAgentData. As informações padrão dos cabeçalhos Sec-CH-UA, Sec-CH-UA-Mobile e Sec-CH-UA-Platform podem ser acessadas usando as propriedades brands e mobile, respectivamente:

// Log the brand data
console.log(navigator.userAgentData.brands);

// output
[
  {
    brand: 'Chromium',
    version: '93',
  },
  {
    brand: 'Google Chrome',
    version: '93',
  },
  {
    brand: ' Not;A Brand',
    version: '99',
  },
];

// Log the mobile indicator
console.log(navigator.userAgentData.mobile);

// output
false;

// Log the platform value
console.log(navigator.userAgentData.platform);

// output
"macOS";

Os outros valores são acessados pela chamada getHighEntropyValues(). O termo "alta entropia" é uma referência à entropia de informações, ou seja, a quantidade de informações que esses valores revelam sobre o navegador do usuário. Assim como na solicitação de cabeçalhos adicionais, depende do navegador quais valores são retornados, se houver.

// Log the full user-agent data
navigator
  .userAgentData.getHighEntropyValues(
    ["architecture", "model", "bitness", "platformVersion",
     "fullVersionList"])
  .then(ua => { console.log(ua) });

// output
{
   "architecture":"x86",
   "bitness":"64",
   "brands":[
      {
         "brand":" Not A;Brand",
         "version":"99"
      },
      {
         "brand":"Chromium",
         "version":"98"
      },
      {
         "brand":"Google Chrome",
         "version":"98"
      }
   ],
   "fullVersionList":[
      {
         "brand":" Not A;Brand",
         "version":"99.0.0.0"
      },
      {
         "brand":"Chromium",
         "version":"98.0.4738.0"
      },
      {
         "brand":"Google Chrome",
         "version":"98.0.4738.0"
      }
   ],
   "mobile":false,
   "model":"",
   "platformVersion":"12.0.1"
}

Demonstração

Você pode testar os cabeçalhos e a API JavaScript no seu dispositivo em user-agent-client-hints.glitch.me.

Vida útil e redefinição da dica

As dicas especificadas pelo cabeçalho Accept-CH são enviadas durante a sessão do navegador ou até que um conjunto diferente de dicas seja especificado.

Isso significa que, se o servidor enviar:

⬇️ Resposta

Accept-CH: Sec-CH-UA-Full-Version-List

Em seguida, o navegador enviará o cabeçalho Sec-CH-UA-Full-Version-List em todas as solicitações para esse site até que seja fechado.

⬆️ Pedidos subsequentes

Sec-CH-UA-Full-Version-List: " Not A;Brand";v="99.0.0.0", "Chromium";v="98.0.4738.0", "Google Chrome";v="98.0.4738.0"

No entanto, se outro cabeçalho Accept-CH for recebido, isso substituirá completamente as dicas atuais que o navegador está enviando.

⬇️ Resposta

Accept-CH: Sec-CH-UA-Bitness

⬆️ Pedidos subsequentes

Sec-CH-UA-Platform: "64"

O Sec-CH-UA-Full-Version-List solicitado anteriormente não será enviado.

É melhor pensar no cabeçalho Accept-CH como a especificação do conjunto completo de dicas desejado para essa página, o que significa que o navegador envia as dicas especificadas para todos os sub-recursos dessa página. Embora as dicas sejam mantidas na próxima navegação, o site não pode confiar nem presumir que elas serão entregues.

Você também pode usar isso para limpar de maneira eficaz todas as dicas enviadas pelo navegador enviando um Accept-CH em branco na resposta. Adicione essa informação sempre que o usuário estiver redefinindo preferências ou sair do site.

Esse padrão também corresponde a como as dicas funcionam usando a tag <meta http-equiv="Accept-CH" …>. As dicas solicitadas só vão ser enviadas em solicitações iniciadas pela página, e não em qualquer navegação subsequente.

Escopo de dica e solicitações de origem cruzada

Por padrão, as dicas de cliente serão enviadas somente em solicitações de mesma origem. Isso significa que se você pedir dicas específicas sobre https://example.com, mas os recursos que quer otimizar estiverem em https://downloads.example.com, eles não vão receber nenhuma.

Para permitir dicas em solicitações de origem cruzada, cada dica e origem precisam ser especificadas por um cabeçalho Permissions-Policy. Para aplicar isso a uma dica de cliente do user agent, você precisa colocar a dica em letras minúsculas e remover o prefixo sec-. Exemplo:

⬇️ Resposta de example.com

Accept-CH: Sec-CH-UA-Platform-Version, DPR
Permissions-Policy: ch-ua-platform-version=(self "downloads.example.com"),
                    ch-dpr=(self "cdn.provider" "img.example.com");

⬆️ Solicitação para downloads.example.com

Sec-CH-UA-Platform-Version: "10"

⬆️ Pedidos para cdn.provider ou img.example.com

DPR: 2

Onde usar as dicas de cliente HTTP do user agent?

A resposta rápida é refatorar todas as instâncias em que você está analisando o cabeçalho User-Agent ou fazendo uso de qualquer uma das chamadas de JavaScript que acessam as mesmas informações (ou seja, navigator.userAgent, navigator.appVersion ou navigator.platform) para usar as dicas de cliente HTTP do user agent.

Indo mais além, você deve reexaminar o uso das informações do user agent e substituí-las por outros métodos sempre que possível. Muitas vezes, você pode alcançar o mesmo objetivo usando o aprimoramento progressivo, a detecção de recursos ou o design responsivo. O problema básico de confiar nos dados do user agent é que você está sempre mantendo um mapeamento entre a propriedade inspecionada e o comportamento ativado. É uma sobrecarga de manutenção para garantir que sua detecção seja abrangente e permaneça atualizada.

Com essas advertências em mente, o repositório de dicas de cliente HTTP do user agent lista alguns casos de uso válidos para sites.

O que acontece com a string do user agent?

O plano é minimizar a capacidade de rastreamento oculto na Web, reduzindo a quantidade de informações de identificação expostas pela string do user agent atual, sem causar interrupções indevidas nos sites atuais. Com as dicas de cliente HTTP do user agent, você tem a chance de entender e testar o novo recurso antes que qualquer alteração seja feita nas strings do user agent.

Finalmente, as informações na string do user agent vão ser reduzidas para manter o formato legado, fornecendo apenas o mesmo navegador de alto nível e informações de versão significativas, conforme as dicas padrão. No Chromium, essa mudança foi adiada até, no mínimo, 2022. Assim, o ecossistema terá mais tempo para avaliar os novos recursos de dicas de cliente do user agent.

É possível testar uma versão disso ativando a sinalização about://flags/#reduce-user-agent no Chrome 93. Observação: essa sinalização era chamada de about://flags/#freeze-user-agent nas versões 84 a 92 do Chrome. Isso vai retornar uma string com as entradas históricas por motivos de compatibilidade, mas com detalhes corrigidos. Por exemplo, algo como:

Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36

Miniatura de Sergey Zolkin no Unsplash