浏览器CDP自动化检测技术-Error和Worker

BrowserScan Bot Detection CDP 技术报告

结论

目标页 https://www.browserscan.net/zh/bot-detection 的 CDP 相关检测不是哈希类纯算,而是两条浏览器运行时探针:

  1. CDP:利用 Error.stack getter 被 console.debug(error) 序列化时触发的副作用。
  2. Dev Tool:在 Worker 中执行 debugger,用 before/after 两次消息的时间差判断是否被开发者工具或调试协议暂停。

可复刻代码已写入 browserscan_bot_cdp_detection.js。它保留 BrowserScan 的判定阈值:Dev Tool 时间差大于 100ms 判定异常,after 消息 500ms 内未返回也判定异常。

源码定位

本次分析使用已落盘响应脚本:

  • 页面组件:trace_browserscan_bot_20260609_221758/response_9684_8589934601_7.BtL2bcz0.js.decoded.js
  • 检测函数:trace_browserscan_bot_20260609_221758/response_9684_8589934602_2.hd4NLkmt.js.decoded.js

组件导入关系:

js 复制代码
import {
  r as He,
  s as Ve
} from "./hd4NLkmt.js";

页面执行关系:

js 复制代码
f.value = He();        // CDP 卡片
y.value = yield Ve();  // Dev Tool 卡片

if (f.value) n.value = false;
if (y.value) n.value = false;

页面展示关系:

  • f 控制 Chrome DevTools Protocol 检测 区域里的 CDP 结果。
  • y 控制同一区域里的 Dev Tool 结果。
  • 顶部 CDP 摘要项使用 f || y
  • 任一结果为 true,总检测结果进入异常状态。

检测 1:CDP / Error.stack getter

还原后的核心逻辑:

js 复制代码
function detectChromeDevToolsProtocol() {
  let detected = false;
  const errorObject = new window.Error();

  window.Object.defineProperty(errorObject, "stack", {
    configurable: false,
    enumerable: false,
    get: function () {
      detected = true;
      return "";
    }
  });

  window.console.debug(errorObject);
  return detected;
}

判定逻辑:

  • 正常情况下,只创建 Error 并传给 console.debugstack getter 不一定会被同步读取。
  • 某些 CDP/DevTools/自动化协议链路会为了展示或传输 console 参数而序列化 Error 对象。
  • 一旦序列化过程读取 error.stack,getter 触发,detected = true
  • 返回 true 表示 CDP 相关序列化副作用被观察到。

这一条是同步探针,BrowserScan 直接把返回值写入 CDP 卡片。

检测 2:Dev Tool / Worker debugger timing

还原后的 Worker 代码:

js 复制代码
onmessage = function() {
  postMessage("before");
  debugger;
  postMessage("after");
};

主线程判定逻辑:

js 复制代码
const blob = new Blob([workerCode], { type: "application/javascript" });
const url = URL.createObjectURL(blob);
const worker = new Worker(url);

let beforeAt;
worker.onmessage = function (event) {
  if (event.data === "before") {
    beforeAt = performance.now();
    setTimeout(() => resolve(true), 500);
  } else if (event.data === "after") {
    const elapsedMs = performance.now() - beforeAt;
    resolve(elapsedMs > 100);
  }
};

worker.postMessage("");

判定逻辑:

  • Worker 收到消息后先发 before
  • 随后执行 debugger
  • 如果没有调试器介入,Worker 很快继续执行并发出 after
  • 主线程计算 after - before,大于 100ms 判定异常。
  • 如果 after500ms 内没有到达,也判定异常。

这一条是异步探针,BrowserScan 通过 yield Ve() 等待结果后写入 Dev Tool 卡片。

纯算边界

这里的"纯算"不能理解成脱离浏览器环境的固定公式。CDP 检测的输入不是字符串、canvas 图像或可枚举参数,而是运行时副作用:

  • console.debug 是否触发 Error.stack getter,取决于控制台实现、DevTools/CDP 是否附着、自动化框架是否拦截 console 参数。
  • debugger 是否造成 Worker 暂停,取决于调试器状态、断点策略、Worker 调试支持和事件循环调度。
  • 因此 JS 代码可以纯复刻判定树,但最终真假必须在目标浏览器上下文里执行得到。

可稳定复刻的部分是:

  • getter 设置方式;
  • console 调用方式;
  • Worker 源码;
  • 100ms 阈值;
  • 500ms 兜底超时;
  • CDP || Dev Tool 的页面聚合逻辑。

产物说明

browserscan_bot_cdp_detection.js 暴露全局对象:

js 复制代码
window.BrowserScanBotCDP

主要接口:

js 复制代码
BrowserScanBotCDP.detectChromeDevToolsProtocol(window);
await BrowserScanBotCDP.detectDevToolDebuggerTiming(window);
await BrowserScanBotCDP.collect(window);

collect() 返回结构:

js 复制代码
{
  cdp: { name: "CDP", detected: false, ... },
  devTool: { name: "Dev Tool", detected: false, elapsedMs: "<runtime number>", ... },
  detected: false,
  siteCompatible: {
    cdp: false,
    devTool: false,
    abnormal: false
  }
}

其中 siteCompatible.cdp 对齐页面 CDP 卡片,siteCompatible.devTool 对齐页面 Dev Tool 卡片。

验证结果

验证脚本:ruyipage_verify_browserscan_bot_cdp.py

验证方式:

powershell 复制代码
node --check .\browserscan_bot_cdp_detection.js
python .\ruyipage_verify_browserscan_bot_cdp.py

实测页面 CDP 区域文本:

text 复制代码
Chrome DevTools Protocol 检测 ... CDP 正常 Dev Tool 正常

本地复刻函数返回:

json 复制代码
{
  "cdp": false,
  "devTool": false,
  "abnormal": false
}

页面文本与复刻函数一致:CDP 为正常,Dev Tool 为正常。

相关推荐
IT_陈寒1 小时前
Python列表的+=操作符坑了我一整天
前端·人工智能·后端
右耳朵猫AI1 小时前
React周刊2026W22 | React 13周年、React Router 7.16.0、Spoiled 0.5
前端·react.js·前端框架
恋猫de小郭1 小时前
flutter_agent_lens 用 MCP 服务,将 Flutter DevTools 暴露给 AI
android·前端·flutter
广州灵眸科技有限公司1 小时前
3Tops NPU + 4核高性能架构:灵眸科技EASY-EAI-PI2开发板,为边缘AI开启“easy模式”
服务器·前端·人工智能·python·科技·深度学习·架构
李白的天不白2 小时前
服务器地址在哪里 pwd
运维·前端·nginx
AC赳赳老秦2 小时前
技术文章素材收集自动化:用 OpenClaw 自动爬取行业资讯、技术热点、优质文章
运维·开发语言·python·自动化·wpf·deepseek·openclaw
右耳朵猫AI2 小时前
JS/TS周刊2026W22 | Deno 2.8、Node.js v26.2.0、Firefox 151、Storybook 10.4、npm 12.0
javascript·node.js·firefox
晓13132 小时前
【Cocos Creator 3.x】篇——第三章 脚本编程
前端·javascript·游戏引擎
烧饼Fighting2 小时前
Jenkins自动化编译部署Spring Boot项目
spring boot·自动化·jenkins