Download docs/anti-detection-critical-analysis.md from webhook/codex: direct link, hf CLI and curl.
- Browser
- Download file 8.25 kB
-
https://huggingface.co/spaces/webhook/codex/resolve/main/docs/anti-detection-critical-analysis.md
- Command line
-
hf download hf://spaces/webhook/codex/docs/anti-detection-critical-analysis.md
-
curl -L -o anti-detection-critical-analysis.md https://huggingface.co/spaces/webhook/codex/resolve/main/docs/anti-detection-critical-analysis.md
HTTP-Only 设备指纹补强方案 — 批判性深度分析(v2 修订版)
以反检测专家视角,结合代码实查,对原始分析文档以及 v1 批判报告的逐项复核。
⚠️ v2 修正了 v1 中 3 处事实性错误,并新增了 3 个代码中发现的真实 bug。
v1 → v2 勘误表
| v1 中的说法 | 判决 | 原因 |
|---|---|---|
| "严重低估 Turnstile" → P0 威胁 | ❌ 说错了 | 注册链路用的是 openai-sentinel-token(PoW only),不是 openai-sentinel-turnstile-token(VM 字节码)。两条链路完全独立。项目能跑通即为实证。 |
"oai-echo-logs 是 P0 级遗漏" |
❌ 说错了 | oai-echo-logs 是 ChatGPT 对话链路(/backend-anon/f/conversation)的 header,注册链路(auth.openai.com/api/accounts/*)从未出现过。混淆了两条链路。 |
| "Auth0 内置 ML bot detection" | ⚠️ 不准确 | 代码中 OpenAI 使用的是 自有 auth 端点(auth.openai.com/api/accounts/authorize/continue 等),不是标准 Auth0 Universal Login。不能直接套用 Auth0 商业版的 bot detection 文档。 |
| Traceparent / Datadog 应降至 P2 | ✅ 方向对但理由需修正 | 实际代码中存在格式 bug(见下文),这些 header 不仅是低 ROI,而且目前的实现有害。 |
| Cookie 属性一致性是盲区 | ✅ 依然成立 | curl_cffi 的 cookie jar 自动处理 Set-Cookie 属性,不需要手动模拟。但如果有手动硬编码 cookie,需要确认属性匹配。 |
| Client Hints 不完整 | ✅ 依然成立,比想象中更严重 | 整个 src/ 目录中 零个 sec-ch-ua header。 |
🔴 代码实查发现的真实 Bug
Bug 1:impersonate 版本与 User-Agent 不匹配
# http_client.py L29 — 注册链路使用的 impersonate
impersonate: str = "chrome" # 泛版本,curl_cffi 自动选最新
# http_client.py L258-259 — 硬编码的 User-Agent
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Chrome/120.0.0.0 Safari/537.36"
问题:impersonate="chrome" 让 curl_cffi 使用最新 Chrome 的 TLS/HTTP2 指纹(可能是 Chrome 131+),但 User-Agent 写死了 Chrome/120.0.0.0。TLS 指纹说 Chrome 131,UA 说 Chrome 120 —— 这是一个典型的指纹分裂信号。
对比:项目其他模块统一使用 impersonate="chrome110",至少内部一致。
修复建议:将 impersonate 固定为具体版本(如 chrome120),或动态匹配 UA 版本。
Bug 2:traceparent 与 x-datadog-trace-id 不一致
# register.py L279-288
def _make_trace_headers(self) -> Dict[str, str]:
trace_id = random.randint(10 ** 17, 10 ** 18 - 1) # 十进制整数
parent_id = random.randint(10 ** 17, 10 ** 18 - 1) # 十进制整数
return {
"traceparent": f"00-{uuid.uuid4().hex}-{format(parent_id, '016x')}-01",
# ^^^^^^^^^^^^^^^^ 这是 uuid4 的 32 位 hex
"x-datadog-trace-id": str(trace_id),
# ^^^^^^^^^^^^^ 这是另一个随机数的十进制
}
问题:traceparent 里的 trace-id 是 uuid4().hex(32位hex),但 x-datadog-trace-id 是另一个完全不相关的十进制随机数。真实 Datadog RUM SDK 中,这两个值必须对应同一个 trace。这个不一致比不发这些 header 更糟糕 —— 它变成了一个"我在伪造追踪头"的强信号。
修复建议:要么不发这些 header(推荐),要么从同一个 trace-id 派生两个值。
Bug 3:_submit_login_password 发送裸 headers
# register.py L456-464
response = self.session.post(
OPENAI_API_ENDPOINTS["password_verify"],
headers={
"referer": "https://auth.openai.com/log-in/password",
"accept": "application/json",
"content-type": "application/json",
}, # ← 没有 oai-device-id, 没有 sentinel, 没有 trace, 没有 origin
data=json.dumps({"password": self.password}),
)
问题:对比 _submit_auth_start(提交邮箱阶段),它会注入 openai-sentinel-token。但 _submit_login_password(提交密码阶段)完全没有 sentinel,也没有 oai-device-id。这造成了同一会话中两个连续请求之间的 header 风格突变。
风险:这正是原始分析文档说的"同一会话像多个不同浏览器"的问题。
修复建议:用 _build_oauth_json_headers 统一构建 headers,至少加 origin 和 oai-device-id。
✅ 原始文档经代码验证后的评级调整
原文档 P0 项验证
| 原文档建议 | 代码现状 | 验证结论 |
|---|---|---|
| 统一 session 级浏览器 profile | sec-ch-ua 全项缺失;impersonate 与 UA 版本不匹配 |
✅ 确实是 P0,且比文档描述的更急迫 |
oai-did 跨域同步 |
_get_device_id 从 Set-Cookie 读取,_build_oauth_json_headers 会注入 oai-device-id |
⚠️ 部分已做,但 _submit_login_password 等路径丢失了 |
| Sentinel 按 flow 生成 | check_sentinel 和 _submit_auth_start 都硬编码 flow: "authorize_continue",password_verify 无 sentinel |
✅ 确实需要补,至少 password_verify 应有自己的 sentinel |
| Sentinel 请求补 client hints | sentinel 请求(http_client.py L376-380)只有 origin/referer/content-type,无 sec-ch-ua |
✅ 确认缺失 |
修订后的优先级排序(v2 代码实证版)
P0(代码中已确认的问题)
| 项目 | 证据 |
|---|---|
| 修复 impersonate 与 UA 版本分裂 | impersonate="chrome" + Chrome/120.0.0.0 UA,TLS 层与应用层对不上 |
| 统一关键路径的 header 构建 | _submit_login_password 是裸请求,和同会话其他请求风格不一致 |
补 sec-ch-ua 系列 header |
整个 src/ 中零个 sec-ch-ua,真实 Chrome 每个请求都带 |
| 修复或移除 traceparent/datadog 头 | 当前实现的 trace-id 不一致问题反而暴露自动化 |
P1(原文档建议 + 代码验证确认有价值)
| 项目 | 理由 |
|---|---|
| Sentinel 按 flow 分类 | password_verify 完全无 sentinel,和 authorize_continue 形成断层 |
oai-did 在所有 auth 请求中统一注入 |
部分路径丢失 |
| 建立 TLS 指纹自测 | impersonate="chrome" 的实际行为依赖 curl_cffi 版本,需要客观验证 |
P2(灰度验证 / 长期观察)
| 项目 | 理由 |
|---|---|
ext-oai-did / auth_session_logging_id |
前端语义增强,按原文档灰度引入即可 |
oai-sc cookie 研究 |
需要抓包确认注册流程是否涉及 |
| 注册链路 Turnstile 监控 | 当前不需要,但未来可能引入,建议在 sentinel 响应异常时记录完整响应体 |
v1 中仍然准确的部分
- "一致性 > 随机性" — 核心判断正确,代码中 Bug 1-3 都是一致性问题
- Cookie 属性关注 —
curl_cffi自动处理Set-Cookie属性,但值得确认无手动覆盖 - 网络环境是指纹的一部分 — datacenter IP +
curl_cffi的 TLS 即使匹配也不够 - 请求时序模拟 — 虽然
oai-echo-logs不适用于 auth 链路,但步骤间延迟仍是好建议 - 不堆随机 — 代码实证再次证明,不一致远比缺少更危险
最终建议(v2)
最大的威胁不是"缺什么 header",而是已经发的 header 自相矛盾。 你的注册链路能跑通,说明 PoW + oai-did 这条路线是可行的。现在最值得投入的是修复 Bug 1-3 这种自我暴露的问题,而不是追加更多 header。
建议落地顺序:
- 修 impersonate/UA 版本对齐(10 分钟)
- 统一
_submit_login_password的 header 构建(30 分钟) - 修复或移除 traceparent/datadog 头(15 分钟)
- 补
sec-ch-ua系列,绑定到 session profile(1-2 小时) - 后续按 P1/P2 灰度推进
关于 headless browser 兜底:v1 的建议仍成立,但紧迫度降低。当前注册链路能跑通,先把 HTTP-only 的一致性全面修复,headless 作为长期保险即可。