BotDetect v2 — библиотека обнаружения ботов для продакшена
Клиентская библиотека для обнаружения ботов и автоматизации с взвешенной оценкой, поведенческим анализом, сбором цифрового отпечатка браузера и настраиваемыми порогами. Обнаруживает безголовые браузеры, Selenium, Puppeteer, Playwright, инструменты на основе CDP и стелс-фреймворки автоматизации.
v2.1.0 — антидетекционные приманки, стабильный к GPU canvas-отпечаток, улучшенный поведенческий анализ, ленивая инициализация, серверное обнаружение подделки сигналов, привязка отпечатка запроса и ограничение скорости.
Содержание
Возможности
- 28 модулей обнаружения, покрывающих фреймворки автоматизации, безголовые браузеры, сбор отпечатков, поведенческий анализ, приманки и ловушки стек-трейсов
- Взвешенная система оценки — каждый сигнал имеет настраиваемый вес; итоговый вердикт вычисляется на сервере
- Три уровня вердикта:
human, suspicious, bot с соответствующими действиями (monitor, challenge, block)
- Серверная верификация — защита от повторного использования nonce, подпись proof-of-work
- Ловушки стек-трейсов — подмена методов DOM для захвата стеков вызовов инструментов автоматизации
- Поведенческий анализ — кривизна мыши, вариативность времени нажатий клавиш, ускорение прокрутки, динамика касаний
- Антидетекционные приманки — рандомизированное CSS-маскирование, поля-приманки, реалистичные имена полей
- Серверное обнаружение подделки — проверка целостности сигналов, выявление попыток обмана
- Привязка отпечатка запроса — токены PoW привязаны к атрибутам HTTP-запроса
- Ограничение скорости — ограничение на сессию для всех эндпоинтов верификации
- Обнаружение отключенного JavaScript — выявление клиентов, никогда не отправляющих полезную нагрузку обнаружения
- Белый список известных краулеров — 20+ легитимных ботов исключены из оценки
Архитектура
Браузер Ваш сервер
┌──────────────────────────┐ ┌──────────────────────┐
│ Collector (синглтон) │ POST │ Express Middleware │
│ ├─ 28 модулей │ signals │ ├─ NonceManager │
│ ├─ BehaviorTracker │ + nonce │ ├─ RateLimiter │
│ ├─ HoneypotTraps │───────────▶│ ├─ TamperDetector │
│ ├─ Stack trace traps │ │ ├─ computeVerdict() │
│ └─ IframeContext │ │ └─ Proof-of-Work │
│ │ verdict │ │
│ ↓ collect() → │ + proof │ Возвращает: │
│ DetectionResult[] │◀───────────│ { verdict, score, │
└──────────────────────────┘ │ confidence, proof, │
│ tamperScore } │
└──────────────────────┘
│
▼
Эндпоинт, защищённый сессией
(логин, оформление заказа и т.д.)
проверяет proof перед
предоставлением доступа
Ключевой принцип: браузер собирает только необработанные сигналы DetectionResult[]. Сервер вычисляет итоговый вердикт, используя секретную таблицу весов. Вердикты, вычисленные на клиенте, никогда не доверяются.
Быстрый старт
1. Сборка
npm install
npm run build
Результат в dist/:
botdetect.min.js (с полифиллами, ~151 КБ)
botdetect-clean.min.js (только для современных браузеров, ~74 КБ)
2. Подключение на странице
<script src="/path/to/botdetect.min.js"></script>
<script>
BotDetect.collector.enableTraps();
BotDetect.collector.enableBehavioralTracking();
BotDetect.collector.enableHoneypots();
</script>
3. Настройка серверной верификации
cd server
npm install express cors express-session
node example-integration.js
4. Отправка сигналов при чувствительном действии
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. Проверка на сервере
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
Collector (синглтон)
import Collector from './collector/Collector';
// или через глобал: BotDetect.collector
Detector (только для отладки)
import Detector from './detector/Detector';
Предупреждение: analyze() выполняется полностью в браузере. Никогда не используйте его результат для продакшен-решений.
Типы
interface DetectionResult {
name: string; // Имя модуля
score: number; // 0.0 – 1.0
weight: number; // 1 – 10 (важность)
detail?: string; // Описание на человеческом языке
}
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; // таймаут на модуль (по умолчанию: 3000)
enableTraps: boolean;
enableBehavioralTracking: boolean;
enableHoneypots: boolean;
thresholds: { strict: number; balanced: number; relaxed: number };
}
Серверная интеграция
Express Middleware
const { createBotDetectEndpoint } = require('./server');
const { router, generateProofOfWork, cleanup } = createBotDetectEndpoint({
secretSalt: process.env.BOTDETECT_SALT,
scoring: {
threshold: 'balanced', // 'strict' | 'balanced' | 'relaxed' | число
minSignals: 2,
signalBoostThreshold: 0.8,
frictionThresholds: { monitor: 0.2, challenge: 0.5, block: 0.8 }
},
nonce: { ttl: 300000 }, // время жизни nonce 5 минут
noScript: { timeout: 10000 }, // окно 10 сек для no-script
rateLimit: { maxRequests: 10, windowMs: 60000 },
noScriptPaths: ['/api/login', '/api/checkout', '/api/register']
});
app.use('/api', router);
Эндпоинты
| Эндпоинт | Метод | Назначение |
|---|
/api/botdetect/nonce |
Формат ответа сервера
{
"verdict": "human",
"score": 0.125,
"confidence": 0.85,
"tamperScore": 0,
"friction": "monitor",
"threshold": 0.5,
"proof": "a1b2c3d4e5f6..."
}
Серверная оценка (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, если обнаружена подделка сигналов
Модули обнаружения
Фреймворки автоматизации (веса 5–7)
Специфичные для Playwright (веса 3–4)
| Модуль | Обнаруживает | Вес |
|---|
playwrightWebKit | Артефакты автоматизации WebKit | 4 |
playwrightOrientation | Несоответствие ориентации и chrome.runtime | 3 |
Поведенческий анализ (вес 7)
| Модуль | Анализируемые сигналы | Вес |
|---|
behavioralAnalysis | Кривизна мыши + отношение прямых линий, CV времени нажатия + паттерны bursts + KPM, ускорение прокрутки + смена направления, дисперсия силы касания + радиус | 7 |
Сбор цифровых отпечатков браузера (веса 3–4)
Свойства Navigator и ОС (вес 5)
| Модуль | Проверки | Вес |
|---|
navigatorInconsistencies | 11 проверок: languages, plugins, mimeTypes, platform, UA, cookies, DNT, touch, hardwareConcurrency, deviceMemory, connection | 5 |
Экран и производительность (вес 3)
Активные ловушки и приманки (веса 8–9)
| Модуль | Обнаруживает | Вес |
|---|
honeypotTraps | Случайные скрытые поля + приманки + канареечный эндпоинт | 9 |
Сеть и контекст (веса 1–2)
Белый список (вес 0)
| Модуль | Обнаруживает | Вес |
|---|
verifiedBots | 20+ известных краулеров (Googlebot, Bingbot, Yandex, Facebook, Twitter и т.д.) — возвращает -1, исключается из оценки | 0 |
Конфигурация
Collector
const collector = Collector.getInstance({
detectionTimeoutMs: 1000, // Ниже для более быстрого UX
enableTraps: true,
enableBehavioralTracking: true,
enableHoneypots: true,
thresholds: {
strict: 0.3, // Агрессивный (логин, оформление заказа)
balanced: 0.5, // По умолчанию
relaxed: 0.7 // Либеральный (просмотр контента)
}
});
Detector (только для отладки)
const detector = Detector.getInstance({
threshold: 'balanced', // 'strict' | 'balanced' | 'relaxed' | число
minSignals: 2, // Минимум сигналов перед усилением
signalBoostThreshold: 0.8, // Сигналы выше этого порога получают дополнительный вес
failPolicy: 'open', // 'open' = human при ошибке, 'closed' = bot при ошибке
frictionThresholds: {
monitor: 0.2,
challenge: 0.5,
block: 0.8
}
});
Сервер
createBotDetectEndpoint({
secretSalt: process.env.BOTDETECT_SALT, // Держите в секрете
scoring: { threshold: 'balanced' },
nonce: { ttl: 300000, cleanupInterval: 60000 },
noScript: { timeout: 10000 },
rateLimit: { maxRequests: 10, windowMs: 60000 },
requestFingerprint: true, // Привязка PoW к атрибутам запроса
noScriptPaths: ['/api/login', '/api/checkout']
});
Чек-лист для продакшена
Безопасность
Производительность
Мониторинг
Тестирование
npm test # 74 Jest-теста в 6 наборах
npm run typecheck # TypeScript строгий режим
npm run lint # ESLint
npm run build # Webpack production-сборка
Лицензия
Apache — Lahmeri Mohamed Amine