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 do user agent são uma nova expansão da API Client Hints, que permite que os desenvolvedores acessem informações sobre o navegador de um usuário de maneira ergonômica e que preserva a privacidade.

Os Client Hints permitem que os desenvolvedores solicitem ativamente informações sobre o dispositivo ou as condições do usuário, em vez de precisar analisá-los na string User-Agent (UA). Fornecer essa rota alternativa é a primeira etapa para reduzir a granularidade da string 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 a análise e personalizar a resposta. Isso foi definido em 1996 (RFC 1945 para HTTP/1.0), onde você pode encontrar a definição original da string User-Agent, que inclui um exemplo:

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

O objetivo desse cabeçalho era 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 User-Agent

Ao longo das décadas, essa string acumulou vários detalhes adicionais sobre o cliente que fez a solicitação, além de lixo, devido à compatibilidade com versões anteriores. Podemos ver isso ao analisar a string 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, além de 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 User-Agent permite muitos casos de uso legítimos e tem uma finalidade importante para desenvolvedores e proprietários de sites. No entanto, também é importante que a privacidade dos usuários seja protegida contra métodos de rastreamento ocultos, e o envio de informações do UA por padrão vai contra essa meta.

Também é necessário melhorar a compatibilidade da Web em relação à string 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 talvez os sites não tenham sido testados em relação à configuração.

Introdução às 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 do cliente (link em inglês) impõem 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ções do 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 mais 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 do cliente, mas aqui está uma breve revisão do processo.

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 escolher enviar os seguintes cabeçalhos em solicitações posteriores:

⬆️ Pedido subsequente

Viewport-Width: 460
Width: 230

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

As dicas do cliente 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 saber todos os detalhes, comece com o explicativo e confira a proposta completa.

Dicas de cliente HTTP do user agent do Chromium 89

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

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

⬆️ Todas as solicitações

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 resposta e solicitação do User-Agent

⬇️ Resposta Accept-CH
⬆️ Cabeçalho da solicitação
⬆️ Valor de exemplo da solicitação
Descrição
Sec-CH-UA "Chromium";v="84",
"Google Chrome";v="84"
Lista de marcas de navegadores e versões significativas.
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 navegadores e as respectivas versões completas.
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" Arquitetura do dispositivo. Embora isso não seja relevante para a exibição da página, o site pode oferecer um download com o formato padrão correto.
Sec-CH-UA-Model "Pixel 3" O modelo do dispositivo.
Sec-CH-UA-Bitness "64" O bitness da arquitetura de destino (ou seja, o tamanho em bits de um endereço de memória ou de número inteiro)

Exemplo de troca

Um exemplo de troca ficaria assim:

⬆️ 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 também pede 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 envia as dicas extras de volta em todas as solicitações posteriores.

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 pelas 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 valores adicionais são acessados pela chamada getHighEntropyValues(). O termo "alta entropia" é uma referência à entropia da informação, ou seja, a quantidade de informações que esses valores revelam sobre o navegador do usuário. Assim como ao solicitar cabeçalhos adicionais, o navegador determina quais valores, se houver, serão retornados.

// 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

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

Duração e redefinição de dicas

As dicas especificadas pelo cabeçalho Accept-CH serã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 vai enviar o cabeçalho Sec-CH-UA-Full-Version-List em todas as solicitações para esse site até que o navegador seja fechado.

⬆️ Solicitações 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, ele substituirá completamente as dicas atuais que o navegador está enviando.

⬇️ Resposta

Accept-CH: Sec-CH-UA-Bitness

⬆️ Solicitações 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 a página, o que significa que o navegador envia as dicas especificadas para todos os sub-recursos dessa página. Embora as dicas persistam até a próxima navegação, o site não deve depender delas nem presumir que elas serão exibidas.

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

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

Escopo de dica e solicitações de origem cruzada

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

Para permitir dicas em solicitações de origem cruzada, cada dica e origem precisa ser especificada por um cabeçalho Permissions-Policy. Para aplicar isso a uma dica de cliente HTTP do user agent, você precisa usar 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"

⬆️ Solicitações para cdn.provider ou img.example.com

DPR: 2

Onde usar as dicas de cliente HTTP do user agent?

A resposta rápida é que você precisa refatorar todas as instâncias em que está analisando o cabeçalho User-Agent ou usando 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 do User-Agent.

Para ir além, examine novamente o uso das informações do User-Agent e substitua-as 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 depender dos dados do User-Agent é que você sempre mantém um mapeamento entre a propriedade que está inspecionando e o comportamento que ela permite. É um custo extra de manutenção para garantir que a detecção seja completa 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 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.

Eventualmente, 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é pelo menos 2022 para dar mais tempo ao ecossistema para avaliar os novos recursos das dicas de cliente do user agent.

Para testar uma versão, ative a flag about://flags/#reduce-user-agent do Chrome 93. Essa flag foi chamada de about://flags/#freeze-user-agent nas versões do Chrome 84 a 92. 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