那个写着“请验证您是真人”的小勾选框,到底在防什么、怎么识别机器人, 以及一个真实浏览器自动化工具是从哪几个维度把它过掉的。带真实实测、诚实的边界。
你一定见过它:打开某个网站,先蹦出一页“正在进行安全验证”, 中间一个勾选框「请验证您是真人」,配着 Cloudflare 的橙色云朵。勾一下、转个圈,过了。 这东西叫 Cloudflare Turnstile / Managed Challenge。
它看起来只是“点个框”,但那一下点击背后,是一整套机器人识别在运行。 先讲它怎么防,再讲怎么过。
Turnstile 不是靠“你会不会点框”来判断的——勾选框只是最后的仪式。 真正的判定发生在你看到页面之前,后台一段 JS 在几百毫秒里给你打了个 威胁分(threat score)。打分的依据分四层:
不需要你做任何动作就能采集的信号:
navigator.webdriver 是不是 true(自动化框架的经典破绽)HeadlessChrome、版本和平台对不对得上navigator.plugins / languages / platform 是否为空或异常isTrusted:浏览器原生输入是 true,JS 合成的 click() 是 falseRuntime.enable 的副作用泄漏数据中心 IP(云服务器机房段)天然高风险;住宅/移动 IP 天然低风险。 同一个 IP 短时间大量请求,分数直接拉黑。
打完分,结果只有三种:
| 威胁分 | 表现 | 你看到的 |
|---|---|---|
| 高(像真人) | invisible 放行 | 什么都没有,直接进 |
| 中(不确定) | managed challenge | 「请验证您是真人」勾选框 |
| 低(像机器人) | 拦截 / 死循环 | 勾了也一直转圈,进不去 |
过关之后,Cloudflare 会发一张通行证 cookie:cf_clearance。
它是 HttpOnly(JS 读不到),而且绑定你的 IP + User-Agent。
带着这张票、用同一个 IP 和 UA 再来,就直接跳过验证——这点后面有用。
看懂了打分维度,怎么过就清楚了——把每个维度都做成真人的样子。 我们用的是 chrome-use(一个真实浏览器自动化工具)。
最关键的一步:不开无头浏览器,而是通过浏览器扩展中继, 驱动用户自己那台、已经登录、天天在用的真实 Chrome。 于是指纹是真的、cookie 是真的、出口是住宅 IP。 被动指纹和 IP 信誉这两层,直接就是满分。
剩下的零星破绽用底层覆盖补掉,而且原则是“原生覆盖 > JS 撒谎” ——能用 CDP / Chrome 启动参数改的,就不用 JS 打补丁(JS 补丁本身会留痕):
navigator.webdriver → falseHeadlessChromenavigator.platform 修成 MacIntel 这类真实值针对行为检测:鼠标走曲线、带减速、落点有抖动,打字用变速节奏, 滚动有缓动。专门骗 Akamai / DataDome / Turnstile 这类行为评分。
Turnstile 校验那一下点击的 isTrusted。
JS 合成的 element.click() 是 isTrusted=false,当场被拒——
这是绝大多数“纯脚本”方案死在这一步的原因。
而我们走 CDP 的 Input.dispatchMouseEvent,浏览器把它当成真实硬件输入,
isTrusted=true,和真人手点一模一样。这是“真实浏览器 + CDP”这条路相对纯 HTTP 脚本的硬优势。
我们在两个公开 demo 上实测(真实 Chrome + 受信点击):
success: true。cf_clearance cookie。3x00000000000000000000FF,强制弹挑战、点了必过,页面上会有红字
“For testing only”)。所以严格说,它们测的是
“能不能定位并受信点击那个会动的勾选框”这个机械能力,
而不是 Cloudflare 的真实威胁评分。机械层面我们 2/2 通过;
真实评分对抗(生产 key、真打分)是另一个维度,公开 demo 测不到——因为没人会把生产 key 摆出来给你测。
过关那张 cf_clearance 是真正值钱的东西。两个要点决定它能不能复用:
document.cookie 根本读不到,
必须走 CDP 的 cookie API 读和存。很多人用 document.cookie 存会员态,
结果把 cf_clearance 弄丢了,下次还得重解。所以我们给 chrome-use 加了一个 过关前预检 命令
chrome-use cf-status:访问前先判断“当前是不是 Cloudflare 挑战页”
以及“有没有还没过期的 cf_clearance”,给出建议:
$ chrome-use cf-status
✓ cleared — no challenge, proceed # 已有有效通行证,别重解
challenged: no
cf_clearance: valid, expires in 27m 11s
device trusted: yes (CF_VERIFIED_DEVICE)
# 三种结论:
# proceed → 已过关,直接用
# solve → 有挑战、没通行证,去解
# reissue → 有通行证但页面还拦着 → IP/UA 漂了,重解
配合“驱动真实 Chrome”,续存基本是免费的:解一次,通行证就留在真实 profile 里,下次同 IP 同 UA 直接进。
必须说清楚我们这条路唯一的软肋:CDP(调试协议)attach 本身是可被检测的——
Runtime.enable 等操作会留下信号,理论上一个足够狠的生产站能据此压低你的分。
所以这不是“一招通杀”,而是持续对抗:检测方加新指纹,绕过方补新覆盖。
nowsecure 那句“一直是动态的”,说的就是这个——挑战框每次位置都变、形态都变,
就是逼你别写死、别偷懒。
这也是为什么这类研究的正经用途是给自己的工具做反检测自测: 你得知道自己在每个维度上还露不露馅,才能补。
仅管理员可见。点击后将物理删除该文章内容(含跨语种联删规则)。