Roteie seu tráfego por Amsterdã e o Google passa a cumprimentar você em holandês. Praticamente todo mundo que usa VPN já esbarrou nesse incômodo e deu de ombros, achando que é só esquisitice de VPN. Esquisitice não é. É o vazamento de que este artigo trata, rodando ao contrário.
A requisição se contradizia. Os pacotes vinham de um endereço IP holandês; os cabeçalhos diziam quais idiomas você de fato lê: Accept-Language: en-US,en;q=0.9. Para escolher o idioma da interface, o Google confia no IP. Um script antifraude numa página de checkout roda a comparação idêntica no sentido oposto: verifica se os idiomas combinam com o IP e arquiva a resposta na sua pontuação de risco. O widget nesta página roda exatamente essa verificação contra o seu navegador, agora mesmo.
Accept-Language: um cabeçalho em toda requisição
Quando seu navegador pede qualquer coisa a um servidor, uma página, uma imagem, uma fonte, ele anexa o cabeçalho HTTP Accept-Language. O cabeçalho existe para que os servidores possam escolher um idioma que você entenda, e é montado a partir da lista de idiomas nas configurações do navegador, que por sua vez herdou o locale do sistema operacional quando o navegador foi instalado. A notação q=0.9 ordena a lista: este navegador prefere inglês americano, e inglês genérico vem logo atrás. A gramática completa está na página do MDN sobre Accept-Language.
Esse cabeçalho está na primeiríssima requisição que você envia. Não depois de algum script carregar, não depois de algum cookie ser gravado. O servidor o lê lado a lado com o endereço IP de origem do pacote:
198.51.100.7 banco de dados geo Amsterdã, NLGET /checkout HTTP/1.1 Host: shop.example User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Accept-Language: en-US,en;q=0.9 ◄ a lista de idiomas do próprio navegador
O JavaScript obtém a mesma informação via navigator.language, e a lista completa via navigator.languages, sem nenhum pedido de permissão no caminho. Repare na diferença em relação ao relógio: um script precisa rodar e perguntar pelo seu fuso horário; seu idioma chega antes de a página ter qualquer script para rodar.
Por que a VPN não muda o idioma do seu navegador
Uma VPN não faz absolutamente nada quanto a isso. O túnel transporta seus pacotes; não os traduz. O que o navegador escreveu é entregue como foi escrito, incluindo o cabeçalho que diz “meu usuário lê inglês, não holandês”. E reescrevê-lo nem está em cogitação: em qualquer site HTTPS, o cabeçalho viaja dentro da sessão TLS entre o navegador e o site, que a VPN não consegue abrir.
O que uma divergência prova, e o que não prova
Idioma é um sinal fraco, mais fraco que o fuso horário. Inglês é o que um sistema operacional tem de mais próximo de uma configuração de fábrica, então um en-US saindo de um IP de Amsterdã, sozinho, não desperta desconfiança nenhuma. A Bélgica funciona com três idiomas oficiais, a Suíça com quatro. Expatriados e quem trabalha remoto leem, legitimamente, um idioma diferente do dos vizinhos. Todo sistema de detecção sério sabe de tudo isso, e é por isso que uma divergência de idioma dá um empurrãozinho na pontuação e nada mais.
Mas o sinal tem uma direção afiada. Um navegador que prefere pt-BR atrás de um IP de saída holandês não é ambíguo como o inglês: ele diz que a pessoa no teclado lê português do Brasil, e a Holanda não tem escassez de endereços IP, mas tem pouquíssimos lares onde o português vem em primeiro lugar. Some isso a um IP de datacenter e a um relógio ainda cravado em America/Sao_Paulo, e os pacotes alegando Amsterdã perderam a discussão:
nl-NL, nl+ IP de Amsterdãconcorda O par conta uma única história. Nada a pontuar.en-US, en+ IP de Amsterdãambíguo Navegador em inglês existe em todo lugar. Um sinal fraco sozinho, mas conta quando outros se acumulam.pt-BR, pt+ IP de Amsterdãdivergência O navegador aponta para o Brasil enquanto os pacotes alegam Holanda. Agora você ficou interessante.- cabeçalho:
nl-NL+ JavaScript:pt-BRfalsificação detectada O navegador discorda de si mesmo, e quase nada além de adulteração deliberada faz isso.
Há um segundo custo, mais silencioso. A composição exata da sua lista, quais idiomas, em que ordem, com quais valores de q, é matéria-prima de fingerprint. O estudo Panopticlick da EFF mediu cerca de seis bits de informação identificadora nos cabeçalhos Accept, e é isso que faz o fingerprinting via Accept-Language funcionar: en-US,en;q=0.9 se esconde na multidão; nl-BE,fr-BE;q=0.9,en;q=0.8,de;q=0.7 é praticamente uma assinatura. Para comparar: sua lista de fontes vaza mais que o dobro de bits, mas um script precisa medi-la, enquanto este cabeçalho se entrega sozinho em cada requisição.
Os fabricantes de navegador sabem disso. O Safari envia apenas o seu idioma principal exatamente por esse motivo, os engenheiros do Chrome têm uma proposta para enxugar o cabeçalho para um único idioma, e o Brave borra deliberadamente a própria resposta site a site. Nada disso ajuda com a divergência, porém: o idioma que sobrevive ao corte continua sendo o seu.
Por que o Google aparece no idioma errado com a VPN ligada
De volta ao Google em holandês. Se os navegadores anunciam educadamente seus idiomas em toda requisição, por que os sites os ignoram assim que você conecta por uma VPN? Porque confiam mais na geolocalização de IP, e confiam desde muito antes de você ter uma VPN. O Google disse isso em alto e bom som em um anúncio de 2017, quando parou de atrelar as versões por país a domínios como google.nl e passou a servir o que quer que a localização detectada indique. O cabeçalho declara uma preferência; o IP é tratado como fato. A mesma hierarquia que irrita você na página inicial do Google é a que um sistema antifraude aplica quando seu cabeçalho e seu IP discordam: o IP vence, e seu cabeçalho é rebaixado de preferência a evidência.
Se o incômodo é o seu problema de verdade, a solução mora nas configurações da sua conta, não nas da VPN: preferências de idioma de quem está logado costumam se sobrepor ao chute do IP no Google e na maioria dos sites grandes. O vazamento, porém, não tem solução em página de configurações, porque o vazamento é o próprio cabeçalho.
A armadilha da falsificação pela metade, de novo
Quem leu o artigo sobre fuso horário já conhece essa armadilha. Aqui ela tem o mesmo formato, e cair nela é ainda mais fácil: o idioma existe em dois lugares, o cabeçalho Accept-Language na rede e navigator.languages no motor JavaScript. Num navegador normal, são duas visões da mesma configuração e sempre concordam. Ferramenta que falsifica um tende a esquecer o outro.
Extensões de spoofing geralmente sobrescrevem o lado JavaScript, porque é o que uma extensão alcança com facilidade; seu cabeçalho continua contando a verdade a todos os servidores. Proxies que reescrevem cabeçalhos fazem o inverso e deixam navigator.languages reportando sua lista real a todo script que perguntar. De um jeito ou de outro, o navegador passa a discordar de si mesmo, e essa contradição vale mais para um sistema de detecção do que a divergência original, porque usuários comuns de VPN produzem divergências o dia inteiro, enquanto só a adulteração deliberada produz contradições. De quebra, um getter de navigator.languages sobrescrito deixa de reportar [native code] quando um script lê seu código-fonte, o indício a que nosso artigo sobre detecção de bots dedica uma seção inteira.
A única falsificação que funciona em escala é a sem graça: na configuração padrão em inglês, o Tor Browser responde en-US,en;q=0.5 para todo mundo, o que esconde seu idioma ao tornar você idêntico a todos os outros usuários do Tor. Essa barganha, proteção ao custo de ser obviamente o Tor, é a versão honesta do que as extensões meia-boca fingem oferecer.
O que realmente fazer
- Rode a verificação. O widget nesta página compara agora mesmo os idiomas do seu navegador com o país do seu IP, usando as mesmas expectativas de idioma por país que um script antifraude usaria. Faça isso com a VPN ligada, porque é dessa configuração que sua pontuação de risco é construída, e emende com o scan completo do navegador para as verificações vizinhas: fuso horário, WebRTC, fingerprints.
- Mova seus idiomas junto com a VPN. A correção limpa espelha o conselho do fuso horário: torne a alegação verdadeira. Adicione o idioma do país de saída à lista do navegador, no Chrome em
chrome://settings/languages, no Firefox em “Idiomas preferidos”, e mantenha o seu de verdade ao lado se quiser; a verificação que a maioria dos sistemas roda é “algum idioma serve?”, não “todos servem?“. Só configure nas opções do próprio navegador em vez de numa extensão, para que o cabeçalho e o JavaScript mudem juntos. - Se você opera múltiplas identidades, isso não é serviço para página de configurações. Cada perfil precisa de idiomas, fuso horário e IP contando uma única história, em toda sessão, e editar configurações na mão, identidade por identidade, não sobrevive ao contato com o trabalho de verdade. O Incogniton define o idioma de cada perfil para combinar com o proxy daquele perfil, no cabeçalho e no JavaScript ao mesmo tempo, para que o navegador nunca discuta com os próprios pacotes.
Seu navegador contou ao último servidor que você visitou qual idioma você lê. O widget acima diz se o seu IP sustenta essa declaração.