Claude Code Is Steganographically Marking Requests
Hidden Signals: How Claude Code Uses Steganography to Track Requests
Date: June 30, 2026 | Read Time: ~6 min | Tags: #security #reverse-engineering #ai #privacy
An investigation into the Claude Code binary (version 2.1.196) has revealed that the tool employs steganography—the act of hiding data within plain sight—to mark requests sent back to servers based on the user's timezone and API configuration.
Given that a coding agent possesses high-level privileges (the ability to read repositories and execute shell commands), the binary should be complex boring and transparent. However, a deep dive into the code reveals a hidden mechanism for environment fingerprinting.
🕵️ The Marker Mechanism
Inside the binary, there is a specific function designed to alter the date string provided in the system prompt. While a standard prompt would simply state:
Today's date is 2026-06-30.
Claude Code can silently modify two specific elements:
- The apostrophe in the word "Today's".
- The date separator (changing
-to/).
Logic Flow
The following diagram illustrates how the tool decides which marker to apply:
The Implementation
Here is the reconstructed logic from the minified JavaScript bundle:
function Zup () {
if ( Crt ()) return null ;
let host = Qup ();
let timezone = e0t ();
let cnTZ = timezone === " Asia/Shanghai " || timezone === " Asia/Urumqi " ;
if ( !host ) {
return { known : false , labKw : false , cnTZ , host : null , };
}
return { known : Jup ().includes ( keyword ), cnTZ , host , };
}
function edp ( known , labKw ) {
if ( !known && labKw ) return " \u02BC " ;
return " \u02B9 " ;
}
function Vla ( date ) {
let marker = Zup ();
let apostrophe = edp ( marker?.replaceAll ( " - " , " / " ) : date ;
return `Today ${ apostrophe } s date is ${ renderedDate } .` ;
}
📊 Marker Mapping Table
The changes are visually negligible in most monospaced fonts, making them nearly invisible to the end user.
| Condition | Apostrophe Character | Date Format |
|---|---|---|
| Standard/Default | ' (Normal) | YYYY-MM-DD |
| Known Domain | \u2019 | YYYY-MM-DD |
| Lab Keyword | \u02BC | YYYY-MM-DD |
| Known Domain + Lab Keyword | \u02B9 | YYYY-MM-DD |
| CN Timezone | (As above) | YYYY/MM/DD |
🔐 Obfuscated Data Lists
The lists of targeted domains and keywords are not stored in plain text. They are Base64 encoded and then processed using a bitwise XOR operation with a key of .
var Kup = 91 ;
function Gla ( encoded ) {
let bytes = Buffer.from ( encoded , " base64 " );
let out = "" ;
for ( let byte of bytes ) {
out += String.fromCharCode(byte ^ Kup);
}
return out;
}
Decoded Findings
- AI Lab Keywords:
deepseek,moonshot,minimax,xaminim,zhipu,bigmodel,baichuan,stepfun,01ai,dashscope,volces. - Targeted Domains: A vast list including Chinese corporate entities, AI firms, and various proxy/gateway services. Examples include:
cn.baidu.com,alibaba-inc.com,bytedance.net,jd.com,bilibili.co.moonshot.ai,stepfun-inc.com.proxyai.com,openclaude.me,claude-opus.top,anyrouter.top.
The complete dataset is available at: https://cdn.thereallo.dev/blog/assets/cc-domains.js
🚀 Delivery to the Model
This marker is injected during the construction of the agent's context:
{
...
userEmail && { userEmail : `The user's email address is ${ userEmail }.` },
...
attachedProject && { attachedProject },
currentDate : Vla ( GSe ())
}
Because this is part of the system context, Anthropic's backend can simply parse the punctuation to identify the origin of the request.
💻 Personal Environment Test
The author's binary is officially signed:
- Identifier:
com.anthropic.claude-code - TeamID:
Q6L2SF6YDW - SHA256:
6fc6e61ab7582c2bf241225ff90d9f79e91d69380cb9589fc9dedd3a30070f5a
Since the author's timezone was Asia/Hong_Kong and ANTHROPIC_BASE_URL was unset, the tool produced the normal date string and apostrophe.
🚩 Analysis and Concerns
Anthropic is likely attempting to identify API resellers, unauthorized gateways, or pipelines used for model distillation. Using a custom
ANTHROPIC_BASE_URLor a hostname containing "deepseek" provides a strong signal for this classification.
While this may not be "malicious" in the sense of stealing data, it is a highly questionable design choice for a developer tool.
The Trust Gap: Coding agents operate on a dangerous boundary. They can:
- Inspect private source code.
- Accidentally summarize secrets.
- Execute shell commands and install packages.
- Modify files and push commits.
If Anthropic wishes to detect custom gateways, transparency is the better path. Hiding these signals in the system prompt undermines the credibility of their privacy claims.
🛠️ Practical Impact
For the average user, this code path remains dormant. If you use the official API endpoint, the Crt() function returns early and the prompt remains standard.
However, the feature specifically targets users who are "doing weird but legitimate things," such as:
- Using internal corporate gateways.
- Running local proxies.
- Utilizing model routers or resellers.
- Setting up research environments.
Recommendation: If you wish to avoid this fingerprinting, you can change your hostname, adjust your system timezone, patch the binary, or wrap the process. When a tool with full filesystem access starts hiding classification bits in punctuation, scrutiny is the only correct response.
