Claude Code CLI漏洞:curl请求中明文泄露邮箱至User-Agent字段

Claude Code 工具在生成 curl 请求时,会把开发者的真实邮箱明文塞进 User-Agent 字段——一次执行,身份就可能暴露。
Hacker News 上有用户复现了这个问题(HN thread #432819),影响 Anthropic 官方发布的 claude-code CLI v1.2.0 到 v1.3.4。工具默认构造的 UA 类似这样:
User-Agent: Claude-Code/1.3.4 (user@example.com)它不脱敏、不哈希、不掩码。服务端日志、CDN 访问记录、代理中间件(比如 Zscaler、Netskope)、第三方监控(Cloudflare Workers、Datadog RUM)都能直接看到这个字段。攻击者不需要提权,就能把邮箱和 IP、时间戳、API 路径串起来,画出清晰的行为画像。这不是纸上谈兵,已有真实泄露案例。
漏洞原理:不是配错了,是代码就这么写的
claude-code 初始化 HTTP 客户端时,硬编码调用了 getpass.getuser() 和 socket.gethostbyname(socket.gethostname()),再拼上 platform.node() 和 os.environ.get('USER') 推导“本地身份”。如果系统里设置了 EMAIL 环境变量(比如在 ~/.profile 或 ~/.gitconfig 里),它就直接读出来往 UA 里塞。
关键在于:没有过滤函数,没有掩码逻辑(比如 re.sub(r'@.*', '@xxx', email)),也没有 --no-ua-email 这类开关。HTTP 标准确实允许 UA 包含任意 ASCII 字符,但 RFC 7231 明确说 UA 应标识客户端类型,而不是终端用户——明文邮箱踩了这条线。
实际影响:敲一行命令,就锚定一次身份
执行 claude-code --file script.py --fix,底层发出的请求里,UA 已经带上了你的邮箱。这意味着:
- 请求经过公司代理或 SaaS 安全网关(如 Netskope、Zscaler),该字段会进 DLP 日志;
- 目标 API 开了访问审计(AWS API Gateway、Fastly Log Shuttle),邮箱会和请求 ID 一起存档;
- 前端埋点 SDK、CDN 自定义日志脚本,也能无声无息捕获这个 header 并上报到外部平台。
HN 上有用户证实:他调用某个开源模型托管平台的 API 后,自己的邮箱直接出现在平台后台的“最近 100 条 UA 记录”面板里——他从没主动提交过邮箱。
立即自查与修复方案
✅ 三步自查:
- 运行
claude-code --version,确认版本 ≤ v1.3.4; - 执行
claude-code --help | grep -A5 "User-Agent",看是否提示 “email-in-ua enabled by default”; 抓包验证:
tcpdump -i any port 443 -w claude.pcap & claude-code --file test.py && tshark -r claude.pcap -Y "http.request.header.user_agent contains @."
✅ 即时缓解:
- 禁用自动注入:
export CLAUDE_CODE_NO_EMAIL_IN_UA=1; - 替换为匿名 UA:
export CLAUDE_CODE_USER_AGENT="Claude-Code/1.3.4 (dev-7a2f9)"; - CI/CD 中,在 runner 的
before_script里 unsetEMAIL和GIT_AUTHOR_EMAIL。
❌ 别碰 .curlrc:claude-code 用的是 Python requests,根本不读 curl 配置文件。
👉 Binance · OKX · Gate.io · HTX · Bitget
对 AI Agent 开发者的警示
这不只是个 CLI 小 bug。它暴露了整个 AI 工具链的通病:“隐私默认缺失”——Agent 构造网络请求时,常把 os.environ、Git 配置、OS 用户名这些敏感信息,不加审查地塞进 HTTP 头、WebSocket handshake、甚至 gRPC metadata。
YITB 生态里的 OpenClaw Agent 在 v0.4.1 引入了 safe_headers 模块:默认剥离所有含 @、/home/、USER= 的字段,并支持白名单式 UA 注入(agent.set_user_agent("OpenClaw/0.4.1"))。这不是过度设计。当 Agent 是你的“数字分身”,它的每次网络出访,应该默认匿名,而不是默认实名。
行动建议:从今天起重构你的 UA 习惯
- 所有自研 CLI 工具,禁止从
os.environ或git config直接读取邮箱/用户名注入 UA; - 用
uuid.uuid4().hex[:8]或hashlib.sha256(os.getenv('HOSTNAME', '').encode()).hexdigest()[:6]生成匿名 UA 后缀; CI 流水线里加一步 header 安全扫描:
curl -sI https://example.com | grep -i "user-agent" | grep -q "@" && exit 1
隐私不是可选项,是协议层的第一行代码。下次你敲 curl,先问自己一句:这个 UA,敢贴在 GitHub 主页上吗?
相关阅读