Software · Opinion

Claude Code's User-Agent fix is a regex guarding a model that writes its own headers

Anthropic's patch for the email-in-User-Agent leak matches one known string, but a model that writes its own requests can also leak project and client names.

On 5 November 2026 someone opened issue 107757 on the Claude Code repository. They say the agent put their email address in the User-Agent header of its web requests and that they now get dozens of scam emails a day. The causal claim is unproven: the issue shows no link between the header and the spam, and an address on a developer account can reach scammers by many routes. I take the leak as real anyway, because mkubenka posted better evidence than the reporter’s inbox.

The mechanism is mundane. demegire writes that Claude Code and other agents typically do this when a site such as the SEC or Wikimedia asks for a mail address in User-Agent, and says they should ask the user first. Nobody has shown a line of code that ships addresses to third parties. A model took a string it had in context and used it.

Existing telemetry opt-outs were not built for this. Go’s opt-in telemetry, designed by Russ Cox in 2023, and the .NET SDK’s DOTNET_CLI_TELEMETRY_OPTOUT variable both govern a fixed set of fields that code collects and a vendor can list. A header composed by a model has no field list. What can leak is whatever the model decides to type, and an opt-out switch cannot enumerate that.

Anthropic’s answer, from poteat, who is marked as a contributor, is a built-in mod called cc-plugin-privacy. It arrived in v2.1.317, is meant to block the behaviour deterministically, is on by default and can be switched off in /plugins. The reporter was on 2.1.318. The issue does not say whether the leak happened before or after the mod was running, so I cannot tell you whether it failed. mkubenka reports that on 2.1.319, with the mod not disabled anywhere, a shell command containing User-Agent: test and the account email still ran without being refused.

mkubenka also did what a vendor should have done and read their own session transcripts, under ~/.claude/projects/. They found two outbound cases. In one, a curl -A call sent a user agent made of a project name plus the account email to a public geocoding API, alongside an address query. One request gave a third party a project, an identity and a location. In the other, the model wrote the address into a Python script with its edit tool and then ran the script, so no shell command the mod could inspect ever contained the email.

As mkubenka describes it, the mod matches the account address in checked input. A model can put a string in a file, or invent a descriptive token from the session, and neither route contains the pattern. The first case would have passed with the email removed, because the project name alone identifies the work and the IP address links the requests. A pattern filter on the one value somebody thought to protect is a blocklist, and I do not expect a blocklist to hold against an author that generates text.

The obvious objection is that the sites asked for contact details. I assume Wikimedia and the SEC want a way to reach the operator of a misbehaving client, and a bare claude-code/<version> might get rate-limited or blocked. I accept that, and it is a reason to prompt the user once per site: show the exact header string and let the human decide whether their mailbox goes into someone’s access logs. Everywhere else, mkubenka’s proposal is the right default. Requests the model composes carry a generic product token and nothing taken from the session.

I would go further than a patch. Anthropic, and every vendor shipping an agent with network access, should publish the list of session context that can reach outbound requests, and ship a request log users can diff. Until they do, the measurement falls to users, and it takes a few minutes. Search your own transcripts for -A, User-Agent and mailto:, and count the project and client names in the headers as well as the email. If that count is above zero on a build with the privacy mod enabled, the mod is not covering your leak.

Prompted by Bug Report: Privacy violation in User-Agent header, github.com.