Como detectar navegadores headless e automação na página de cadastro
Os sinais do navegador que denunciam cadastros feitos com Puppeteer, Playwright e Selenium, por que cada um pode ser falsificado sozinho e como combiná-los sem bloquear pessoas reais.
Por que os bots agora usam navegadores de verdade
Alguns anos atrás, a maioria dos bots de cadastro eram scripts HTTP simples postando seu formulário direto. Esses são fáceis de barrar: não rodam JavaScript, então nada que sua página calcula no navegador chega. Hoje, a maioria dos bots sérios controla um navegador real com Puppeteer, Playwright ou Selenium, muitas vezes headless, às vezes por um navegador anti-detecção que disfarça a própria impressão digital. Eles rodam seu JavaScript, renderizam a página e preenchem o formulário como uma pessoa faria.
Detectá-los é procurar os pontos em que um navegador automatizado difere de um usado por um humano. Nenhum dos sinais abaixo é prova sozinho — cada um pode ser corrigido por um operador determinado —, mas são baratos de coletar e se somam.
Sinal 1: a flag do WebDriver
Navegadores sob automação do tipo WebDriver definem navigator.webdriver como true. Isso faz parte, de propósito, do padrão WebDriver, e as configurações padrão do Selenium, Puppeteer e Playwright o expõem.
const automated = navigator.webdriver === true;
Plugins “stealth” apagam ou sobrescrevem a flag, então a ausência dela não prova nada. A presença, porém, é quase conclusiva: usuários reais praticamente nunca a têm.
Sinal 2: o user agent headless
O Chrome headless se identifica como HeadlessChrome no user agent, a menos que o operador o sobrescreva. Cheque também no servidor, pelo cabeçalho da requisição, já que o user agent que o navegador informa no JavaScript pode ser diferente do que ele envia.
Sinal 3: um cliente do protocolo DevTools conectado
Puppeteer e Playwright controlam o Chrome pelo protocolo DevTools. Quando um cliente do protocolo escuta eventos do console, registrar um objeto faz o navegador serializá-lo — inclusive lendo propriedades que uma página normal nunca tocaria. Um getter que registra se foi lido é um jeito conhecido de perceber isso:
function devtoolsProtocolAttached() { let read = false; const e = new Error(); Object.defineProperty(e, "stack", { get() { read = true; return ""; } }); console.debug(e); return read; }
Ele também dispara quando um desenvolvedor está com o DevTools aberto, então dê um peso moderado em vez de tratá-lo como veredito.
Sinal 4: renderização por software e janelas estranhas
Navegadores headless em servidores não têm GPU, então o WebGL cai num renderizador por software como SwiftShader ou llvmpipe. Dá para ler o nome do renderizador pela extensão WEBGL_debug_renderer_info, quando o navegador a expõe. Algumas configurações headless também informam uma janela com largura ou altura zero. Máquinas virtuais e áreas de trabalho remotas compartilham essas características, então são sinais fracos sozinhos.
Sinal 5: uma impressão digital que se contradiz
Navegadores anti-detecção existem para parecer muitos navegadores reais diferentes. Fazem isso sobrescrevendo propriedades, e sobrescritas raramente são perfeitamente consistentes. Vale comparar:
- O sistema operacional no user agent versus
navigator.platforme os User-Agent Client Hints. - A família do navegador no user agent versus recursos que só aquele motor tem.
- As fontes instaladas versus as fontes que aquele sistema operacional traz.
- Um canvas desenhado duas vezes seguidas gerando duas imagens diferentes — sinal de ruído injetado.
Notification.permissiondizendo “denied” enquanto a Permissions API diz “prompt”.
Cada contradição é fraca sozinha, porque extensões de privacidade e configurações incomuns produzem algumas delas. Duas ou três juntas formam um padrão forte.
Sinal 6: o token que nunca voltou
Uma técnica simples e robusta: faça o script da página de cadastro pedir um token de vida curta e uso único, coloque-o num campo oculto do formulário e verifique no servidor. Um bot que pula o seu JavaScript chega sem token válido; um que reaproveita um token antigo chega com um token já usado. Você não precisa saber como o bot funciona para perceber que ele nunca rodou sua página direito. Mantenha o token de uso único, ligado ao seu site, e faça-o expirar em minutos.
Sinal 7: comportamento, não impressão digital
Impressão digital pode ser falsificada; comportamento é mais difícil. Uma pessoa lê o formulário, move o ponteiro e digita. Um script preenche os campos e envia em algumas centenas de milissegundos depois de a página carregar, sem nenhum evento de entrada confiável.
A medição confiável não precisa de software extra: seu agente emite o token do visitante quando a página carrega, e o servidor compara esse horário com o momento da checagem. Menos de cerca de um segundo entre carregar e se cadastrar é script. Quando o agente também consegue informar eventos de entrada confiáveis, um envio instantâneo sem nenhum evento de ponteiro, tecla ou toque é uma segunda confirmação independente.
Uma ressalva sobre o sinal 3: no Chrome atual, o truque do DevTools só dispara quando o cliente de automação assina os eventos do console, então trate-o como bônus e não como detector principal.
Combine; não bloqueie por um sinal só
Trate cada sinal como pontos numa pontuação e decida pelo total. Uma ponderação razoável para começar, do mais forte para o mais fraco:
| Sinal | Peso | Por quê |
|---|---|---|
navigator.webdriver true | alto | Quase nunca é true para usuários reais |
| User agent HeadlessChrome | alto | Só versões headless o enviam |
| Token ausente ou reutilizado | alto | O script da página não rodou, ou rodou uma vez para vários cadastros |
| Protocolo DevTools conectado | médio | Desenvolvedores com DevTools aberto também disparam |
| Contradições de SO ou navegador | médio | Sobrescritas anti-detecção, mas também algumas extensões |
| Renderização por software, janela zero | baixo | VMs e áreas de trabalho remotas também têm |
Junte os sinais do navegador com os do servidor — cadastros de faixas de IP de nuvem, rajadas de uma sub-rede, contas ligadas ao mesmo dispositivo — e pouquíssimos bots vão parecer limpos em todos ao mesmo tempo.
O que não fazer
- Não bloqueie só pela ausência de plugins ou idiomas. Navegadores reforçados para privacidade os removem.
- Não publique sua lógica de detecção como checagens com nomes óbvios que um operador possa procurar e corrigir de uma vez; colete fatos brutos no navegador e decida no servidor.
- Não confie cegamente em nada que o navegador informa. O cliente está sob controle do bot. A verificação acontece no seu servidor, com o seu segredo.
Como o Attrelix faz
O agente do Attrelix coleta esses fatos do navegador e um token de visitante de uso único na sua página de cadastro; o servidor os combina com sinais de rede, caixa de e-mail e contas ligadas numa única pontuação. Todos os pesos são públicos na documentação, e nenhum sinal fraco sozinho leva um cadastro para revisão.
Resumo
- Bots modernos rodam navegadores reais; procure onde a automação difere de um humano.
- WebDriver, user agent headless e tokens ausentes são fortes; o resto é fraco, mas soma.
- Decida no servidor, por pontuação, nunca por uma única flag do navegador.