Claude Code API安全漏洞:dev@example.com邮箱硬编码导致生产环境信息泄露

Claude Code API 的 curl 示例里硬编码了 dev@example.com,这不是占位符,是真实跑进生产环境的邮箱。官方文档、CLI 工具和 SDK 生成的请求头中,User-Agent 固定为:
curl/8.10.1 (Linux) Claude-Code-CLI/1.2.0 (dev@example.com)dev@example.com 不会自动替换。开发者没改,它就真发出去了——CI/CD 流水线、GitHub Actions 日志、Slack Bot 请求、OpenClaw 接入 Claude 的代码执行模块,全在持续泄露注册邮箱。
问题不在服务端。User-Agent 本该说明客户端类型和版本(RFC 7231),结果被当成隐式身份凭证用。API Key 控制权限,User-Agent 暴露身份,两者耦合,违背 OAuth 和密钥分离原则。攻击者不需要碰密钥,只要扫一遍代理日志或审计平台原始请求流,就能批量捞出活跃开发者邮箱,直接喂给钓鱼系统。
硬编码邮箱不是“示例”,是生产事故导火索
claude-code-cli v1.2.0 默认行为就是把 dev@example.com 塞进 User-Agent。不传 --email 参数?就用这个。通过 CLAUDE_EMAIL 环境变量设邮箱?原样写进去,不校验、不脱敏、不警告。
后果很直接:
- OpenClaw 类 Agent 编排节点复用 CLI 默认配置 → 每条请求都带真实邮箱
- Shell 脚本直接抄文档里的 curl 命令 →
dev@example.com进入所有下游日志系统 - GitLab CI 的
.gitlab-ci.yml示例模板照搬该命令 → 邮箱随构建日志永久存档
User-Agent 不是凭证容器
AI Agent 工具链对“身份标识”普遍缺乏边界意识。User-Agent 是协商兼容性的字段,不是归属证明。Claude Code 把它当开发者 ID 用,和 API Key 形成双凭证绑定:Key 决定能不能调,User-Agent 告诉你是谁。最小权限原则在这里失效了——攻击者只需监听流量或翻日志,就能拿到邮箱列表。
对比 Llama.cpp 或 Ollama 的 curl 示例:
User-Agent: llama-cpp/0.2.5纯版本标识,零业务信息。Agent 工具链需要明确标识分层:
- 调试阶段:
dev@local - 测试阶段:哈希化 ID(如
agent-7f3a9c2e) - 生产阶段:禁用邮箱等 PII 字段
👉 Binance · OKX · Gate.io · HTX · Bitget
立即排查:三步阻断泄露链
别等 Anthropic 发补丁。现在就能做:
全局 grep
grep -r "dev@example.com" . --include="*.sh" --include="*.yml" --include="*.py"验证本地 CLI 行为
curl -v https://api.anthropic.com/v1/messages 2>&1 | grep "User-Agent"如果输出含真实邮箱:升级到 v1.2.1+,或启动时加
--email ''清空字段。企业级加固
在 API 网关(Kong/Nginx)加请求头重写规则,把邮箱替换成匿名哈希:# Nginx 示例 proxy_set_header User-Agent $sent_http_user_agent; # 配合 map 或 lua 实现正则替换:(dev@example.com) → (anon-dev@example.com)OpenClaw 用户可启用
agent.http.headers.sanitize自动过滤。
“示例即生产”不是便利,是技术债
这不是单点漏洞。Cursor 曾泄露 X-Cursor-Session-ID,早期 Copilot 插件把 Authorization: Bearer <token> 明文打到日志里——根子都在把调试快捷性当成工程契约。
每行 curl、每个 SDK 初始化参数、每份 Agent YAML,都该默认按生产标准对待。建议团队:
- 把「请求头 PII 扫描」加入 CI
- 用
httpie替代裸curl:http --print h POST ...显式看头字段,拒绝黑盒调用 - AI 工具的生命线,不在模型参数量,而在每一行 HTTP 请求是否经得起审计推演
相关阅读