O mesmo script passa no seu notebook e é barrado no runner de CI. Não é cota nem azar: o reCAPTCHA v3 não devolve "aprovado" ou "reprovado", e sim uma nota de 0,0 (certamente um bot) a 1,0 (certamente humano) montada a partir de cinco grupos de sinais que não pesam igual.
Resposta curta: comportamento na página é o que mais move a nota, sinais do navegador vêm logo atrás, e rede, histórico e ambiente ajustam nas bordas.
O Google nunca publicou a fórmula do motor de Análise Avançada de Risco (ARA), mas testes públicos mostram quais famílias de sinais mexem no resultado.
Abaixo, os cinco grupos, o peso típico de cada sinal e um roteiro de diagnóstico para QA autorizado.
Como a pontuação do reCAPTCHA v3 é montada
O valor que chega ao seu backend pela API siteverify é o resultado de uma função sobre sinais coletados durante toda a visita, não apenas no clique de envio:
Final Score = f(Browser Signals, Behavioral Signals, Network Signals,
History Signals, Environmental Signals)
Da maior para a menor influência: comportamento na página (peso muito alto), sinais do navegador (alto), rede — IP e TLS — (médio-alto), histórico e cookies (médio) e coerência do ambiente (baixo a médio).
Sinais fracos se somam: um item isolado raramente leva a nota de 0,9 para 0,1; três ou quatro medianos ao mesmo tempo, sim.
Grupo 1: sinais do navegador, o que o JavaScript entrega
A pergunta é uma só: do outro lado há um navegador real ou uma ferramenta de automação?
APIs que o modo headless implementa de outro jeito
O reCAPTCHA consulta APIs que navegadores headless não têm ou expõem diferente:
| API verificada | Esperado em navegador real | Indício de modo headless |
|---|---|---|
| Sinalizador de automação do navegador | undefined ou false |
true (Selenium, Puppeteer) |
navigator.plugins |
PluginArray com um ou mais itens | vazio ou ausente |
navigator.languages |
array com strings de locale | array vazio ou ausente |
navigator.hardwareConcurrency |
2 a 16, compatível com a CPU | às vezes 0 ou indefinido |
navigator.deviceMemory |
2 a 16 GB | ausente em parte dos modos headless |
window.chrome |
objeto com runtime e afins |
ausente no Chrome headless |
Notification.permission |
"default", "granted" ou "denied" | lança erro ou não existe |
Impacto na nota: valores ausentes ou incoerentes custam de 0,3 a 0,5 ponto.
Sinal de canvas
O reCAPTCHA desenha canvas ocultos e lê os pixels de volta — o resultado é um sinal característico da combinação navegador/sistema/GPU:
// reCAPTCHA performs something similar to:
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.textBaseline = "top";
ctx.font = "14px 'Arial'";
ctx.fillText("Hello", 2, 2);
const sinal de navegador = canvas.toDataURL();
Impacto na nota:
- Sinal coerente com o navegador e o sistema declarados → neutro
- Sinal igual a um padrão conhecido de modo headless → -0,3 a -0,5
- Operações de canvas bloqueadas ou devolvendo dados uniformes → -0,4 a -0,6
Renderizador WebGL
A string do renderizador WebGL entrega a GPU:
const gl = document.createElement('canvas').getContext('webgl');
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
// Expected: "ANGLE (NVIDIA GeForce GTX 1060...)"
// Headless: "SwiftShader" or "Google SwiftShader"
Impacto na nota: SwiftShader, renderizador por software do Chrome headless, é indício forte de automação e custa de 0,3 a 0,5 ponto.
Grupo 2: rede, o que o IP e o TLS contam antes do JavaScript rodar
É avaliado antes de qualquer script rodar e é o mais barato de testar: comece o diagnóstico por ele.
Reputação de IP
O Google mantém uma base de reputação de IP alimentada por:
- Resultados anteriores de desafios reCAPTCHA vindos daquele IP
- Faixas conhecidas de data center (AWS, GCP, Azure, DigitalOcean e outras)
- Faixas conhecidas de provedores de proxy e VPN
- Denúncias de abuso e listas de spam
- Sinais de fraude em busca e publicidade
| Tipo de IP | Impacto típico na nota |
|---|---|
| Residencial com pouco histórico de abuso | neutro a +0,1 |
| Residencial com algum histórico de abuso | -0,1 a -0,2 |
| Faixa de data center | -0,3 a -0,5 |
| Faixa conhecida de proxy ou VPN | -0,2 a -0,4 |
| Nó de saída Tor | -0,4 a -0,6 |
| IP sinalizado por abuso recentemente | -0,3 a -0,6 |
Sinal de TLS (JA3/JA4)
O handshake TLS revela cifras e extensões suportadas, e cada cliente tem assinatura própria:
- Chrome: ordem de cifras específica, TLS 1.3, extensões GREASE
- Biblioteca
requestsdo Python: outra ordem de cifras, sem GREASE, lista de extensões mais simples - cURL: extensões mínimas, padrões característicos do OpenSSL
Impacto na nota: sinal de TLS que não corresponde a nenhum navegador → -0,2 a -0,4.
Cabeçalhos HTTP
O servidor do reCAPTCHA também lê os cabeçalhos:
| Cabeçalho | Indício de pessoa | Indício de automação |
|---|---|---|
User-Agent |
corresponde a uma versão real do navegador | versão desatualizada ou UA de ferramenta |
Accept-Language |
preenchido com preferências de locale | ausente ou genérico |
Accept-Encoding |
gzip, deflate, br |
ausente ou incomum |
Sec-CH-UA |
client hints coerentes com o navegador | ausente (padrão anterior a 2022) |
Grupo 3: comportamento, o que mais move a pontuação
Coletados desde o carregamento da página, os sinais de comportamento dominam o cálculo. É aqui que a automação mais escorrega.
Movimento do mouse
O reCAPTCHA acompanha coordenadas e tempos do ponteiro durante a visita:
| Sinal | Padrão de pessoa | Padrão de automação |
|---|---|---|
| Quantidade de eventos | 50 a 500 ou mais por visita | 0 a 5 eventos |
| Trajetória | curvas com velocidade variável | linhas retas em velocidade constante |
| Aceleração | ease-in/ease-out natural | início e parada instantâneos |
| Micromovimentos | pequenos tremores ao pairar | imobilidade perfeita entre ações |
| Ultrapassagem do alvo | passa um pouco do alvo e corrige | mira exata |
Impacto na nota: ausência total de movimento do mouse custa de 0,4 a 0,7 ponto, o maior desconto isolado da lista.
Digitação
Inter-key timing:
Human: Variable (50-300ms between keys, varies by key pair)
Bot: Constant (all keys at same interval, or instant paste)
Key events:
Human: keydown → keypress → keyup for each character
Bot: May skip keypress, or fire all events simultaneously
Corrections:
Human: Occasional backspace, re-typing
Bot: Perfect input without corrections
Impacto na nota: texto inserido de uma vez, por área de transferência ou por value em JavaScript, tira de 0,1 a 0,2.
Rolagem
- Pessoas: rolagem gradual, com inércia, velocidade variável e pausas de leitura
- Automação: nenhuma rolagem, ou salto instantâneo até o formulário
Impacto na nota: nenhum evento de rolagem antes da interação com o formulário → -0,2 a -0,3.
Ordem de interação com os elementos
O reCAPTCHA registra com quais elementos houve interação e em que ordem.
- Pessoas: clicam pela página, passam o mouse por links, leem antes de preencher
- Automação: vai direto aos campos, preenche na ordem do DOM e envia
Impacto na nota: ir direto ao formulário, sem explorar a página → -0,1 a -0,3.
Grupo 4: histórico, cookies e reputação acumulada
Aqui o reCAPTCHA olha para trás: o que esse navegador já fez antes, dentro e fora do seu site.
Cookies de conta Google
Quem está logado em uma conta Google, com histórico, começa em nota mais alta:
- Cookies
SID,HSID,SSID→ existe sessão do Google no navegador - Sem cookies do Google → visitante desconhecido, nota inicial mais baixa
Impacto na nota: sessão ativa do Google → +0,1 a +0,3.
Cookies do próprio reCAPTCHA
Depois de um desafio concluído, o reCAPTCHA grava os próprios cookies:
_GRECAPTCHA→ houve resolução bem-sucedida anteriorrc::a,rc::b,rc::c→ dados da análise de risco
Impacto na nota: sessão nova, sem nenhum cookie do reCAPTCHA → -0,1 a -0,2.
Reputação entre sites
- O Google observa o mesmo perfil de navegador em todos os sites que usam reCAPTCHA: histórico limpo no site A melhora a nota no site B.
- Perfis descartados a cada execução do pipeline nunca acumulam esse crédito.
Grupo 5: coerência do ambiente
Peso menor, mas é onde imagens de CI mais produzem incoerências bobas.
Fuso horário
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
// Should match IP geolocation
// "America/New_York" with a New York IP → consistent
// "America/New_York" with a Tokyo IP → suspicious
Impacto na nota: isolado, o desconto é pequeno; somado a um IP de data center, passa a pesar.
Tela e janela
screen.width, screen.height // Physical screen
window.innerWidth, innerHeight // Browser window
window.outerWidth, outerHeight // Including browser chrome
Impacto na nota: dimensões incomuns (0×0, gigantescas ou o padrão de fábrica) → -0,1 a -0,2.
Status da bateria, quando disponível
navigator.getBattery().then(battery => {
battery.level; // 0.0 to 1.0
battery.charging; // true/false
});
A API de bateria é um sinal menor: estar sempre carregando é coerente com uma estação de trabalho.
Diagnóstico: por que a pontuação despenca para 0,1 no CI
Cenário comum em times brasileiros: a regressão roda em workers na região sa-east-1 (São Paulo) da AWS, contra o próprio staging. Na máquina do desenvolvedor a nota fica perto de 0,8; no pipeline cai para 0,1 e aparece desafio de imagem.
O site não mudou — mudaram três sinais juntos: IP em faixa de data center, navegador headless e nenhum evento de ponteiro antes do envio. Somados os intervalos das tabelas acima, 0,1 deixa de ser mistério.
Isole um sinal por vez, em ambiente próprio e com dados fictícios:
| Verificação no ambiente de teste | Efeito típico na nota | Esforço |
|---|---|---|
| Chrome real em vez de modo headless | +0,3 a +0,5 | baixo |
| Perfil padrão, sem flags de automação | +0,2 a +0,3 | baixo |
| Interação real: ponteiro, rolagem e digitação com intervalos | +0,2 a +0,4 | médio |
| Egress de rede autorizado, fora de faixa de data center | +0,2 a +0,3 | baixo (custo) |
| Cookies preservados entre execuções do mesmo perfil | +0,1 a +0,2 | médio |
| Sinal de TLS alinhado ao navegador declarado | +0,1 a +0,3 | alto |
| Navegação pela página antes de chegar ao formulário | +0,1 a +0,2 | médio |
Duas ressalvas. Os intervalos são indicativos, observados por terceiros em implementações públicas, e variam por site e por action: meça no seu próprio ambiente.
A segunda: ao registrar sessões de QA, guarde só o necessário — esses logs podem conter dados pessoais, no escopo da LGPD (RGPD em Portugal).
Quando parar de perseguir sinais e usar a API
Há um ponto em que manter navegador real, perfis aquecidos e egress dedicado custa mais do que o teste entrega. Dali em diante, delegue: envie a tarefa, consulte o resultado e receba o token g-recaptcha-response.
import requests
import time
API_KEY = "YOUR_API_KEY"
# Request a high-score token
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": "6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp",
"pageurl": "https://staging.example.com/qa-login",
"version": "v3",
"action": "login",
"score_qa": "0.9",
"json": 1,
})
task_id = submit.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if result.get("status") == 1:
token = result["request"]
print(f"High-score token received")
break
O ambiente de resolução trata esses sinais internamente; a nota final continua sendo decidida pelo Google. O custo é por thread simultânea, não por resolução: BASIC (US$ 15/mês, 5 threads) cobre uma suíte pequena e a escala vai até VIP-3 (US$ 7.500/mês, 5.000 threads). Escopo do serviço:
- reCAPTCHA v2 e v3, Cloudflare Turnstile e Cloudflare Challenge, GeeTest v3, imagem/OCR e grade de imagens
- CaptchaFox, Friendly Captcha e Lemin em beta
- hCaptcha e FunCaptcha não suportados; GeeTest v4 apenas em breve
Perguntas frequentes
Qual pontuação meu backend deveria aceitar?
Depende do risco da ação. Entre 0,5 e 0,7 é o limite mais comum em contato e login; abaixo de 0,3, a maioria das implementações pede um segundo fator ou um desafio explícito. A nota é um insumo da decisão, não o veredito.
Rodar em modo headless condena a nota?
Não condena, mas é um começo ruim: o modo headless costuma acumular dois descontos de uma vez — APIs ausentes e renderizador SwiftShader. Um navegador real com perfil padrão, mesmo em servidor, tende a pontuar melhor.
Um servidor no Brasil pontua diferente de um nos Estados Unidos?
A geografia pesa pouco; o que pesa é a coerência. Um IP em sa-east-1 com fuso America/Sao_Paulo e Accept-Language: pt-BR é coerente; o mesmo IP com fuso de Nova York e locale em inglês, não. Faixa de data center desconta igual em qualquer região.
A CaptchaAI consegue entregar uma nota específica?
Não. Quem calcula a nota é o Google — nenhum fornecedor controla esse número. A API aceita campos de contexto opcionais, como cookies, userAgent e proxy, para resolver o desafio em condições próximas do seu ambiente. Desconfie de promessa de nota fixa.
Resumo
A nota vem de cinco grupos: navegador (APIs, canvas, WebGL), comportamento (mouse, digitação, rolagem), rede (IP e sinal de TLS), histórico (cookies e resoluções anteriores) e coerência do ambiente.
Nenhum decide sozinho: o que derruba a nota é o acúmulo. Isole um sinal por vez e, quando o esforço deixar de compensar, deixe a resolução com a CaptchaAI.