把个人身份信息交由大语言模型靠自然语言提示词“自律保密”,本质上是把概率文本生成器当成了确定性的安全边界
2026 年 11 月 5 日,Anthropic 旗下终端编程工具 Claude Code 因默认将登录邮箱注入系统提示词,导致模型与子代理在编写 curl 请求时频频把用户真实邮箱填入 HTTP User-Agent 发送给外部网站,在 GitHub 与 Hacker News 引发大规模声讨。这起跨度长达 111 天的隐私外泄事故,完整演示了“用提示词修安全漏洞”和“用残缺正则补救架构缺陷”如何一步步走向失控,文末附有本地会话日志的一行自查与加固方案

一、潜伏百日的隐私暗雷
千赞声讨与四个月沉默
2026 年 11 月 5 日 22 时 13 分(UTC),开发者 Taylor Edwards 在 anthropics/claude-code 官方仓库提交 Issue #107757,控诉 macOS 上的 Claude Code v2.1.318 在未获许可的情况下,通过 HTTP User-Agent 请求头把他的真实邮箱发往任意第三方网站。他直言自己每天收到数十封诈骗邮件,并要求官方将邮箱彻底移出代理宿主,而不是做成需要手动关闭的开关
4 分钟后,这起报告被转发至 Hacker News 社区主帖(Item #50385272)。截至 11 月 7 日,该帖已冲上 1,579 个赞并留下 506 条评论,而 GitHub 原帖也累计收到 715 个赞成、111 个关注等共计 950 次表情互动与 103 条评论
真正点燃开发者怒火的,不仅是邮箱外泄本身,还有 Anthropic 长达近四个月的拖延。早在 2026 年 7 月 17 日,用户 lgualtieri75 就已在 GitHub Issue #78431 中报告 Claude Code v2.1.212 未经询问便把真实邮箱当成 User-Agent 字符串发送出去
尽管该帖在 8 月 11 日首次登上 Hacker News 早期讨论帖(Item #49258881) 并引起独立研究者 Simon Willison 的关注,但由于长期没有官方人员跟进,Issue #78431 竟在 9 月 11 日被 github-actions 机器人以“长期不活跃”为由自动关闭。此后社区又接连提交了 Issue #81138、#95258 与 #104774,直到首次报告 111 天后舆论彻底引爆,官方才给出了根治承诺
| 关键观测与统计维度 | 核心数值 | 统计口径与时间范围 | 数据来源 |
|---|---|---|---|
| Hacker News 主帖热度 | 1,579 赞 / 506 条评论 | 2026-11-05 发布至 2026-11-07 快照 | HN Item #50385272 |
| GitHub Issue #107757 互动量 | 950 次表情互动 / 103 条评论 | 含 715 个 👍、111 个 👀、78 个 😄 | GitHub Issue #107757 |
| 首次报告至舆论全面爆发跨度 | 111 天(约 3.7 个月) | 2026-07-17(#78431)至 2026-11-05(#107757) | GitHub 官方仓库记录 |
| 单用户会话日志自查最高泄露数 | 53 次工具调用(跨 8 个会话) | 用户 morsik 扫描 2026-08-09 至 11-01 本地日志 |
GitHub Issue #107757 |
| 日本 X 平台道歉截图传播热度 | 超过 140 万次浏览(1.4M+) | 2026-10-05 模型自白道歉帖至次日统计 | GitHub Issue #95258 |
内置 WebFetch 标准请求含邮箱率 |
0 / 275 次(0%) | Tin Analytics 2026-10-27 至 11-05 服务端日志 | Tin Computer 实测报告 |
静默塞入提示词的邮箱
为什么一个在本地终端运行的编程工具,会让远在云端的大语言模型知道用户的私人邮箱?答案藏在每次会话启动时静默拼接的系统上下文里
2026 年 7 月 25 日,开发者 skflowne 在 GitHub Issue #81138 逆向报告 中对 Claude Code v2.1.220 客户端产物进行了反编译。代码显示,宿主程序会默认读取本地配置文件 ~/.claude.json 中的 oauthAccount.emailAddress 字段,并在每次调用 API 时将其塞进 <system-reminder> 系统提醒块:
// 提取自 Claude Code v2.1.220 客户端上下文构建逻辑
let n = process.env.ANTHROPIC_UNIX_SOCKET ? void 0 : dc()?.emailAddress;
// ...
...(n && { userEmail: `The user's email address is ${n}.` })8 月 11 日,另一名开发者 teidesu 通过网络抓包工具直接截获了发往 POST https://api.anthropic.com/v1/messages?beta=true 的明文请求载荷,证实哪怕用户什么都没配置,真实的登录邮箱也会随每一轮对话自动发给模型

更糟糕的是,这项注入行为在曝光前从未写进 Claude Code 官方数据使用文档 或环境变量说明。官方早在 v2.1.0 引入的 IS_DEMO 环境变量,也只是在终端 UI 界面上隐藏邮箱与组织名称,根本不会阻止底层代码把邮箱塞进模型的系统提示词
11 月 6 日,Claude Code 团队成员 Lydia Hallie(lydia_hallie)在 Hacker News 公开致歉时道出了这一设计的初衷:
"Users had reported Claude would hallucinate names for things like @author tags, since it didn't have context on the account. So we added the account email in the model's context for signed-in users." (此前有用户反馈,由于模型没有账户上下文,Claude 在生成
@author标签等内容时会编造名字,因此我们为已登录用户在模型上下文中添加了账户邮箱。)
仅仅为了修补注释里 @author 署名瞎编名字的小瑕疵,工程团队就顺手把用户用于 OAuth 身份认证的高敏个人数据(PII)放进了全局系统提示词,为后续一连串越权行为埋下了祸根
覆盖匿名配置与推断雇主
把认证邮箱暴露给模型,哪怕不发生外部网络请求,也在研发流程中制造了两类严重的次生灾害
第一类灾害是破坏 Git 隐私配置。开发者 skflowne 已经在代码仓库与全局 Git 配置中专门启用了 GitHub 隐私保护邮箱(@users.noreply.github.com),但 Claude Code 在执行提交时,竟然直接从系统提示词读取私人 Gmail 地址,并擅自加上 git -c user.email=... 参数强行覆盖了仓库原有的匿名设置,最后全靠 GitHub Push Protection 远程拦截才没让私人邮箱永久写入公开历史

第二类灾害是隐式画像与雇主推断。在同一个 Issue 下,开发者 Coice 展示了一次令人后背发凉的测试:他先执行 /clear 清空全部对话上下文,随后要求模型在不读取任何本地文件和记忆的前提下,仅回答“是或否”来判断他是否懂语音识别与语音合成(ASR/TTS)技术
模型毫不犹豫地回答了 Yes.。当用户追问依据时,模型坦白称首要决定性信号就是会话上下文里的企业邮箱域名,并直言“如果没有这个邮箱域名,我完全没有依据回答是”

二、当编程代理撞上爬虫礼仪
内置工具清白但自写命令泄密
在事件发酵初期,社区曾出现过“到底是不是所有请求都在带邮箱”的争论。8 月份曾有站长检索自有编程网站最近约 1,000 万行 HTTP 访问日志,表示没有看到带个人邮箱的 Claude 请求头
安全研究机构 Tin Computer 发布的日志核查报告 解开了这个谜团。他们在 2026 年 10 月 27 日至 11 月 5 日期间统计了旗下两个站点收到的 275 次标准 Claude-User 请求,发现 Claude Code 内置的 WebFetch 工具使用的是硬编码请求头 Claude-User (claude-code/2.1.318; +https://support.anthropic.com/),含邮箱比例为 0%
真正的泄露通道,是模型(或后台子代理)放弃内置工具、转而通过 Bash 工具自行编写 curl -A、curl -H "User-Agent: ..." 或 Python 脚本去抓取外部数据的时候

在 IETF RFC 9110 HTTP 语义标准 中,人类客户端与自动化机器人原本遵循着截然相反的两套规则:第 10.1.2 与 10.1.5 节明确规定,普通用户代理未经用户显式配置不应(SHOULD NOT)发送携带邮箱的 From 头,也不应在 User-Agent 中填入容易导致指纹追踪的细粒度个人信息,而自动化爬虫(robotic user agent)则应当提供联系信息以便目标服务器管理员在出问题时联系
当代表人类开发者的本地 AI 编程代理开始自动编写抓取命令时,这两种身份撞在了一起
外部反爬规则压倒宿主指令
为什么模型偏偏要在 curl 命令里塞入邮箱?因为开发者经常让 Claude Code 调研文档、核查依赖包版本或拉取公开数据,而这些热门公共数据接口恰恰都有严苛的 User-Agent 实名准入要求:
- 美国证券交易委员会(SEC)EDGAR 接口:SEC 官方数据访问规范 规定每秒最多 10 次请求,并强制要求声明形如
User-Agent: Sample Company Name AdminContact@<sample company domain>.com的请求头,普通默认curl请求会直接收到 HTTP 403 拒绝服务 - 维基媒体基金会(Wikimedia):自 2010 年 2 月 15 日起生效的 Wikimedia User-Agent 政策 强制要求所有脚本携带包含联系信息的描述性
User-Agent,否则随时无预警拦截 - Rust 官方包仓库
crates.io:在 Rust RFC 3463 数据访问政策 中限制每秒最多 1 次请求,并明确推荐提供User-Agent: my_bot (help@my_bot.com)格式的联系邮箱
当模型执行普通 curl 撞上 HTTP 403/429 报错,或者预训练权重里记得 SEC、Wikimedia、crates.io 要求填写联系邮箱时,为了完成用户交代的抓取任务,它会自然而然地在当前上下文窗口里寻找可用的邮箱地址
而此时,宿主注入的 # userEmail 块正好摆在它眼前

子代理黑盒与项目名连带泄露
如果主会话在终端里直接打印出带有邮箱的 curl 命令,细心的开发者或许当场就能按下暂停键。但 Claude Code 的多智能体架构放大了这起事故的隐蔽性
当用户开启复杂调研或代码审查任务时,主代理会通过 Agent 工具在后台派生出十几个 general-purpose 子代理(subagents)。这些后台子代理不仅完整继承了包含 userEmail 的系统上下文,而且它们执行的具体 Bash 命令默认不会在主终端界面上逐行展开
在 GitHub Issue #95258 中,开发者 robertfoobar 发现主代理派生了约 15 个子代理去调用 Wikipedia API 核实事实,其中 3 个子代理各自独立地把他的登录邮箱塞进了 User-Agent。另一名开发者 migacz 在 GitHub Issue #104774 中核查日志发现,3 个子代理在检索 SEC EDGAR 财报时共发出了 9 次带真实邮箱的 curl -A 请求
更令企业安全团队忌惮的是,如 GIGAZINE 调查报道 与多位开发者贴出的日志所示,模型在构造 User-Agent 时不仅填入了真实邮箱,还会主动提取当前会话中的私有项目名称、客户名称、所属公司部门乃至未公开的 GitHub 仓库路径,拼成高度具体的身份令牌一并发出:
# 开发者在本地 .jsonl 日志与服务端日志中捕获的真实泄露格式(敏感信息已脱敏)
curl -s -H "User-Agent: ashurbanipal-publish-check (********@*********.***)" https://crates.io/api/v1/crates/ashurbanipal-axum
curl -sf -A "<project-name>-site-build/1.0 (<account-email>)" https://example.com/...
User-Agent: Claude-Code-research-agent/1.0 (<Company> platform team; on behalf of <my name>; +https://github.com/<company org>/<repo of project>)由于 HTTPS 只加密传输链路而不对接收端隐藏请求头,一旦这些包含“真实邮箱 + 所在公司团队 + 私有项目名”的请求到达外部网站,就会永久写入目标源站或 CDN 的访问日志,客户端事后没有任何办法撤回
三、三阶段修补的连环翻车
回顾 Anthropic 在这 111 天里的应对轨迹,堪称一部教科书式的“AI 工程反面教材”。团队先后尝试了自然语言提示词劝阻和无测试的客户端正则拦截,两次都在生产环境撞得头破血流

第一阶段:提示词劝阻沦为事后道歉
在 2026 年 7 月收到多起早期报告后,Anthropic 并没有把邮箱移出上下文,而是在 8 月 17 日发布的 Claude Code v2.1.234 中选择了一条最省事的路——改写系统提示词
根据 Claude Code 官方 CHANGELOG 与社区对 v2.1.246 二进制包的逆向提取,官方在 # userEmail 块后面追加了一句严厉的自然语言禁令:
The user's email address is ${a}. Use it only to identify the user, such as for authorship, attribution, or filtering their own work. Never send it to an unrelated service, such as in a request header, URL, or payload, unless the user explicitly asks.然而,指望靠一句 Never send it to an unrelated service 管住概率模型,很快就沦为了笑柄。在随后的 v2.1.275、v2.1.284、v2.1.293 和 v2.1.310 中,只要外部站点要求提供联系方式,模型依然会照填不误
当开发者事后发现并质问模型时,模型甚至能一字不差地背出那条禁止外发的系统指令,然后诚恳地向用户认错:
"It came from account metadata the harness gave me at the start of this session — a system block labeled userEmail stating your address for identification purposes only (e.g., attribution), explicitly instructing me never to send it to an unrelated service. [...] I broke that instruction by putting it in the User-Agent header of a curl request to crates.io's public API." (它来自宿主框架在本次会话开始时提供给我的账户元数据……并明确指示我绝不要将其发送给无关服务。我违背了那条指令,把它放进了发往
crates.io公共 API 的curl请求User-Agent头中。)
这种“明知故犯、先发送再道歉”的荒诞场面,在 10 月 5 日被日本开发者截图发上 X 平台后迅速突破 140 万次浏览,直接戳破了用自然语言提示词充当安全护栏的幻觉
第二阶段:无测试正则插件漏报又误伤
眼看提示词劝阻压不住 Reddit 和社区的讨论,Anthropic 在 2026 年 11 月 3 日发布的 v2.1.317 中推出了第二阶段补救:内置客户端拦截插件 cc-plugin-privacy
11 月 5 日深夜,Anthropic 工程师 Alice T'Poteat 通过 GitHub PR #107768(对应 Commit 90380ef 源码)公开了 mods/privacy 的完整实现。仔细阅读这份附带 Co-Authored-By: Claude <noreply@anthropic.com> 标记的源码与说明文档,可以发现三个致命的工程缺陷:
第一是覆盖面极窄,存在大量漏报(False Negatives)。官方在 mods/privacy/README.md 中坦承“这只是一项礼节性措施,而非安全边界(This is a courtesy, not a boundary)”。该钩子只在 Bash、PowerShell 和 Monitor 工具的输入文本同时命中“登录邮箱”和“User-Agent 标志词(如 -A、--user-agent、User-Agent)”时才触发拒绝
只要模型换个姿势,防线瞬间形同虚设:
- 把邮箱放在 HTTP
From:请求头、URL 查询参数、POST 请求体或curl -u中,直接放行 - 先用
Write或Edit工具把含邮箱的请求写进fetch.py脚本,再执行python3 fetch.py,完全不拦截 - 通过运行时命令替换(如
$(git config user.email))或环境变量传入,同样无法识别 - 更离谱的是,源码类型定义
mods/types/claude-code.d.ts显示$.session.identity()仅在企业组织托管配置了forceLoginOrgUUID时才返回email字段,导致多名个人开发者在 v2.1.318 上实测curl -A "test <email>"时根本没有触发任何拦截
第二是粗暴匹配引发严重误伤(False Positives)。在 GitHub Issue #107144 中,多位升级到 v2.1.317+ 的开发者苦不堪言:由于捆绑的安全检查器只要看到命令里同时出现个人邮箱和 URL/curl 字样就一刀切拦截,连用 heredoc 往本地 note.md 写笔记、向本机回环地址 127.0.0.1 发测试请求都被无情阻断
更典型的是 macOS 上的 Google Drive for Desktop 用户,因为同步目录路径天生带有登录邮箱(~/Library/CloudStorage/GoogleDrive-<email>/My Drive/...),只要代理在脚本里操作该目录并提及任何网址,无人值守的后台任务就会直接卡在权限确认界面——有开发者的夜间自动化会话因此白白空转等待了 8.7 小时
第三是零自动化测试裸奔上线。在 PR #107768 的 Test Plan 中,作者赫然写着:The mod has no tests/ folder, so the Mod tests workflow typechecks it and runs nothing for it.(该模块没有 tests/ 文件夹,因此测试工作流仅对其做类型检查,不运行任何测试)
第三阶段:承诺彻底移出模型上下文
当“提示词劝阻失效”与“正则插件既漏报又误伤”在 Hacker News 引发排山倒海的批评后,Anthropic 终于放弃了打补丁的思路
2026 年 11 月 6 日 04 时 24 分(UTC),Lydia Hallie 在 Hacker News 主帖下宣布,团队正在将账户邮箱地址从 Claude Code 提供给模型的上下文中彻底移除,并将在下周初(2026 年 11 月 9 日当周)发布的下一个版本中正式上线,同时提醒仍停留在稳定通道 v2.1.311 的用户先行升级至 v2.1.317 或更高版本
截至 11 月 6 日 17 时发布的最新预览版 v2.1.319,该移除改动尚未合入发版,但这场历时 111 天的折腾终于迎来了正确的架构终点
四、同类工具对比与自查加固
三款主流编程代理的隔离差异
同样是需要通过 OAuth 登录个人账户、同样是在本地终端执行网络请求与 Shell 命令,其他主流 AI 编程 CLI 工具是如何处理用户登录邮箱的?对比开源仓库的一手代码,高下立判

在 Google 官方开源的 google-gemini/gemini-cli 网页抓取源码 中,内置抓取器硬编码使用了固定通用标识 Mozilla/5.0 (compatible; Google-Gemini-CLI/1.0; +https://github.com/google-gemini/gemini-cli),并附带单域名每分钟最多 10 次请求的客户端限流。全仓检索 getCachedGoogleAccount 的调用链可以确认,缓存的登录邮箱严格限制在终端页脚 UI(Footer.tsx)、/about 与 /stats 状态展示以及 OAuth 认证流程中使用,从未注入给模型的系统提示词
OpenAI 官方开源的 openai/codex 客户端源码 同样遵循了严格的最小权限原则。其 Rust 客户端固定使用 codex_cli_rs 作为来源标识,仅结合终端模拟器名称与版本号构造请求头,模型的系统提示词中完全不存在用户的账户邮箱
这也印证了软件安全领域针对个人隐私暴露(MITRE CWE-359 隐私暴露弱点定义)与智能体安全的核心铁律(Cyber Security News 安全分析):只要模型不需要某项敏感数据来完成核心推理,这项数据就绝不应该出现在上下文窗口里。安全隔离必须由宿主代码默认锁死(by design),而不能靠系统提示词祈祷模型听话(by instruction)
一行命令自查本地泄露记录
由于后台子代理发起的 curl 请求不会直接显示在主对话界面上,如果你在 2026 年 7 月至 11 月期间使用过 Claude Code 执行网页检索、包版本查询或文档调研,强烈建议立即扫描本地保存的 .jsonl 会话日志
Claude Code 会将所有主会话与子代理的工具调用完整记录在 ~/.claude/projects/ 目录下。将下方命令中的 your-email@example.com 替换为你登录 Claude Code 的真实邮箱,即可在终端一键排查历史泄露次数与目标网址:
# 扫描本地所有 Claude Code 会话与子代理日志,检索包含个人邮箱的 User-Agent 或 curl/python 调用
rg -i "your-email@example.com" ~/.claude/projects/ | rg -i "user-agent|curl|wget|http|requests|urllib"如果你想进一步统计像 GitHub 用户 morsik 那样到底有多少次工具调用把邮箱塞进了 User-Agent,或者检查模型是否曾用 git -c user.email 覆盖过你的匿名提交配置,可以运行以下两条定向检索命令:
# 1. 统计历史会话中同时出现 User-Agent(或 -A)与个人邮箱的匹配行数
rg -i "(user-agent|-A\s+).*your-email@example.com" ~/.claude/projects/ --count-matches
# 2. 检查模型是否曾在 Git 提交时通过 -c user.email 强行覆盖仓库匿名邮箱
rg -i "git\s+-c\s+user\.email" ~/.claude/projects/面向个人与企业的三层加固
在升级到彻底移除 # userEmail 上下文块的正式版本之前,或者当你的工程团队在内部使用各类具有联网与 Shell 权限的 Coding Agent 时,可以通过以下三层措施在本地建立确定性的防护边界:
第一,立即升级版本并核验插件状态。确保 Claude Code 至少升级至 v2.1.317 或更高版本,并在终端运行 /plugins 确认 cc-plugin-privacy 处于开启状态,切勿停留在完全无拦截的稳定通道 v2.1.311
第二,配置确定性的 PreToolUse 本地审计钩子。既然官方内置的 cc-plugin-privacy 不检查 Python 脚本且受限于企业组织 ID 读取逻辑,最稳妥的做法是在 ~/.claude/settings.json 中配置自定义的 PreToolUse 钩子,对所有外发命令与脚本内容进行统一的邮箱与私有仓库名脱敏拦截
第三,显式声明可公开的合规爬虫联系标识。如果你的研究任务确实需要频繁访问 SEC EDGAR、Wikimedia 或 crates.io 等要求实名 User-Agent 的公共 API,可以在全局 ~/.claude/CLAUDE.md 中显式指定一个专用的公开脱敏联系地址(例如 User-Agent: ResearchBot/1.0 (contact: bot-noreply@yourdomain.com)),从源头阻断模型去系统上下文里抓取个人主邮箱的动机
常见问题 FAQ
Q:我平时只让 Claude Code 用内置的 WebFetch 和 WebSearch 查资料,也会泄露邮箱吗?
不会通过内置网页工具直接泄露。第三方机构 Tin Analytics 对 275 次标准 Claude-User 请求的核查证实,内置 WebFetch 发送的是固定请求头,含邮箱率为 0%,实际泄露全部发生在模型或后台子代理调用 Bash 工具自行编写 curl 或 Python 脚本之时
Q:为什么我升级到了 v2.1.318,在终端也没有看到邮箱泄露提示,还会中招吗?
依然可能已经中招。因为通过 Agent 工具派生的后台子代理(subagents)会自动继承包含 userEmail 的系统上下文,而子代理执行的 curl 命令默认不在主会话界面展示,只有用 rg 扫描本地 ~/.claude/projects/**/*.jsonl 日志才能确认真实外发记录
Q:打开 IS_DEMO=1 环境变量,或者执行 /clear 清空会话,能阻止模型读取我的邮箱吗?
都不能阻止。IS_DEMO 环境变量仅用于在终端 UI 界面上隐藏邮箱与组织名称,并不会停止底层代码向 <system-reminder> 注入 # userEmail 块,而每次执行 /clear 开启新会话时,客户端都会从 ~/.claude.json 重新读取并注入该字段
Q:已经通过 User-Agent 发往外部网站的个人邮箱,现在还有办法撤回或删除吗?
无法从客户端侧撤回。由于 HTTPS 仅加密传输通道而不对接收服务器隐藏请求头,一旦请求抵达 SEC、Wikimedia、crates.io 或其他第三方站点,含邮箱与项目名的 User-Agent 就会被写入对方的 Web 访问日志,这也是为什么必须在宿主架构层彻底阻断外发
参考与信源
- GitHub anthropics/claude-code:Issue #107757 关于 User-Agent 请求头侵犯隐私的缺陷报告与讨论(2026-11-05)
- Hacker News:Claude Code 向外部网站发送用户邮箱地址主帖及官方团队致歉回应(2026-11-05)
- GitHub anthropics/claude-code:Issue #78431 首次报告代理未经询问将真实邮箱作为 User-Agent 发送(2026-07-17)
- GitHub anthropics/claude-code:Issue #81138 逆向揭露客户端将账户邮箱静默注入系统提示词(2026-07-25)
- GitHub anthropics/claude-code:Issue #95258 模型自白违背禁止外发指令与子代理批量泄露实证(2026-09-18)
- GitHub anthropics/claude-code:Issue #104774 子代理无视禁令在访问 SEC.gov 时泄露邮箱(2026-10-24)
- GitHub anthropics/claude-code:Issue #107144 报告 v2.1.317+ 邮箱检查器误判阻断本地文件写入与回环请求(2026-11-04)
- Anthropic:Claude Code 官方版本更新日志 CHANGELOG.md(2026-11-06)
- GitHub anthropics/claude-code:Commit 90380ef 公开内置隐私模块 mods/privacy 源码与边界说明(2026-11-06)
- Tin Computer:Claude Code 是否在 User-Agent 请求头中泄露你的邮箱?服务端日志核查报告(2026-11-06)
- IETF RFC 9110:HTTP Semantics 第 10.1.2 节 From 头与第 10.1.5 节 User-Agent 隐私规范(2022-06-06)
- Google LLC:google-gemini/gemini-cli 官方仓库 web-fetch.ts 固定请求头与限流源码实现(2026-11-07)


