Ataques de timing — é um método de detecção de bots baseado na análise do tempo de execução de ações no navegador. Sistemas antifraude modernos do Facebook, Google, TikTok e outras plataformas analisam não apenas o que você faz, mas também quão rápido. Cliques muito rápidos, carregamento instantâneo de páginas, ausência de pausas naturais — tudo isso revela a automação. Neste artigo, vamos explorar métodos técnicos de proteção contra ataques de timing para desenvolvedores que trabalham com Selenium, Puppeteer e navegadores anti-detectores.
O que são ataques de timing e como funcionam
Ataque de timing — é um método de detecção de automação baseado na medição dos intervalos de tempo entre as ações do usuário. Sistemas antifraude coletam telemetria: quanto tempo passou desde o carregamento da página até o primeiro clique, quão rápido o usuário rola, se há pausas ao preencher formulários. Esses dados são comparados com modelos comportamentais de pessoas reais.
As principais métricas temporais que os sistemas de proteção analisam:
- Time to First Interaction (TTFI) — tempo desde o carregamento da página até a primeira ação (clique, rolagem, entrada de texto). Bots geralmente começam a agir instantaneamente após o carregamento do DOM, humanos — entre 0,5 a 3 segundos.
- Padrões de tempo de clique — intervalos entre cliques. Scripts automatizados frequentemente clicam com a mesma frequência (por exemplo, exatamente a cada 2 segundos), humanos — de forma caótica.
- Consistência da velocidade de digitação — velocidade de entrada de texto. Bots digitam texto instantaneamente ou com um atraso constante entre os caracteres, humanos — com velocidade variável e pausas.
- Velocidade de movimento do mouse — velocidade do cursor. Selenium, por padrão, teleporta instantaneamente o cursor para o ponto desejado, humanos movem o mouse com aceleração e desaceleração.
- Comportamento de rolagem — padrões de rolagem da página. Bots frequentemente rolam exatamente uma quantidade fixa de pixels, humanos — de forma desigual, com paradas.
Sistemas de detecção usam aprendizado de máquina para analisar essas métricas. Eles constroem um perfil de comportamento e calculam a probabilidade de que o usuário seja um bot. Se os padrões temporais forem muito perfeitos ou muito rápidos — isso é um sinal vermelho.
Importante: Ataques de timing são especialmente eficazes contra automação em massa. Se você estiver executando 100 navegadores com os mesmos padrões temporais, o sistema antifraude facilmente os detectará por anomalias estatísticas.
Métodos de detecção de automação através de padrões temporais
Sistemas antifraude modernos utilizam várias camadas de análise das características temporais. Vamos examinar técnicas específicas usadas pelo Facebook, Google, Cloudflare e outras plataformas.
1. Análise do Performance API
Os navegadores fornecem o Performance API, que coleta telemetria detalhada do carregamento da página. Sistemas antifraude analisam:
// Exemplo de dados do Performance API
performance.timing = {
navigationStart: 1234567890000,
domLoading: 1234567890150, // +150ms
domInteractive: 1234567890300, // +300ms
domComplete: 1234567890500, // +500ms
loadEventEnd: 1234567890600 // +600ms
}
// Padrões suspeitos para bots:
// - Carregamento muito rápido (domComplete < 200ms)
// - Intervalos perfeitamente iguais entre eventos
// - Ausência de atrasos no carregamento de recursos externos
Navegadores headless (especialmente versões antigas do Puppeteer e Selenium) frequentemente mostram valores anormalmente rápidos para navigationStart e domLoading, pois não carregam imagens, fontes e outros recursos da mesma forma que um navegador normal.
2. Análise de Tempo de Eventos
Rastreador JavaScript monitora os timestamps de todos os eventos (cliques, movimentos do mouse, pressionamentos de tecla) e analisa os padrões:
// Exemplo de coleta de telemetria de eventos
const events = [];
document.addEventListener('click', (e) => {
events.push({
type: 'click',
timestamp: performance.now(),
x: e.clientX,
y: e.clientY
});
});
// Análise de padrões suspeitos:
// - Cliques ocorrem exatamente a cada N milissegundos
// - Não há micro-movimentos do mouse antes do clique
// - O primeiro clique ocorre instantaneamente após o carregamento da página
3. Dinâmica de Teclado
Ao preencher formulários, sistemas antifraude analisam a dinâmica de pressionamento de teclas — um indicador biométrico único de cada pessoa:
- Dwell time — tempo de pressão da tecla (de keydown a keyup). Para humanos varia de 50 a 200 ms, para bots — é uma constante.
- Flight time — tempo entre soltar uma tecla e pressionar a próxima. Para humanos — de 100 a 500 ms com variações, para bots — um atraso fixo.
- Ritmo de digitação — ritmo geral de digitação. Humanos fazem pausas em sinais de pontuação, corrigem erros, bots — não.
Exemplo de detecção: Se você usar element.send_keys("texto") no Selenium, todo o texto é inserido em 1-2 milissegundos — isso revela instantaneamente a automação.
Imitação de atrasos humanos no código
O primeiro nível de proteção contra ataques de timing — adicionar atrasos entre ações. Mas é importante não apenas inserir time.sleep(2), mas sim imitar o comportamento natural.
Imitação básica de atrasos em Python (Selenium)
import time
import random
from selenium import webdriver
from selenium.webdriver.common.by import By
def human_delay(min_sec=0.5, max_sec=2.0):
"""Atraso aleatório que imita um humano"""
delay = random.uniform(min_sec, max_sec)
time.sleep(delay)
driver = webdriver.Chrome()
driver.get("https://example.com")
# Atraso antes da primeira ação (humano lê a página)
human_delay(1.5, 4.0)
# Clique no elemento
button = driver.find_element(By.ID, "submit-btn")
button.click()
# Atraso antes da próxima ação
human_delay(0.8, 2.5)
Imitação avançada com distribuição normal
A distribuição uniforme (uniform) parece não natural. Atrasos humanos seguem uma distribuição normal com outliers:
import numpy as np
def realistic_delay(mean=1.5, std_dev=0.5, min_val=0.3, max_val=5.0):
"""
Atraso com distribuição normal
mean: tempo médio de atraso
std_dev: desvio padrão
min_val, max_val: limites (para evitar valores extremos)
"""
delay = np.random.normal(mean, std_dev)
delay = max(min_val, min(max_val, delay)) # Limitando o intervalo
time.sleep(delay)
return delay
# Uso
realistic_delay(mean=2.0, std_dev=0.7) # Média de 2 seg, mas com variações
Atrasos contextuais
Diferentes ações requerem tempos diferentes. Crie perfis de atrasos para diferentes cenários:
class HumanBehavior:
"""Perfis de atrasos para diferentes tipos de ações"""
@staticmethod
def page_load_delay():
"""Atraso após o carregamento da página (lendo o conteúdo)"""
return realistic_delay(mean=2.5, std_dev=1.0, min_val=1.0, max_val=6.0)
@staticmethod
def before_click():
"""Atraso antes do clique (procurando o elemento com os olhos)"""
return realistic_delay(mean=0.8, std_dev=0.3, min_val=0.3, max_val=2.0)
@staticmethod
def before_typing():
"""Atraso antes de começar a digitar"""
return realistic_delay(mean=1.2, std_dev=0.5, min_val=0.5, max_val=3.0)
@staticmethod
def between_form_fields():
"""Atraso entre os campos do formulário"""
return realistic_delay(mean=0.6, std_dev=0.2, min_val=0.2, max_val=1.5)
# Uso no script
driver.get("https://example.com/login")
HumanBehavior.page_load_delay()
username_field = driver.find_element(By.ID, "username")
HumanBehavior.before_typing()
# ... inserindo o login ...
HumanBehavior.between_form_fields()
password_field = driver.find_element(By.ID, "password")
HumanBehavior.before_typing()
# ... inserindo a senha ...
Randomização do tempo de execução das ações
Atrasos iguais entre ações — é uma anomalia estatística. Se você estiver executando 100 instâncias do script, e todas clicarem no botão exatamente 2,5 segundos após o carregamento — isso é facilmente detectável. É necessária a randomização em vários níveis.
1. Randomização da ordem das ações
Adicione variabilidade na sequência de ações. Por exemplo, antes de preencher o formulário, às vezes role a página, às vezes — não:
def fill_form_naturally(driver):
# 30% de chance de rolar a página antes de preencher
if random.random() < 0.3:
driver.execute_script("window.scrollBy(0, 200)")
human_delay(0.5, 1.5)
# 20% de chance de clicar em um lugar aleatório (imitação de leitura)
if random.random() < 0.2:
body = driver.find_element(By.TAG_NAME, "body")
body.click()
human_delay(0.3, 0.8)
# Ação principal — preenchendo o formulário
username_field = driver.find_element(By.ID, "username")
type_like_human(username_field, "meuusuario")
2. Velocidade de digitação variável
Em vez de inserir texto instantaneamente, imite a digitação caractere por caractere com velocidade variável:
def type_like_human(element, text):
"""Inserindo texto com imitação da velocidade de digitação humana"""
for char in text:
element.send_keys(char)
# Atraso básico entre caracteres
base_delay = random.uniform(0.05, 0.15)
# Pausas adicionais em espaços e sinais de pontuação
if char in [' ', '.', ',', '!', '?']:
base_delay += random.uniform(0.1, 0.3)
# "Momentos de reflexão" aleatórios (5% de chance de uma pausa longa)
if random.random() < 0.05:
base_delay += random.uniform(0.5, 1.5)
time.sleep(base_delay)
# Às vezes cometemos um erro de digitação e corrigimos (10% de chance)
if random.random() < 0.1:
time.sleep(random.uniform(0.2, 0.5))
element.send_keys(Keys.BACKSPACE)
time.sleep(random.uniform(0.1, 0.3))
element.send_keys(text[-1]) # Inserindo o último caractere novamente
3. Puppeteer: entrada de texto lenta
No Puppeteer, há uma opção embutida delay para o método type(), mas ela precisa ser randomizada:
// Uso básico (NÃO recomendado — atraso fixo)
await page.type('#username', 'meuusuario', { delay: 100 });
// Abordagem correta — randomização para cada caractere
async function typeWithVariableSpeed(page, selector, text) {
await page.click(selector);
for (const char of text) {
await page.keyboard.type(char);
// Atraso aleatório de 50 a 150 ms
let delay = Math.random() * 100 + 50;
// Pausa adicional em espaços
if (char === ' ') {
delay += Math.random() * 200 + 100;
}
// Pausas longas aleatórias (5% de chance)
if (Math.random() < 0.05) {
delay += Math.random() * 1000 + 500;
}
await page.waitForTimeout(delay);
}
}
// Uso
await typeWithVariableSpeed(page, '#username', 'meuusuario');
Movimento natural do mouse e velocidade de rolagem
Selenium e Puppeteer, por padrão, não movem o cursor do mouse — eles teletransportam instantaneamente para o ponto desejado e clicam. Este é um dos sinais mais óbvios de automação. Para imitar o movimento humano do mouse, são necessárias bibliotecas especiais.
Biblioteca pyautogui para movimento suave do mouse
A biblioteca pyautogui permite mover o cursor em uma curva de Bézier com aceleração e desaceleração:
import pyautogui
from selenium.webdriver.common.action_chains import ActionChains
def move_mouse_naturally(driver, element):
"""Movimento suave do mouse para o elemento imitando um humano"""
# Obtendo as coordenadas do elemento
location = element.location
size = element.size
# Ponto alvo (centro do elemento + um pouco de aleatoriedade)
target_x = location['x'] + size['width'] / 2 + random.randint(-5, 5)
target_y = location['y'] + size['height'] / 2 + random.randint(-5, 5)
# Movimento suave com velocidade variável
# duration — tempo de movimento (0.5-1.5 seg para realismo)
duration = random.uniform(0.5, 1.5)
# tweening — função de aceleração (easeInOutQuad imita movimento humano)
pyautogui.moveTo(target_x, target_y, duration=duration, tween=pyautogui.easeInOutQuad)
# Pequena pausa antes do clique (humano não clica instantaneamente)
time.sleep(random.uniform(0.05, 0.15))
# Clique
element.click()
Importante: Este método funciona apenas se o Selenium estiver controlando uma janela real do navegador (não headless). Para o modo headless, o movimento do mouse é inútil, pois os sistemas antifraude não veem o cursor.
Puppeteer: imitação do movimento do mouse
No Puppeteer, você pode usar a biblioteca ghost-cursor para movimento realista do cursor:
// Instalação: npm install ghost-cursor
const { createCursor } = require("ghost-cursor");
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
const cursor = createCursor(page);
await page.goto("https://example.com");
// Movimento suave para o elemento e clique
const button = await page.$("#submit-btn");
await cursor.click(button); // O cursor se move em uma curva de Bézier!
// Alternativamente — movimento para coordenadas
await cursor.move("#username"); // Apenas movendo o cursor sem clicar
await page.waitForTimeout(300);
await cursor.click(); // Clicando na posição atual
})();
Imitação de rolagem
Um humano não rola a página exatamente 500 pixels de uma vez. A rolagem deve ser desigual, com pausas e às vezes rolando para trás:
def scroll_like_human(driver, target_position=None):
"""
Imitação da rolagem humana
target_position: posição alvo em pixels (se None — rola até o final)
"""
current_position = driver.execute_script("return window.pageYOffset;")
if target_position is None:
# Rolando até o final da página
target_position = driver.execute_script("return document.body.scrollHeight;")
while current_position < target_position:
# Passo de rolagem aleatório (100-400 pixels)
scroll_step = random.randint(100, 400)
current_position += scroll_step
# Rolando
driver.execute_script(f"window.scrollTo(0, {current_position});")
# Pausa entre as rolagens (humano lê o conteúdo)
time.sleep(random.uniform(0.3, 1.2))
# Às vezes rola um pouco para trás (10% de chance)
if random.random() < 0.1:
back_scroll = random.randint(50, 150)
current_position -= back_scroll
driver.execute_script(f"window.scrollTo(0, {current_position});")
time.sleep(random.uniform(0.2, 0.6))
# Uso
scroll_like_human(driver, target_position=2000) # Rolando até 2000px
Tempo de carregamento de páginas e requisições AJAX
Sistemas antifraude analisam não apenas as ações do usuário, mas também as características de carregamento das páginas. Navegadores headless frequentemente carregam anormalmente rápido, pois não carregam imagens, não executam alguns scripts, não renderizam CSS.
Problema: carregamento muito rápido
Compare os valores típicos do Performance API para um navegador normal e headless:
| Métrica | Navegador normal | Headless (suspeito) |
|---|---|---|
| domContentLoaded | 800-2000 ms | 50-200 ms |
| loadEventEnd | 2000-5000 ms | 100-500 ms |
| Número de recursos carregados | 50-200 (imagens, CSS, JS) | 5-20 (apenas críticos) |
Solução: atraso forçado no carregamento
Adicione um atraso artificial após o carregamento da página para que as métricas pareçam mais naturais:
def load_page_naturally(driver, url):
"""Carregamento da página imitando um tempo de carregamento natural"""
start_time = time.time()
driver.get(url)
# Esperando o DOM carregar completamente
WebDriverWait(driver, 10).until(
lambda d: d.execute_script("return document.readyState") == "complete"
)
# Calculando o tempo de carregamento real
actual_load_time = time.time() - start_time
# Se o carregamento foi muito rápido (< 1 seg), adicionamos um atraso
if actual_load_time < 1.0:
additional_delay = random.uniform(1.0, 2.5) - actual_load_time
time.sleep(additional_delay)
# Atraso adicional para "ler a página"
time.sleep(random.uniform(0.5, 2.0))
# Uso
load_page_naturally(driver, "https://example.com")
Aguardando requisições AJAX
Sites modernos carregam conteúdo de forma assíncrona através de AJAX. Se seu script começa a agir antes de todas as requisições AJAX serem concluídas — isso é suspeito. Use esperas explícitas:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def wait_for_ajax(driver, timeout=10):
"""Aguardando a conclusão de todas as requisições AJAX (jQuery)"""
WebDriverWait(driver, timeout).until(
lambda d: d.execute_script("return jQuery.active == 0")
)
# Para sites sem jQuery — aguardando um elemento específico
def wait_for_dynamic_content(driver, selector, timeout=10):
"""Aguardando a aparição de um elemento carregado dinamicamente"""
WebDriverWait(driver, timeout).until(
EC.presence_of_element_located((By.CSS_SELECTOR, selector))
)
# Atraso adicional após a aparição do elemento
time.sleep(random.uniform(0.3, 0.8))
Configuração de proteção em navegadores anti-detectores
Se você trabalha com arbitragem, multi-contas ou outras tarefas onde a anonimidade é crítica, use navegadores anti-detectores: Dolphin Anty, AdsPower, Multilogin, GoLogin. Eles têm mecanismos embutidos de proteção contra ataques de timing, mas precisam ser configurados corretamente.
Dolphin Anty: configuração de Digitação Humana
No Dolphin Anty, há uma função "Emulação de Digitação Humana" — imitação automática da digitação humana. Configuração:
- Abra o perfil do navegador → aba "Automação"
- Ative "Emulação de Digitação Humana"
- Configure as opções:
- Velocidade média de digitação: 150-250 caracteres/minuto (velocidade realista)
- Variação: 30-50% (variação de velocidade entre caracteres)
- Pausa em pontuação: ativado (pausas em sinais de pontuação)
- Erros de digitação aleatórios: 2-5% (erros de digitação aleatórios com correção)
Após isso, qualquer entrada de texto através da API Dolphin irá automaticamente imitar um humano.
AdsPower: configuração do Movimento do Mouse
AdsPower permite gravar padrões de movimento do mouse de um usuário real e reproduzi-los:
- Abra o perfil → "Configurações Avançadas" → "Comportamento do Mouse"
- Selecione o modo "Gravar Usuário Real":
- Abra o navegador em modo normal
- Realize ações típicas (cliques, rolagem, movimentos do mouse)
- AdsPower gravará as trajetórias dos movimentos
- Ao automatizar através da API, o AdsPower irá reproduzir os padrões gravados com variações
Multilogin: Ruído de Canvas e Tempo de WebGL
Multilogin adiciona ruído (noise) nas impressões digitais do Canvas e WebGL, o que afeta os ataques de timing relacionados à renderização:
- Perfil → "Configurações de Impressão Digital" → "Canvas"
- Ative "Ruído de Canvas" (adiciona micro-atrasos na renderização do Canvas)
- Ative "Mascaramento de Metadados do WebGL" (mascara características da GPU que afetam a velocidade de renderização)
Isso protege contra a detecção através da análise do tempo de execução de Canvas.toDataURL() e operações do WebGL.
Recomendação: Se você trabalha com multi-contas no Facebook, Instagram ou TikTok, use navegadores anti-detectores em conjunto com proxies residenciais de qualidade — isso minimiza o risco de bans em cadeia e detecção por IP.
Técnicas avançadas para contornar a detecção de timing
Para plataformas altamente protegidas (Google, Facebook, sites bancários), métodos básicos podem não ser suficientes. Vamos considerar técnicas avançadas.
1. Substituição do Performance API
É possível redefinir métodos do Performance API para retornar valores realistas em vez de reais:
// Injeção de script para substituir performance.now()
const script = `
(function() {
const originalNow = performance.now.bind(performance);
let offset = 0;
let lastValue = 0;
performance.now = function() {
const realValue = originalNow();
// Adicionando ruído aleatório ao tempo
const noise = Math.random() * 2 - 1; // de -1 a +1 ms
let fakeValue = realValue + offset + noise;
// Garantindo monotonicidade (o tempo não volta)
if (fakeValue <= lastValue) {
fakeValue = lastValue + 0.1;
}
lastValue = fakeValue;
return fakeValue;
};
})();
`;
// Puppeteer: injeção ao criar a página
await page.evaluateOnNewDocument(script);
Atenção: Este método pode ser detectado através da verificação de integridade de métodos nativos. Use apenas em sites sem forte proteção.
2. Limitação de CPU e Rede
O Chrome DevTools Protocol permite desacelerar artificialmente a CPU e a rede, para que as métricas de carregamento pareçam mais naturais:
// Puppeteer: desacelerando a CPU em 2 vezes
const client = await page.target().createCDPSession();
await client.send('Emulation.setCPUThrottlingRate', { rate: 2 });
// Desacelerando a rede (emulação 3G)
await page.emulateNetworkConditions({
offline: false,
downloadThroughput: 1.5 * 1024 * 1024 / 8, // 1.5 Mbps
uploadThroughput: 750 * 1024 / 8, // 750 Kbps
latency: 40 // 40ms de atraso
});
Isso aumentará o tempo de carregamento das páginas e a execução do JavaScript, tornando o perfil mais parecido com um usuário real com velocidade média de internet.
3. Imitação de atividade em segundo plano
Usuários reais não ficam em uma única aba — eles alternam entre abas, minimizam janelas, se distraem. Imite isso:
async function simulateTabSwitch(page) {
// Emulando a troca para outra aba (Page Visibility API)
await page.evaluate(() => {
Object.defineProperty(document, 'hidden', {
get: () => true,
configurable: true
});
document.dispatchEvent(new Event('visibilitychange'));
});
// Pausa (o usuário está olhando outra aba)
await page.waitForTimeout(Math.random() * 3000 + 2000);
// Voltando para a aba
await page.evaluate(() => {
Object.defineProperty(document, 'hidden', {
get: () => false,
configurable: true
});
document.dispatchEvent(new Event('visibilitychange'));
});
}
// Uso: "destraímos" aleatoriamente durante o trabalho
if (Math.random() < 0.15) { // 15% de chance
await simulateTabSwitch(page);
}
4. Uso de marcas de tempo reais do User Timing
Alguns sites criam suas próprias marcas de tempo através do User Timing API. Adicione marcas realistas:
// Criando marcas de tempo realistas
await page.evaluate(() => {
// Imitação da "reflexão" do usuário antes da ação
performance.mark('user-started-reading');
setTimeout(() => {
performance.mark('user-found-button');
performance.measure('reading-time', 'user-started-reading', 'user-found-button');
}, Math.random() * 2000 + 1000);
});
5. Rotação de proxies para reduzir a correlação estatística
Mesmo que cada instância do seu script tenha atrasos randomizados, sistemas antifraude podem detectar correlação se todas as requisições vierem de um único IP. Use rotação de proxies:
- Para scraping e tarefas em massa: proxies de data center com rotação automática a cada 5-10 minutos
- Para trabalhar com redes sociais e publicidade: proxies residenciais com vinculação a sessão (sticky sessions)
- Para plataformas móveis (Instagram, TikTok): proxies móveis com rotação por timer ou por requisição
A rotação de IP reduz a probabilidade de que o sistema antifraude consiga coletar dados suficientes para análise estatística dos seus padrões de timing.
Conclusão
Ataques de timing — é um método complexo de detecção de automação que requer uma abordagem abrangente para proteção. Principais conclusões:
- Não use atrasos fixos — sempre randomize o tempo entre ações usando distribuição normal
- Imite atrasos contextuais — diferentes ações requerem tempos diferentes (ler a página ≠ clicar no botão)
- Adicione variabilidade na sequência de ações — rolagens, cliques, trocas de abas aleatórias
- Use movimento suave do mouse — bibliotecas ghost-cursor (Puppeteer) ou pyautogui (Selenium)
- Imite a velocidade natural de digitação — entrada caractere por caractere com pausas em sinais de pontuação
- Configure navegadores anti-detectores — Dolphin Anty, AdsPower e Multilogin têm mecanismos embutidos de proteção contra ataques de timing
- Combine com proxies de qualidade — rotação de IP reduz a possibilidade de análise estatística
Lembre-se: proteção ideal não existe. Sistemas antifraude estão em constante evolução, adicionando novos métodos de detecção. Sua tarefa é aproximar ao máximo o comportamento do script ao de um usuário real e atualizar regularmente os métodos de contorno.
Se você trabalha com automação de navegadores para scraping, testes ou outras tarefas, recomendamos o uso de proxies residenciais — eles oferecem o máximo nível de anonimato e minimizam o risco de detecção por endereço IP. Para plataformas móveis, proxies móveis são mais adequados, pois imitam usuários reais de operadoras móveis.