BotDetect v2 — Biblioteca de Detecção de Bots de Produção
Biblioteca de detecção de bots e automação no lado do cliente com pontuação ponderada, análise comportamental, impressão digital do navegador e limites configuráveis. Detecta navegadores headless, Selenium, Puppeteer, Playwright, ferramentas baseadas em CDP e estruturas de automação furtiva.
v2.1.0 — honeypots anti-detecção, impressão digital de canvas estável em GPU, análise comportamental aprimorada, inicialização preguiçosa, detecção de adulteração no lado do servidor, vinculação de impressão digital de requisição e limitação de taxa.
Índice
Funcionalidades
- 28 módulos de detecção cobrindo estruturas de automação, navegadores headless, impressão digital, análise comportamental, honeypots e armadilhas de stack trace
- Sistema de pontuação ponderada — cada sinal tem peso configurável; pontuação final calculada no servidor
- Três níveis de veredito:
human, suspicious, bot com ações de atrito correspondentes (monitor, challenge, block)
- Verificação no lado do servidor — protegido por nonce, replay protegido, prova-de-trabalho assinada
- Armadilhas de stack trace — monkey-patches de APIs DOM para capturar call stacks de ferramentas de automação
- Análise comportamental — curvatura do mouse, variação de tempo de digitação, aceleração de rolagem, dinâmica de toque
- Honeypots anti-detecção — ocultação CSS aleatória, campos isca, nomes de campo realistas
- Detecção de adulteração no servidor — valida integridade do sinal, detecta tentativas de manipulação
- Vinculação de impressão digital da requisição — tokens PoW vinculados a atributos da requisição HTTP
- Limitação de taxa — limitação de taxa por sessão em todos os endpoints de verificação
- Detecção sem script — identifica clientes que nunca enviam payloads de detecção
- Lista de permissão de crawlers conhecidos — 20+ bots legítimos excluídos da pontuação
Arquitetura
Browser Your Server
┌──────────────────────────┐ ┌──────────────────────┐
│ Collector (singleton) │ POST │ Express Middleware │
│ ├─ 28 detection modules│ signals │ ├─ NonceManager │
│ ├─ BehaviorTracker │ + nonce │ ├─ RateLimiter │
│ ├─ HoneypotTraps │───────────▶│ ├─ TamperDetector │
│ ├─ Stack trace traps │ │ ├─ computeVerdict() │
│ └─ IframeContext │ │ └─ Proof-of-Work │
│ │ verdict │ │
│ ↓ collect() → │ + proof │ Returns: │
│ DetectionResult[] │◀───────────│ { verdict, score, │
└──────────────────────────┘ │ confidence, proof, │
│ tamperScore } │
└──────────────────────┘
│
▼
Session-gated endpoint
(login, checkout, etc.)
validates proof before
granting access
Princípio chave: O navegador apenas coleta sinais brutos DetectionResult[]. O servidor calcula o veredito final usando uma tabela de pesos secreta. Vereditos calculados no cliente nunca são confiáveis.
Início Rápido
1. Construir
npm install
npm run build
Saída em dist/:
botdetect.min.js (com polyfills, ~151 KB)
botdetect-clean.min.js (apenas navegadores modernos, ~74 KB)
2. Incluir na sua página
<script src="/path/to/botdetect.min.js"></script>
<script>
BotDetect.collector.enableTraps();
BotDetect.collector.enableBehavioralTracking();
BotDetect.collector.enableHoneypots();
</script>
3. Configurar verificação no lado do servidor
cd server
npm install express cors express-session
node example-integration.js
4. Enviar sinais em ação sensível
async function onLogin() {
const { nonce } = await (await fetch('/api/botdetect/nonce')).json();
BotDetect.collector.setNonce(nonce);
const signals = await BotDetect.collector.collect();
const resp = await fetch('/api/botdetect/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ signals, nonce })
});
const { verdict, score, proof, friction } = await resp.json();
document.getElementById('botdetect-proof').value = proof;
document.getElementById('login-form').submit();
}
5. Validar no servidor
app.post('/api/login', (req, res) => {
const bd = req.session.botdetect;
if (!bd) return res.status(403).json({ error: 'no_verification' });
if (bd.verdict === 'bot') return res.status(403).json({ error: 'access_denied' });
if (bd.verdict === 'suspicious') return challengeCaptcha(req, res);
res.json({ success: true });
});
API do Lado do Cliente
Coletor (singleton)
import Collector from './collector/Collector';
// ou via global: BotDetect.collector
Detector (apenas depuração)
import Detector from './detector/Detector';
Aviso: analyze() é executado inteiramente no navegador. Nunca use sua saída para decisões de produção.
Tipos
interface DetectionResult {
name: string; // Nome do módulo
score: number; // 0.0 – 1.0
weight: number; // 1 – 10 (importância)
detail?: string; // Descrição legível
}
interface DetectionVerdict {
verdict: 'bot' | 'suspicious' | 'human';
score: number; // 0.0 – 1.0
confidence: number; // 0.0 – 1.0
signals: DetectionResult[];
threshold: number;
friction: 'monitor' | 'challenge' | 'block';
}
interface CollectorConfig {
detectionTimeoutMs: number; // timeout por módulo (padrão: 3000)
enableTraps: boolean;
enableBehavioralTracking: boolean;
enableHoneypots: boolean;
thresholds: { strict: number; balanced: number; relaxed: number };
}
Integração no Lado do Servidor
Middleware Express
const { createBotDetectEndpoint } = require('./server');
const { router, generateProofOfWork, cleanup } = createBotDetectEndpoint({
secretSalt: process.env.BOTDETECT_SALT,
scoring: {
threshold: 'balanced', // 'strict' | 'balanced' | 'relaxed' | number
minSignals: 2,
signalBoostThreshold: 0.8,
frictionThresholds: { monitor: 0.2, challenge: 0.5, block: 0.8 }
},
nonce: { ttl: 300000 }, // expiração de nonce de 5 minutos
noScript: { timeout: 10000 }, // janela sem script de 10s
rateLimit: { maxRequests: 10, windowMs: 60000 },
noScriptPaths: ['/api/login', '/api/checkout', '/api/register']
});
app.use('/api', router);
Endpoints
| Endpoint | Método | Propósito |
|---|
/api/botdetect/nonce | GET |
Formato da Resposta do Servidor
{
"verdict": "human",
"score": 0.125,
"confidence": 0.85,
"tamperScore": 0,
"friction": "monitor",
"threshold": 0.5,
"proof": "a1b2c3d4e5f6..."
}
Pontuação no Servidor (Node.js)
const { computeVerdict, RateLimiter, NonceManager } = require('./scoring');
const verdict = computeVerdict(signals, {
threshold: 'balanced',
minSignals: 2,
signalBoostThreshold: 0.8,
frictionThresholds: { monitor: 0.2, challenge: 0.5, block: 0.8 }
});
// verdict.tamperScore > 0 se adulteração de sinal detectada
Módulos de Detecção
Estruturas de Automação (pesos 5–7)
Playwright-Específico (pesos 3–4)
| Módulo | Detecta | Peso |
|---|
playwrightWebKit | Artefatos de automação WebKit | 4 |
playwrightOrientation | Inconsistência de orientação + chrome.runtime | 3 |
Análise Comportamental (peso 7)
| Módulo | Sinais Analisados | Peso |
|---|
behavioralAnalysis | Curvatura do mouse + razão linha reta, CV de digitação + padrões de rajada + KPM, aceleração de rolagem + mudanças de direção, variação de força do toque + raio | 7 |
Impressão Digital do Navegador (pesos 3–4)
Propriedades do Navigator e SO (peso 5)
| Módulo | Verifica | Peso |
|---|
navigatorInconsistencies | 11 verificações: languages, plugins, mimeTypes, platform, UA, cookies, DNT, touch, hardwareConcurrency, deviceMemory, connection | 5 |
Armadilhas Ativas e Honeypots (pesos 8–9)
| Módulo | Detecta | Peso |
|---|
honeypotTraps | Campos ocultos aleatórios + iscas + endpoint canário | 9 |
|
Rede e Contexto (pesos 1–2)
Lista de Permissão (peso 0)
| Módulo | Detecta | Peso |
|---|
verifiedBots | 20+ crawlers conhecidos (Googlebot, Bingbot, Yandex, Facebook, Twitter, etc.) — retorna -1, excluído da pontuação | 0 |
Configuração
Coletor
const collector = Collector.getInstance({
detectionTimeoutMs: 1000, // Menor para UX mais rápido
enableTraps: true,
enableBehavioralTracking: true,
enableHoneypots: true,
thresholds: {
strict: 0.3, // Agressivo (login, checkout)
balanced: 0.5, // Padrão
relaxed: 0.7 // Permissivo (navegação de conteúdo)
}
});
Detector (apenas depuração)
const detector = Detector.getInstance({
threshold: 'balanced', // 'strict' | 'balanced' | 'relaxed' | number
minSignals: 2, // Mínimo de sinais antes do boost
signalBoostThreshold: 0.8, // Sinais acima disso ganham peso extra
failPolicy: 'open', // 'open' = humano em erro, 'closed' = bot em erro
frictionThresholds: {
monitor: 0.2,
challenge: 0.5,
block: 0.8
}
});
Servidor
createBotDetectEndpoint({
secretSalt: process.env.BOTDETECT_SALT, // Mantenha em segredo
scoring: { threshold: 'balanced' },
nonce: { ttl: 300000, cleanupInterval: 60000 },
noScript: { timeout: 10000 },
rateLimit: { maxRequests: 10, windowMs: 60000 },
requestFingerprint: true, // Vincular PoW a atributos da requisição
noScriptPaths: ['/api/login', '/api/checkout']
});
Lista de Verificação para Produção
Segurança
Monitoramento
Testes
npm test # 74 testes Jest em 6 suítes
npm run typecheck # Modo estrito TypeScript
npm run lint # ESLint
npm run build # Bundle de produção Webpack
Licença
Apache — Lahmeri Mohamed Amine