O fingerprinting ativo (a coleta ativa da impressão digital de um cliente) faz perguntas: roda código no seu navegador, mede como um canvas é renderizado, testa quais fontes estão instaladas. O fingerprinting passivo não pergunta nada. Ele só escuta o que você já ia dizer de qualquer jeito. Antes que um único byte de dados da aplicação seja enviado, a conexão já anunciou o perfil do seu sistema operacional, da sua pilha TCP, do seu navegador e da biblioteca que montou a requisição, e não por meio de algum segredo, mas por escolhas comuns e observáveis, que mudam de uma implementação para outra.
Vale entender isso por dois motivos. Primeiro, porque esse é o núcleo honesto da tese de privacidade: você vaza identidade só por existir na rede, e nenhuma configuração fecha esse vazamento por completo. Segundo, porque é assim que a detecção de bots funciona de verdade, e o mecanismo é o mesmo, esteja ele protegendo uma página de login ou traçando o perfil de um visitante. Três camadas, três ferramentas, uma ideia.
Camada 1: a pilha TCP/IP (p0f)
O primeiro pacote de qualquer conexão, o SYN, está cheio de pistas. O inicial, o tamanho da janela TCP, a ordem exata das opções TCP, pequenas peculiaridades nos headers (cabeçalhos) IP e TCP: nada disso pode ser configurado pela aplicação, e tudo isso muda de um sistema operacional para outro e de uma versão de kernel para outra. A ferramenta p0f, escrita originalmente por Michal Zalewski em 2000, lê esses campos nos pacotes que um host emite e os compara com uma base de pilhas conhecidas. Ela nunca envia um probe (um pacote de sondagem); só observa. É isso que a torna passiva, e invisível.
O campo mais útil de todos é o TTL inicial. Como cada roteador no caminho decrementa o TTL, um valor que chega perto de 64 quase certamente saiu com 64, o padrão do Linux, do macOS, do e do Android. O Windows começa com 128. Alguns equipamentos de rede usam 255. O explicador de assinaturas p0f decodifica a assinatura completa, de oito campos, e explica cada campo, mas é no TTL que está a parte mais interessante: quando o TTL da pilha de um pacote diz Linux e o User-Agent que vai por cima diz Windows, você está olhando para um proxy ou para um (tradução de endereços de rede). O pacote carrega o kernel do intermediário, e não o do cliente. Essa contradição não tem como ser forjada na camada de aplicação, e é exatamente por isso que se confia nela.
Camada 2: a string de User-Agent
Uma camada acima, o navegador se apresenta no header User-Agent. Durante quase toda a história da web, essa string foi uma confissão generosa: navegador, versão completa, motor de renderização, sistema operacional, versão, às vezes o modelo do aparelho. Cada token traz um pouco de entropia. Nenhum deles sozinho identifica você (milhões de pessoas rodam o mesmo Chrome no mesmo Windows), mas, somados, eles estreitam o universo de candidatos, e uma string detalhada estreita mais do que uma simples.
O analisador de entropia de User-Agent quebra uma string colada nesses tokens e estima quantos bits de distinção cada um acrescenta. As estimativas são ilustrativas, tiradas de pesquisas publicadas sobre fingerprinting, e não medidas ao vivo; o objetivo não é dar uma nota, mas mostrar um formato: tornar visível a superfície exposta. Ele também aponta a grande mudança em curso. Os navegadores modernos agora congelam o User-Agent: o Chromium fixa a versão secundária (minor) em 0.0.0 e limita o detalhe da plataforma; o Safari fixou boa parte da sua string há muito tempo. O detalhe não sumiu. Ele foi para os User-Agent Client Hints, a família de headers Sec-CH-UA, que o site precisa pedir explicitamente pelo Accept-CH. O resultado é que a coleta de alta entropia agora aparece nos headers da requisição, em vez de ficar implícita numa string enviada sempre; é uma melhoria de privacidade real, ainda que parcial.
Camada 3: a ordem dos próprios headers
Esta é a mais sutil. Mesmo que todos os valores dos headers fossem falsificados com perfeição, a ordem em que o cliente envia os headers já é, ela mesma, um fingerprint. O Chromium envia os headers numa sequência característica, o Firefox em outra, o curl e a biblioteca requests do Python nas suas próprias ordens, enxutas. A sequência está gravada no código do cliente e sobrevive intacta à falsificação dos valores.
É exatamente a mesma ideia do , que identifica um cliente TLS pela ordem das cifras e das extensões no ClientHello, só que levada do handshake (o aperto de mão) do TLS para a requisição HTTP. A ferramenta de fingerprint pela ordem dos headers HTTP classifica um bloco de headers colado comparando a sequência com a de clientes conhecidos e procurando headers que só navegadores enviam, como o Sec-Fetch e o Sec-CH-UA. Uma requisição com o User-Agent do Chrome, mas com a ordem de três headers do curl, não é uma requisição do Chrome; é um script fantasiado, e é a ordem dos headers que o denuncia. Os serviços de detecção de bots e os WAFs (web application firewalls) se baseiam exatamente nisso.
Por que tudo gira em torno da contradição
Repare no fio que passa pelas três camadas: a força não está em nenhum fingerprint isolado, mas na contradição entre eles. Uma pilha que diz Linux, um User-Agent que diz Windows e uma ordem de headers que diz curl não podem estar descrevendo o mesmo cliente honesto. Cada camada já é difícil de forjar sozinha; forjar todas de forma coerente, ao mesmo tempo, é mais difícil ainda. É por isso que o fingerprinting passivo em camadas é a espinha dorsal da detecção de bots, e é por isso que entendê-lo é o primeiro passo para pensar com honestidade no que o anonimato na rede pode e não pode significar.
As três ferramentas daqui só decodificam e explicam. Você cola uma assinatura, uma string ou um bloco de headers que já tem em mãos; nada é lido do seu navegador e nada é enviado para lugar nenhum. O objetivo é mostrar a superfície que um rastreador lê, e não lê-la.
Esta série, em ordem
Este artigo abre a série Fingerprinting do que um cliente emite. Ele percorre as três camadas que um cliente entrega sem ninguém perguntar; as partes da série tratam da mais rica delas, o ClientHello do TLS, do JA3, passando pela mudança que o quebrou, até o , que o substituiu.
- Fingerprinting TLS passivo: JA3, GREASE, e o churn que levou ao JA4. Como o JA3 faz o hash das versões, das cifras e das extensões, por que o precisa ser removido, e a instabilidade (o churn) que veio depois.
- O fingerprint que quebrou e o que o próprio autor escreveu para substituí-lo. O Chrome passou a embaralhar as suas extensões em 2023 e o JA3 parou de funcionar; o substituto, do mesmo autor, funciona porque ordena as extensões.
- O que é um fingerprint TLS JA4?. Como um ClientHello vira um JA4 estável, e o que um JA4 pode e não pode dizer a você.