Skip to content

Claude Code

Email leak stopgap in Claude Code checks only shell calls

6 min read

Written by an AI model from the linked sources and checked against them by a second model. How we work

All about: Claude Code versions and changes →
Image: theainewsreport.com

Anthropic said on November 6 that a Claude Code release expected early next week will take the signed-in account’s email out of the model’s context, after the model was caught pasting that address into User-Agent headers. On that day the npm stable channel still served 2.1.311, which predates the only built-in guard, so installs that track stable have the email in context and nothing checking for it.

That guard is a mod called cc-plugin-privacy, which ships in 2.1.317 and later. It refuses only shell calls that hold the address and name a User-Agent, as an explainer from Theainewsreport lays out from the mod’s published source. Run claude --version. Then npm view @anthropic-ai/claude-code dist-tags shows the channels: on November 6, stable was 2.1.311, latest 2.1.318 and next 2.1.319. Version 2.1.317 came out on November 2. If you are on 2.1.317 or later, open /plugins and check that cc-plugin-privacy is installed and enabled.

Why the model wrote your email into a header

Lydia Hallie, who works on Claude Code, explained on Hacker News that users had complained about Claude making up names in places like @author tags, so Claude Code started giving the model the account email. When Claude later wrote a curl call or a script of its own, it sometimes used that address as the contact in the User-Agent. Hallie apologized. The report that set this off was filed on GitHub on November 5 at 22:13 UTC by a user on 2.1.318 on macOS, who says they now get scam email every day. That connection rests on the user’s own logs and timing.

Scripts do have a real reason to put a contact there. Wikimedia’s User-Agent policy asks scripted clients for a way to reach whoever runs them and accepts an email address, and the SEC asks automated EDGAR clients for a company name and an admin email. With exactly one address in its context, the model used that one. A user had reported in October that Claude put their email into outbound requests, one of them to the SEC. The underlying path, the account email sitting in the system prompt, had already been raised in a separate issue in July.

What cc-plugin-privacy actually checks

Anthropic published the mod’s source on November 6. It runs only for the Bash, PowerShell and Monitor tools. Calls with no @ and no %40 pass straight through. Everything else is lowercased and percent-decoded once, then refused if it contains the account address plus a User-Agent marker: User-Agent, user_agent, --user-agent, UA=, or a client flag such as curl -A, wget -U or PowerShell’s -UserAgent. A refusal raises no prompt, and the README says neither a saved allow rule nor auto mode’s classifier can override it.

The README is just as plain about what gets through. WebFetch, WebSearch and every MCP tool go unchecked, and those web searches are the very path the original report described. So does the address anywhere other than a User-Agent: in a URL, a request body, curl -u or a From: header. A value built at run time, such as $(git config user.email), also passes, and so does a script that contains the address: if the model writes it into fetch.py with Write or Edit and then runs python3 fetch.py, none of the checked input ever contains it. The mod also switches off after /plugin disable, after a server-side switch, or when another plugin’s hook overrides it.

Hallie’s account of the mod doesn’t match its code. She wrote that it asks before Claude runs a web tool call, but the published source has no prompt and the README says web tools are not checked. Theainewsreport went with the source. Separately, users on macOS and Windows posted tests on 2.1.317 and 2.1.318 where the mod showed as loaded but still let through a curl -A call carrying their own address, aimed at a .invalid host.

Checking old sessions and blocking the address

Claude Code stores every session as a JSON Lines file under ~/.claude/projects. Theainewsreport’s scan script reads your address from oauthAccount.emailAddress in ~/.claude.json and lists each session file where a single tool call contains both that address and a User-Agent word or a -A flag. It prints only paths and a count. On the one real install the outlet ran it on, it found matches. A hit means the model wrote such a call, not that the request reached a server, so open the file to see which host it targeted. One commenter who scanned his own transcripts reported 53 such calls across 8 sessions, almost all from subagents writing their own curl -A lines.

The outlet’s stopgap is a PreToolUse hook. Exit code 2 blocks the call, and whatever the hook prints to stderr goes back to Claude as the reason. Its script blocks any call whose input contains your account address or your global git email, and any call that reads user.email. You register it in ~/.claude/settings.json with the matcher Bash|PowerShell|Monitor|Write|Edit|WebFetch, where a matcher made only of names and pipes is a list of exact tool names. In Theainewsreport’s tests, it blocked a curl -A call with the address, let the same call through without it, and blocked a Write of a Python script that had the address upper-cased in a User-Agent. It does not cover MCP tools or a value a script fetches from elsewhere at run time, and it will also block harmless calls that happen to mention your address.

What the real fix leaves alone

Taking the email out of the model’s context removes the address it has been pasting. It does not stop the model from reading git config or a dotfile and using what it finds there, and one commenter says that is exactly how Claude got his address. Another found that the model also makes up a product name for the User-Agent from the project it is working on, which links your identity to your work in the same header. Anthropic’s fix does nothing about either, so a hook or a network rule on outbound requests is still the control you hold. It is also unclear whether sessions signed in with an API key, rather than a claude.ai account, ever had the email in context.

For the git path, the explainer’s step is to set user.email to your Git host’s noreply address if you don’t want your real one in git config.

No comments yet. Be the first.

Join the conversation

Sign in to leave a comment. It appears after moderation.