|
Download docs/anti-detection-final-recommendations.md from webhook/codex: direct link, hf CLI and curl.
- Browser
- Download file 13.6 kB
-
https://huggingface.co/spaces/webhook/codex/resolve/main/docs/anti-detection-final-recommendations.md
- Command line
-
hf download hf://spaces/webhook/codex/docs/anti-detection-final-recommendations.md
-
curl -L -o anti-detection-final-recommendations.md https://huggingface.co/spaces/webhook/codex/resolve/main/docs/anti-detection-final-recommendations.md
13.6 kB
| # HTTP-Only 注册链路反检测 — 最终完整修复建议 | |
| > **版本**:v3 全量版(合并 3 轮分析) | |
| > **方法论**:逐行代码审计 + 真实 Chrome 行为对照 + codex-suite-win 参考实现对比 + 防御者视角 10 维度 threat model | |
| > **范围**:覆盖外壳层(HTTP/TLS)、行为层(时序/流量形状)、内核层(Sentinel PoW 载荷) | |
| --- | |
| ## 检测维度总览 | |
| ``` | |
| ┌─ 外壳层(HTTP 请求长什么样)──────────────────────────────┐ | |
| │ TLS/H2 指纹 · HTTP headers · Client Hints · sec-fetch-* │ | |
| │ traceparent/datadog · 首请求导航特征 │ | |
| ├─ 行为层(请求的节奏和模式)──────────────────────────────┤ | |
| │ 步骤间延迟 · 流量入口形状 · 跨账号统计关联 │ | |
| │ 密码/名字/生日的统计指纹 │ | |
| ├─ 内核层(PoW token 里嵌的环境数据)──────────────────────┤ | |
| │ 时区 vs IP 地理 · 语言签名 vs Accept-Language │ | |
| │ 屏幕分辨率 · navigator/window 属性池 · 哈希算法版本 │ | |
| └──────────────────────────────────────────────────────────┘ | |
| ``` | |
| --- | |
| ## 注册链路完整请求地图 | |
| | # | 端点 | 代码位置 | headers 来源 | | |
| |---|---|---|---| | |
| | ① | `GET auth.openai.com/oauth/authorize?...` | `register.py:248` | **无自定义 headers** | | |
| | ② | `POST sentinel.openai.com/backend-api/sentinel/req` | `http_client.py:374` | origin + referer + content-type | | |
| | ③ | `POST auth.openai.com/api/accounts/authorize/continue` | `register.py:372` | referer + accept + content-type + sentinel | | |
| | ④ | `POST auth.openai.com/api/accounts/password/verify` | `register.py:457` | **裸 headers** | | |
| | ⑤ | `POST auth.openai.com/api/accounts/email-otp/validate` | `register.py:2193` | **裸 headers** | | |
| | ⑥ | `POST auth.openai.com/api/accounts/create_account` | `register.py:2281` | **裸 headers** | | |
| | ⑦ | `POST auth.openai.com/oauth/token` | `oauth.py:160` | **独立一次性会话** | | |
| --- | |
| ## 全部问题清单与优先级 | |
| ### 🔴 P0 — 立即修复(每项都是可被直接检测的暴露点) | |
| --- | |
| #### P0-1. Sentinel PoW 语言签名 vs Accept-Language 矛盾 | |
| **代码位置**:`sentinel.py:18` vs `http_client.py:261` | |
| ```python | |
| # sentinel.py — PoW 内部声称浏览器语言 | |
| _LANGUAGE_SIGNATURE = "en-US,es-US,en,es" # ← 包含西班牙语 | |
| # http_client.py — HTTP 请求头 | |
| "Accept-Language": "en-US,en;q=0.9" # ← 只有英语 | |
| ``` | |
| **问题**:同一个浏览器的语言配置在 PoW 载荷和 HTTP 请求中对不上。服务端解码 PoW 后可直接比对。 | |
| **修复**:统一为 `"en-US,en"` 或从 BrowserProfile 中读取。 | |
| **工时**:5 分钟 | |
| --- | |
| #### P0-2. Sentinel PoW 时区硬编码 EST,与代理 IP 地理位置冲突 | |
| **代码位置**:`sentinel.py:29` | |
| ```python | |
| browser_now = datetime.now(timezone(timedelta(hours=-5))) | |
| # → "GMT-0500 (Eastern Standard Time)" | |
| ``` | |
| **问题**:PoW 永远声称浏览器在美东时区。如果代理 IP 在欧洲/亚洲,IP 地理位置 vs PoW 时区 = 矛盾。 | |
| **修复**:改用 UTC(`time.gmtime()` + `"GMT+0000 (Coordinated Universal Time)"`),和 codex-suite-win 保持一致。UTC 不暴露地理位置。 | |
| **工时**:5 分钟 | |
| --- | |
| #### P0-3. Sentinel PoW 屏幕分辨率不是真实值 | |
| **代码位置**:`sentinel.py:17` | |
| ```python | |
| _SCREEN_SIGNATURES = (3000, 3120, 4000, 4160) | |
| # 没有任何真实显示器是这些分辨率 | |
| ``` | |
| **修复**:替换为真实常见值,如 `"1920x1080"`、`"2560x1440"`、`"1366x768"`。codex-suite-win 使用 `"1920x1080"`。 | |
| **工时**:5 分钟 | |
| --- | |
| #### P0-4. impersonate 版本与 User-Agent 版本分裂 | |
| **代码位置**:`http_client.py:29` + `http_client.py:258` | |
| ```python | |
| impersonate: str = "chrome" # → TLS 层 = 最新 Chrome (131+) | |
| "User-Agent": "...Chrome/120.0.0.0..." # → 应用层 = Chrome 120 | |
| ``` | |
| **问题**:TLS ClientHello 的指纹对应 Chrome 131+,但 UA 声称 Chrome 120。 | |
| **修复**:建立 BrowserProfile 工厂,绑定 `impersonate` 版本与 UA/sec-ch-ua: | |
| ```python | |
| _CHROME_PROFILES = [ | |
| {"impersonate": "chrome120", "major": 120, "build": 6099, | |
| "sec_ch_ua": '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"'}, | |
| {"impersonate": "chrome131", "major": 131, "build": 6778, | |
| "sec_ch_ua": '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"'}, | |
| # 按需扩展 | |
| ] | |
| ``` | |
| **工时**:1 小时 | |
| --- | |
| #### P0-5. 所有请求缺少 sec-ch-ua 三件套 | |
| **代码位置**:整个 `src/` 目录 — 零个 `sec-ch-ua` | |
| Chrome 从 2021 年起**每个 HTTPS 请求默认发送**: | |
| ``` | |
| sec-ch-ua: "Chromium";v="120", "Google Chrome";v="120", "Not_A Brand";v="8" | |
| sec-ch-ua-mobile: ?0 | |
| sec-ch-ua-platform: "Windows" | |
| ``` | |
| 你的 7 个请求阶段全部缺失。声称是 Chrome 但不发 Chrome 默认 headers = 最基本的检测信号。 | |
| **修复**:包含在 P0-4 的 BrowserProfile 中。 | |
| **工时**:含在 P0-4 中 | |
| --- | |
| #### P0-6. 注册流程零延迟,全链路 < 2 秒完成 | |
| **代码位置**:`register.py` 全流程 | |
| 7 个 HTTP 请求之间没有任何 `time.sleep()`,请求背靠背发出。真实用户从打开注册页到完成至少 30-120 秒。 | |
| **修复**:在关键步骤间加入正态分布延迟: | |
| ```python | |
| import random, time | |
| def _human_delay(mean=3.0, std=1.0, minimum=1.0): | |
| delay = max(random.gauss(mean, std), minimum) | |
| time.sleep(delay) | |
| ``` | |
| - `_get_device_id` → `_check_sentinel`:延迟 1-3秒 | |
| - `_submit_auth_start` → `_submit_login_password`:延迟 2-5秒("用户在输密码") | |
| - `_validate_verification_code`:延迟 5-15秒("用户在等验证码邮件") | |
| - `_create_user_account`:延迟 2-4秒("用户在填姓名和生日") | |
| **工时**:30 分钟 | |
| --- | |
| #### P0-7. 阶段 ④⑤⑥ 的 headers 风格与 ③ 不一致 | |
| **代码位置**:`register.py:459`、`register.py:2195`、`register.py:2283` | |
| `password_verify`、`validate_otp`、`create_account` 只有 3 行最小 headers(referer + accept + content-type),缺少: | |
| - `origin` | |
| - `oai-device-id` | |
| - `sec-ch-ua` 三件套 | |
| - `sec-fetch-*` 三件套 | |
| 同一会话中 ③ 带了 sentinel 和更多 headers,④⑤⑥ 突然"简化" = header 风格突变。 | |
| **修复**:统一使用 `profile.json_request_headers(referer)` 构建,至少加 `origin` 和 `sec-fetch-*`。 | |
| **工时**:30 分钟 | |
| --- | |
| ### 🟡 P1 — 建议修复(降低检测风险、提高耐久性) | |
| --- | |
| #### P1-1. traceparent 与 x-datadog-trace-id 值不一致 | |
| **代码位置**:`register.py:279-288` | |
| `traceparent` 用 `uuid4().hex` 做 trace-id,`x-datadog-trace-id` 用另一个随机十进制数。两者必须对应同一个 trace。当前实现比不发更糟糕。 | |
| **修复**:**推荐直接移除**这些 headers。如需保留,从同一 trace-id 派生: | |
| ```python | |
| trace_id_hex = uuid.uuid4().hex | |
| dd_trace_id = int(trace_id_hex[16:], 16) # 低64位转十进制 | |
| ``` | |
| **工时**:15 分钟 | |
| --- | |
| #### P1-2. 密码无特殊字符,批量可指纹 | |
| **代码位置**:`constants.py:179` | |
| ```python | |
| PASSWORD_CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" | |
| # → 所有账号密码 = [a-zA-Z0-9]{12},无特殊字符 | |
| ``` | |
| 同一 IP 注册的所有账号密码都是相同字符集和长度,统计可识别。 | |
| **修复**: | |
| ```python | |
| PASSWORD_CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*" | |
| DEFAULT_PASSWORD_LENGTH = random.randint(12, 16) | |
| # 确保至少包含 1 特殊字符 | |
| ``` | |
| **工时**:10 分钟 | |
| --- | |
| #### P1-3. Name 只有名没有姓 | |
| **代码位置**:`constants.py:201` | |
| ```python | |
| name = random.choice(FIRST_NAMES) # → "James"(无姓) | |
| ``` | |
| OpenAI about-you 页面要的是 Full Name,只有一个词极罕见。 | |
| **修复**:加 LAST_NAMES 列表,生成 `"James Smith"` 格式。 | |
| **工时**:10 分钟 | |
| --- | |
| #### P1-4. 首请求(_get_device_id)无浏览器导航 headers | |
| **代码位置**:`register.py:248` | |
| ```python | |
| response = self.session.get(self.oauth_start.auth_url, timeout=20) | |
| # ← 没有 Accept, 没有 Upgrade-Insecure-Requests, 没有 sec-fetch-* | |
| ``` | |
| 真实浏览器导航到页面时的 headers: | |
| ``` | |
| Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 | |
| Upgrade-Insecure-Requests: 1 | |
| Sec-Fetch-Dest: document | |
| Sec-Fetch-Mode: navigate | |
| Sec-Fetch-Site: none | |
| Sec-Fetch-User: ?1 | |
| ``` | |
| **修复**:补上导航请求标准 headers。 | |
| **工时**:10 分钟 | |
| --- | |
| #### P1-5. Sentinel navigator/window 属性池太小 | |
| **代码位置**:`sentinel.py:19-20` | |
| ```python | |
| _NAVIGATOR_KEYS = ("location", "ontransitionend", "onprogress") # 3 个 | |
| _WINDOW_KEYS = ("window", "document", "navigator") # 3 个 | |
| ``` | |
| codex-suite-win 有 21 个 navigator 属性、6 个 window 属性。你的 3 个会导致多次注册中频繁重复。 | |
| **修复**:扩展到至少 15+ 个真实 Chrome navigator 属性。 | |
| **工时**:15 分钟 | |
| --- | |
| #### P1-6. Sentinel 请求缺 sec-ch-ua 和 sec-fetch-* | |
| **代码位置**:`http_client.py:376-380` | |
| Sentinel 请求只有 origin/referer/content-type,缺少浏览器标准 headers。 | |
| **修复**:补 `sec-ch-ua` 三件套 + `sec-fetch-dest: empty` + `sec-fetch-mode: cors` + `sec-fetch-site: cross-site`。 | |
| **工时**:10 分钟 | |
| --- | |
| #### P1-7. Sentinel PoW 哈希算法可能不匹配当前版本 | |
| **代码位置**:`sentinel.py:82` | |
| 你用 SHA3-512,codex-suite-win 用 FNV-1a。这是两种不同的 challenge 协议。需要验证当前 OpenAI 注册链路使用的是哪个版本。 | |
| **修复**:抓包确认 sentinel/req 响应中的 challenge 格式。如果 OpenAI 已升级,需要更新哈希算法。 | |
| **工时**:1-2 小时(含调研) | |
| --- | |
| #### P1-8. 注册入口跳过 chatgpt.com 前端 | |
| 你的流程直接 GET `auth.openai.com/oauth/authorize`,跳过了真实用户的路径:`chatgpt.com → CSRF → signin/openai → 跳转到 auth`。 | |
| **修复**:模拟 chatgpt.com 入口流,注入 `ext-oai-did` + `auth_session_logging_id`。 | |
| **工时**:2-3 小时 | |
| --- | |
| ### ⚪ P2 — 灰度验证(长期增强) | |
| --- | |
| #### P2-1. 跨账号统计关联 | |
| 同一 IP 批量注册时,所有账号共享:单一 Chrome 版本、相同密码字符集/长度、相同名字池、相同 TLS 指纹、相同注册耗时。 | |
| **修复**:通过 P0-4(多版本 Profile 池)+ P1-2(密码多样化)+ P1-3(名字多样化)+ P0-6(延迟随机化)综合缓解。 | |
| --- | |
| #### P2-2. OAuth token exchange 使用独立会话 | |
| `oauth.py:160` 使用 `cffi_requests.post` 而非 `self.session.post`,不携带前面的 cookies。 | |
| **修复**:改为使用主会话发送 token exchange 请求。 | |
| **工时**:30 分钟 | |
| --- | |
| #### P2-3. 出生年份均匀分布 | |
| ```python | |
| birth_year = random.randint(current_year - 45, current_year - 18) | |
| # → 均匀分布,但真人年龄是正态分布 | |
| ``` | |
| **修复**:改为正态分布 `int(random.gauss(28, 6))`,限制在 18-45 岁。 | |
| **工时**:10 分钟 | |
| --- | |
| #### P2-4. ext-oai-did / auth_session_logging_id | |
| codex-suite-win 在 signin 时注入这两个参数,你的项目没有。 | |
| **修复**:在 OAuth 入口流中补充。 | |
| **工时**:含在 P1-8 中 | |
| --- | |
| ## 修复依赖图与落地顺序 | |
| ```mermaid | |
| graph TD | |
| A["P0-4 BrowserProfile 工厂"] --> B["P0-5 sec-ch-ua 全覆盖"] | |
| A --> C["P0-7 统一 header 构建"] | |
| A --> D["P1-6 Sentinel 补 headers"] | |
| A --> G["P1-4 首请求导航 headers"] | |
| E["P0-1 PoW 语言签名"] --> |独立| E | |
| F["P0-2 PoW 时区"] --> |独立| F | |
| H["P0-3 PoW 屏幕分辨率"] --> |独立| H | |
| I["P0-6 步骤间延迟"] --> |独立| I | |
| C --> J["P1-1 移除 traceparent"] | |
| K["P1-2 密码特殊字符"] --> |独立| K | |
| L["P1-3 Name 加姓"] --> |独立| L | |
| ``` | |
| ### 推荐执行顺序 | |
| | 批次 | 内容 | 总工时 | 效果 | | |
| |---|---|---|---| | |
| | **第 1 批** | P0-1 + P0-2 + P0-3(PoW 内部 3 个矛盾) | 15 分钟 | 消除 PoW 载荷的内部自相矛盾 | | |
| | **第 2 批** | P0-6(加延迟) + P1-2(密码)+ P1-3(姓名) | 50 分钟 | 消除行为层最明显的批量特征 | | |
| | **第 3 批** | P0-4 + P0-5(BrowserProfile + sec-ch-ua) | 1 小时 | 消除 TLS/UA 分裂和 Client Hints 缺失 | | |
| | **第 4 批** | P0-7 + P1-4 + P1-6(统一 headers) | 50 分钟 | 消除 header 风格突变 | | |
| | **第 5 批** | P1-1 + P1-5 + P1-7 | 2.5 小时 | 清理 traceparent / 扩展 PoW 属性池 / 确认哈希算法 | | |
| | **第 6 批** | P1-8 + P2-*(入口流 + 灰度项) | 3-4 小时 | 流量形状对齐 | | |
| --- | |
| ## 修复后的覆盖率预估 | |
| | 侦察维度 | 修复前 | 第 1-2 批后 | 第 3-4 批后 | 全部完成后 | | |
| |---|---|---|---|---| | |
| | TLS/HTTP2 指纹 | ⚠️ 版本不匹配 | ⚠️ | ✅ | ✅ | | |
| | HTTP headers 一致性 | ❌ 3 个裸端点 | ❌ | ✅ | ✅ | | |
| | Client Hints | ❌ 零个 | ❌ | ✅ | ✅ | | |
| | Datadog 追踪头 | ❌ 值矛盾 | ❌ | ❌ | ✅ | | |
| | 请求时序/节奏 | ❌ 零延迟 | ✅ | ✅ | ✅ | | |
| | 流量入口形状 | ❌ 跳过前端 | ❌ | ❌ | ✅ | | |
| | 账号数据统计模式 | ❌ 批量可指纹 | ✅ | ✅ | ✅ | | |
| | 首请求导航特征 | ❌ 无 headers | ❌ | ✅ | ✅ | | |
| | PoW 内部环境一致性 | ❌ 3 处矛盾 | ✅ | ✅ | ✅ | | |
| | 跨账号统计关联 | ❌ 单一 profile | ⚠️ | ✅ | ✅ | | |