@sgysldz/anti-debug
v1.0.0
Published
浏览器端防调试与基础运行时防护(检测调试器、DevTools 等)
Maintainers
Readme
anti-debug
浏览器端防调试 / 降低窥探便利度的轻量工具库(TypeScript)。通过启发式检测「调试器暂停」与「DevTools 可能已打开」,并在命中时回调业务逻辑;可选弱化 console 输出。
重要:前端代码无法做到不可被逆向或不可被阅读。本库仅提高成本,不能替代服务端鉴权、密钥不下发、构建混淆、关闭生产 Source Map 等工程措施。
功能概览
| 能力 | 说明 |
| --- | --- |
| 定时守护 | startAntiDebugGuard 按间隔执行多项检测,命中时调用 onThreat(reason) |
| debugger 耗时 | detectDebuggerTiming:利用 debugger 断点处前后时间差异常 |
| 窗口 / 视口 | detectDevToolsByDimensions:outer-inner + 根元素 / visualViewport 差值(不依赖断点) |
| console 耗时(可选) | detectDevToolsByConsoleTiming:DevTools 打开时常更慢(默认关,防误报) |
| 本机跳过 | skipInDevelopment + isLikelyLocalDevHost,避免本地开发时被频繁打断 |
| noop console | installNoopConsole:可选替换常见 console.* 为空实现 |
| 快捷键 / 右键 | installDevToolsUiBlock 或 startAntiDebugGuard({ uiBlock: true }):拦 F12、Ctrl+Shift+I/J/C 等;可选拦右键、Ctrl+U |
安装
在 monorepo 中依赖工作区包(示例):
{
"dependencies": {
"anti-debug": "workspace:*"
}
}pnpm add anti-debug@workspace:* -F your-app快速开始
import { startAntiDebugGuard, installNoopConsole } from "anti-debug"
// 可选:弱化控制台(记得在需要调试时注释掉或条件编译)
const restoreConsole = installNoopConsole()
const guard = startAntiDebugGuard({
intervalMs: 2500,
// 本地 localhost 不跑守护,正式域名照常检测
skipInDevelopment: true,
// 拦 F12、Ctrl+Shift+I/J/C 等;默认不拦整页右键,需则传 { blockContextMenu: true }
uiBlock: true,
onThreat(reason) {
// reason: 'debugger-timing' | 'devtools-dimensions' | 'devtools-console-timing'
// 自行实现:跳转、清 DOM、上报等(本库不内置网络请求)
window.location.replace("/")
},
})
// 单页应用卸载或不再需要时
// guard.stop();
// restoreConsole();API 说明
startAntiDebugGuard(options?)
- 环境:仅在存在
window的浏览器中启动setInterval;Node / 无window时返回{ stop: () => {} },不抛错。 intervalMs:轮询间隔,默认2000。immediate:是否在挂载后立即执行第一次检测,默认true。skipInDevelopment:为true且当前 hostname 为常见本机地址(见下)时,不启动守护。checks:可关闭debuggerTiming/devToolsDimensions;devToolsConsoleTiming默认关闭,需显式true。devToolsThresholds:微调widthGap/heightGap/layoutGap/consoleTimingMs(漏报时可略调低前两项)。uiBlock:true或DevToolsUiBlockOptions对象;与skipInDevelopment同时生效时,本机 hostname 下不安装(与轮询一致)。stop()时会一并卸载快捷键监听。onThreat(reason):有检测为阳性时调用;未传则仅轮询,不执行任何默认破坏操作。
AntiDebugReason(reason 取值)
| 值 | 含义 |
| ------------------------- | -------------------------------------------------------- |
| debugger-timing | detectDebuggerTiming 认为执行在断点/调试器下被显著拖慢 |
| devtools-dimensions | 视口 / 尺寸启发式认为像已打开 DevTools(dock 场景为主) |
| devtools-console-timing | 可选;console 单次调用耗时偏高(与「停用断点」无关) |
detectDebuggerTiming(thresholdMs?)
- 默认
thresholdMs = 120。耗时超过该值返回true。 - 内含
debugger语句:若被 ESLint 禁止,需在项目规则中对本库或本行做例外。
detectDevToolsByDimensions(options?) 或 (widthGap, heightGap)
- 对象形式:可传
widthGapThreshold、heightGapThreshold、layoutGapThreshold(默认160/300/100),并包含对innerWidth - clientWidth、visualViewport与内视口的辅助判断。 - 两数字形式:与旧版兼容,等价于仅调整 outer-inner 阈值。
- 「停用断点」:不会执行
debugger,故debugger-timing会漏报;可依赖本项与可选的detectDevToolsByConsoleTiming。 - DevTools 独立窗口 undock 时主页面尺寸往往不变 → 纯前端无法可靠检测,只能依赖服务端或其它手段。
detectDevToolsByConsoleTiming(thresholdMs?)
- 默认
5ms;仅建议在checks: { devToolsConsoleTiming: true }时由守护调用;单独使用亦可。 - 可能有误报,请结合业务与
devToolsThresholds.consoleTimingMs调整。
isLikelyLocalDevHost()
在 location 存在时,匹配:localhost、127.0.0.1、[::1]、0.0.0.0,以及以 .local 结尾的主机名。
installNoopConsole(options?)
- 默认替换常见输出类方法;返回卸载函数,务必在测试或需要控制台时调用恢复。
installDevToolsUiBlock(options?)
- 在
window上注册捕获阶段keydown,默认拦截:F12;Ctrl+Shift+I/J/C/K/E(Windows/Linux);Cmd+Option+I/J/C、Cmd+Shift+C(Mac 常见)。 - 可选:
blockContextMenu: true拦截整页右键;blockViewSource: true拦截 Ctrl+U 查看源代码。 - 无法拦截:浏览器菜单「更多工具 → 开发者工具」、扩展、远程调试、从书签/其它页已打开的 DevTools 等。
- 返回卸载函数;也可通过
startAntiDebugGuard({ uiBlock: true })自动安装并在stop()时卸载。
局限与误报
- 「Deactivate breakpoints / 停用断点」与「Resume」:
debugger不暂停时,debugger-timing必然漏报——这是浏览器行为,不是库 bug。请依赖devtools-dimensions,并视情况开启devToolsConsoleTiming或调低devToolsThresholds.widthGap/heightGap。 - DevTools 独立窗口:主页面
outer/inner可能不变 → 尺寸类检测常漏报;纯前端无完美对策。 - 尺寸 / console 检测:分屏、缩放、扩展、省电模式等 → 误报或漏报均可能存在。
- 性能:轮询与
debugger/console检测占用主线程,间隔不宜过小。 - 合规与体验:过度惩罚可能伤害正常用户;请谨慎设计
onThreat。 - 快捷键拦截:仅挡常见快捷键;无障碍与高级用户仍可通过菜单或其它方式打开 DevTools,勿当作安全边界。
构建
pnpm --filter anti-debug build
pnpm --filter anti-debug check-types产物目录 dist/ 仅两个文件(单文件分发):
index.js:单入口rolldown打成一个 chunk,再经javascript-obfuscator处理;index.d.ts:dts-bundle-generator自src/index.ts合并生成的单文件类型声明(与package.json的types/exports对齐)。
构建开始时会清空 dist/,避免历史构建遗留的多份 .d.ts。
若根目录 .gitignore 忽略了 dist/,则构建产物不入库;克隆后需先执行 pnpm --filter anti-debug build,依赖方才能解析类型与运行时代码。
压缩与混淆说明
- Rolldown(Oxc Minifier):
minify开启完整压缩与名称混淆;必须设置compress.dropDebugger: false,否则默认会删除源码中的debugger,detectDebuggerTiming会失效。 - javascript-obfuscator:对打包结果做字符串阵列、Base64 编码等增强混淆;未开启控制流平坦化/自防御等,以降低体积与误伤风险。
若只需 Rolldown 压缩、不要第二层混淆,可将 package.json 中 build 改为仅 rolldown -c。
与其他措施的关系
| 措施 | 说明 | | ---- | ---------------------------------------- | | 本库 | 运行时启发式,可组合埋点与温和响应 | | 构建 | 压缩、混淆、关闭生产 Source Map | | 架构 | 敏感逻辑与密钥放在服务端;前端仅展示结果 | | 合规 | 遵循当地法律与用户协议,勿用于恶意目的 |
许可证
ISC(与 package.json 保持一致)。
