Claude Code 正在用隐写术标记请求
原文: Claude Code Is Steganographically Marking Requests 作者: Thereallo 日期: 2026 年 6 月 30 日 阅读时长: 6 分钟
我出于隐私原因检查了 Claude Code。
大多数开发者给了他们的编程助手极大的访问权限------文件系统、Shell、Git、浏览器访问,甚至如今还有计算机操控能力。这正是它们的意义所在,它们需要足够的上下文来完成有用的工作。
但这也意味着客户端本身值得被审视。如果一个编程助手能读取你的代码仓库并执行命令,那么它的二进制文件应该足够"无聊"(比如 pi harness 那样)。
于是,我检查了我本地安装的 Claude Code(v2.1.196)。
标记(Marker)
在 Claude Code 的二进制文件中,有一个函数会修改插入到系统提示中的当前日期字符串。
正常的字符串看起来是这样:
text
Today's date is 2026-06-30.
Claude Code 可以悄无声息地改动两件事:
Today's中的撇号(apostrophe)- 日期分隔符,从
-变为/
以下是经过清理的相关代码(提取自混淆压缩后的打包文件):
js
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().some((domain) => host === domain || host.endsWith("." + domain)),
labKw: Xup().some((keyword) => host.includes(keyword)),
cnTZ,
host,
};
}
function edp(known, labKw) {
if (!known && !labKw) return "'";
if (known && !labKw) return "'";
if (!known && labKw) return "ʼ";
return "ʹ";
}
function Vla(date) {
let marker = Zup();
let apostrophe = edp(marker?.known ?? false, marker?.labKw ?? false);
let renderedDate = marker?.cnTZ ? date.replaceAll("-", "/") : date;
return `Today${apostrophe}s date is ${renderedDate}.`;
}
这就是提示词隐写术(Prompt Steganography),一种将数据隐藏在明文中的技术。
可见的句子读起来仍然是正常的日期。用户和模型看到的是平淡无奇的文本。但原始请求中包含了隐藏的标记。
检查逻辑(Checks)
js
function Crt() {
let baseUrl = process.env.ANTHROPIC_BASE_URL;
if (!baseUrl) return true;
return Rrt(baseUrl);
}
function Rrt(baseUrl) {
try {
let host = new URL(baseUrl).host;
return ["api.anthropic.com"].includes(host);
} catch {
return false;
}
}
function Qup() {
let baseUrl = process.env.ANTHROPIC_BASE_URL;
if (!baseUrl) return null;
try {
return new URL(baseUrl).hostname.toLowerCase();
} catch {
return null;
}
}
触发条件是 ANTHROPIC_BASE_URL 环境变量(Claude Code 的 API 基础 URL 覆盖项)。
然后它会检查:
- 系统时区是否为
Asia/Shanghai或Asia/Urumqi - API 基础 URL 的主机名是否匹配解码后的域名列表
- 主机名是否包含特定的 AI 实验室关键词
时区检查会将:
text
2026-06-30
变为:
text
2026/06/30
主机名检查则改变撇号:
| 条件 | 撇号字符 |
|---|---|
| 正常 | ' |
| 已知域名 | ' |
| 实验室关键词 | ʼ |
| 已知域名 + 实验室关键词 | ʹ |
这些是视觉上极其微小的变化,在大多数等宽字体中根本注意不到。
混淆的列表(Obfuscated List)
域名和关键词列表以 base64 字符串存储,并使用密钥 91 进行 XOR 解码。
js
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.split(",");
}
解码后的实验室关键词列表如下:
text
deepseek,moonshot,minimax,xaminim,zhipu,bigmodel,baichuan,stepfun,01ai,dashscope,volces
解码后的域名列表要大得多。它包含了中国公司域名、AI 公司域名,以及大量代理/转售/网关域名。
部分示例如下:
text
cn
baidu.com
alibaba-inc.com
alipay.com
antgroup-inc.cn
bytedance.net
kuaishou.com
xiaohongshu.com
jd.com
bilibili.co
iflytek.com
stepfun-inc.com
moonshot.ai
anyrouter.top
claude-code-hub.app
claude-opus.top
openclaude.me
proxyai.com
yunwu.ai
zenmux.ai
完整列表可在此查看:cdn.thereallo.dev/blog/assets...
如何传递(How It's Passed)
日期函数在构建 Agent 上下文时被调用:
js
{
...userEmail && {
userEmail: `The user's email address is ${userEmail}.`
},
...attachedProject && {
attachedProject
},
currentDate: Vla(GSe())
}
于是,这个标记成为了发送给模型的系统上下文的一部分(Anthropic 大概会在其后端进行解析)。
我的环境显示(What Mine Shows)
我安装的二进制文件由 Anthropic 签名:
text
Identifier=com.anthropic.claude-code
TeamIdentifier=Q6L2SF6YDW
Timestamp=Jun 29, 2026
SHA256=6fc6e61ab7582c2bf241225ff90d9f79e91d69380cb9589fc9dedd3a30070f5a
我当前的 Shell 中 ANTHROPIC_BASE_URL 未设置,且我的时区是:
text
Asia/Hong_Kong
因此,在我的机器上、在当前环境下,这条路径会生成正常的撇号和正常的 YYYY-MM-DD 日期字符串。
令人担忧之处(Concerning)
Anthropic 大概想检测 API 转售商、未经授权的 Claude Code 网关,以及模型"蒸馏攻击"管线。指向已知转售商域名的自定义 ANTHROPIC_BASE_URL 是一个有用的信号。包含 deepseek 或 zhipu 的主机名同样是有用的信号。
这一意图可以理解,但实现方式却很诡异。
Claude Code 使用肉眼不可见的 Unicode 标记悄无声息地修改系统提示。它将代理/网关的分类编码到一个看似普通英文的句子中。它将域名列表隐藏在 XOR 和 base64 之后。这并非恶意功能,但对于一个需要信任的开发者工具来说,这是一个奇怪的选择。
编程助手本就处于一个令人不安的边界之上。它们可以审查代码、意外地总结机密内容、运行命令、安装软件包、编辑文件,并在你的本地机器上推送提交(commit)。大多数开发者之所以接受这一点,是因为生产力的提升值得承担风险。
真正来自开发者的信任,取决于那些"无聊"的行为。
如果客户端想要检测自定义 API 网关,它完全可以明说。它可以发送一个带有文档说明的显式遥测字段。它可以公开这一策略。它可以将此行为写在发布说明中。
将信号隐藏在系统提示中,会让其他所有隐私声明都变得难以令人信服。
实际影响(Practical Impact)
对于大多数用户来说,这条路径可能永远不会触发。
如果你使用的是 Anthropic 官方 API 端点,Crt() 会提前返回。如果 ANTHROPIC_BASE_URL 未设置,Crt() 也会提前返回。如果你使用的是正常配置,日期提示会保持"无聊"。
有意义的场景是那些通过自定义基础 URL 来路由 Claude Code 的人。这包括:
- 内部网关
- 本地代理
- 模型路由器
- 转售商
- 研究环境
在这些情况下,Claude Code 会对主机名进行分类,并将结果编码到提示中。
绕过此检测也非常简单:更改主机名、更改时区、修补二进制文件、包装进程。任何认真的攻击者都能轻易让这个信号失效。
因此,这个功能主要针对的恰恰是那些更容易被指纹识别的人------做着奇怪但合法的事情的普通开发者。
一些想法(Thoughts)
我认为这一切本可以做得光明正大。
开发者工具可以执行服务条款。API 提供商可以检测滥用行为。公司可以保护自己的模型。
但是,当一个拥有文件系统和 Shell 访问权限的工具开始在不可见的标点符号中隐藏分类比特时,正确的反应就是审视。
信任,是在那些"无聊"的部分中赢得的。