客户端机器人与自动化检测库,具备加权评分、行为分析、浏览器指纹识别及可配置阈值。可检测无头浏览器、Selenium、Puppeteer、Playwright、基于CDP的工具以及隐身自动化框架。
v2.1.0 — 反检测蜜罐、GPU稳定的Canvas指纹识别、增强的行为分析、惰性初始化、服务端篡改检测、请求指纹绑定及速率限制。
human(人类)、suspicious(可疑)、bot(机器人),对应不同摩擦动作(monitor 监控、challenge 挑战、block 阻止)浏览器 你的服务器
┌──────────────────────────┐ ┌──────────────────────┐
│ Collector(单例) │ POST │ Express 中间件 │
│ ├─ 28 个检测模块 │ 信号 │ ├─ NonceManager │
│ ├─ BehaviorTracker │ + nonce │ ├─ RateLimiter │
│ ├─ HoneypotTraps │───────────▶│ ├─ TamperDetector │
│ ├─ 堆栈跟踪陷阱 │ │ ├─ computeVerdict() │
│ └─ IframeContext │ │ └─ 工作量证明 │
│ │ 判定结果 │ │
│ ↓ collect() → │ + proof │ 返回: │
│ DetectionResult[] │◀───────────│ { verdict, score, │
└──────────────────────────┘ │ confidence, proof, │
│ tamperScore } │
└──────────────────────┘
│
▼
会话保护端点
(登录、结账等)
验证 proof 后放行
核心原则:浏览器仅收集原始 DetectionResult[] 信号。服务端使用秘密权重表计算最终判定。客户端计算的判定结果永远不可信。
npm install
npm run build
输出到 dist/:
botdetect.min.js(含 polyfill,约 151 KB)botdetect-clean.min.js(仅现代浏览器,约 74 KB)<script src="/path/to/botdetect.min.js"></script>
<script>
BotDetect.collector.enableTraps();
BotDetect.collector.enableBehavioralTracking();
BotDetect.collector.enableHoneypots();
</script>
cd server
npm install express cors express-session
node example-integration.js
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();
}
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 });
});
import Collector from './collector/Collector';
// 或通过全局变量:BotDetect.collector
| 方法 | 返回类型 | 描述 |
|---|---|---|
getInstance(config?) | Collector | 单例访问器 |
configure(config) | void | 运行时更新配置 |
getConfig() | CollectorConfig | 当前配置 |
init() | void | 惰性初始化陷阱、跟踪、蜜罐 |
enableTraps() | void | 在 DOM API 上安装堆栈跟踪陷阱 |
enableBehavioralTracking() | void | 开始鼠标/键盘/滚动监控 |
enableHoneypots(container?) | void | 安装蜜罐字段 |
collect() | Promise<DetectionResult[]> | 运行所有检测 |
setNonce(nonce) | void | 存储服务端下发的 nonce |
getSessionId() | string | 唯一会话标识符 |
getFingerprint() | string | 会话指纹哈希 |
resetBehavioralData() | void | 清除行为数据 |
destroy() | void | 清理所有监听器和 DOM 元素 |
import Detector from './detector/Detector';
| 方法 | 返回类型 | 描述 |
|---|---|---|
getInstance(config?) | Detector | 单例访问器 |
configure(config) | void | 更新配置 |
analyze(results) | DetectionVerdict | 评分 + 分类(仅本地调试) |
handleError(error) | DetectionVerdict | 失败回退判定 |
警告:
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 };
}
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 }, // 5 分钟 nonce 过期
noScript: { timeout: 10000 }, // 10 秒无脚本窗口
rateLimit: { maxRequests: 10, windowMs: 60000 },
noScriptPaths: ['/api/login', '/api/checkout', '/api/register']
});
app.use('/api', router);
| 端点 | 方法 | 用途 |
|---|---|---|
/api/botdetect/nonce | GET | 发放一次性 nonce |
/api/botdetect/verify | POST | 提交信号,接收签名判定 |
/api/botdetect/midcycle | POST | 会话中途重新验证 |
{
"verdict": "human",
"score": 0.125,
"confidence": 0.85,
"tamperScore": 0,
"friction": "monitor",
"threshold": 0.5,
"proof": "a1b2c3d4e5f6..."
}
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
| 模块 | 检测内容 | 权重 |
|---|---|---|
webdriver | navigator.webdriver、selenium 属性、getter 描述符 | 5 |
chromeDriver | window 上的重复内置属性、document 中的 cache_ | 6 |
fakeCreateElement | 伪造的 document.createElement | 7 |
toStringSpoofed | Function.prototype.toString 篡改 | 6 |
cdpDetection | cdc_*、__playwright__、__puppeteer__ 全局变量、chrome.runtime | 7 |
stealthDetection | 原生函数完整性(Notification、Navigator、Permissions、plugins、languages、canvas) | 5 |
inconsistentCloneError | 结构化克隆算法不一致 | 5 |
iframeChromeRuntime | iframe 上下文中的 chrome.runtime | 5 |
inconsistentChromeObject | chrome 对象在 iframe 与主窗口间不一致 | 4 |
| 模块 | 检测内容 | 权重 |
|---|---|---|
playwrightWebKit | WebKit 自动化痕迹 | 4 |
playwrightOrientation | 方向 + chrome.runtime 不一致 | 3 |
| 模块 | 分析信号 | 权重 |
|---|---|---|
behavioralAnalysis | 鼠标曲率 + 直线比例、按键 CV + 爆发模式 + KPM、滚动加速度 + 方向变化、触摸力方差 + 半径 | 7 |