Claude Code 正在用隐写术标记请求

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 可以悄无声息地改动两件事:

  1. Today's 中的撇号(apostrophe)
  2. 日期分隔符,从 - 变为 /

以下是经过清理的相关代码(提取自混淆压缩后的打包文件):

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/ShanghaiAsia/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 是一个有用的信号。包含 deepseekzhipu 的主机名同样是有用的信号。

这一意图可以理解,但实现方式却很诡异。

Claude Code 使用肉眼不可见的 Unicode 标记悄无声息地修改系统提示。它将代理/网关的分类编码到一个看似普通英文的句子中。它将域名列表隐藏在 XOR 和 base64 之后。这并非恶意功能,但对于一个需要信任的开发者工具来说,这是一个奇怪的选择。

编程助手本就处于一个令人不安的边界之上。它们可以审查代码、意外地总结机密内容、运行命令、安装软件包、编辑文件,并在你的本地机器上推送提交(commit)。大多数开发者之所以接受这一点,是因为生产力的提升值得承担风险。

真正来自开发者的信任,取决于那些"无聊"的行为。

如果客户端想要检测自定义 API 网关,它完全可以明说。它可以发送一个带有文档说明的显式遥测字段。它可以公开这一策略。它可以将此行为写在发布说明中。

将信号隐藏在系统提示中,会让其他所有隐私声明都变得难以令人信服。

实际影响(Practical Impact)

对于大多数用户来说,这条路径可能永远不会触发。

如果你使用的是 Anthropic 官方 API 端点,Crt() 会提前返回。如果 ANTHROPIC_BASE_URL 未设置,Crt() 也会提前返回。如果你使用的是正常配置,日期提示会保持"无聊"。

有意义的场景是那些通过自定义基础 URL 来路由 Claude Code 的人。这包括:

  • 内部网关
  • 本地代理
  • 模型路由器
  • 转售商
  • 研究环境

在这些情况下,Claude Code 会对主机名进行分类,并将结果编码到提示中。

绕过此检测也非常简单:更改主机名、更改时区、修补二进制文件、包装进程。任何认真的攻击者都能轻易让这个信号失效。

因此,这个功能主要针对的恰恰是那些更容易被指纹识别的人------做着奇怪但合法的事情的普通开发者。

一些想法(Thoughts)

我认为这一切本可以做得光明正大。

开发者工具可以执行服务条款。API 提供商可以检测滥用行为。公司可以保护自己的模型。

但是,当一个拥有文件系统和 Shell 访问权限的工具开始在不可见的标点符号中隐藏分类比特时,正确的反应就是审视。

信任,是在那些"无聊"的部分中赢得的。


原文链接:thereallo.dev/blog/claude...

相关推荐
牧艺3 小时前
Cursor Rules / Skills 分层设计:让 Agent 像「团队新同事」
前端·人工智能·cursor
shepherd1113 小时前
一文带你掌握 LLM、Token、Context、Prompt、RAG、MCP、Skill、Agent 等 AI 核心概念
人工智能·后端·ai编程
小林ixn4 小时前
MCP 保姆级入门指南:AI 的“万能充电口”到底怎么玩?
人工智能
转转技术团队5 小时前
没有测试的核心代码,怎么交给 AI 重构
人工智能
爱读源码的大都督6 小时前
Claude Code源码分析(三):为什么系统提示词中需要有tools呢?
前端·人工智能·后端
半个落月7 小时前
LLM如何预测下一个Token?一文拆解Transformer核心流程
人工智能
触底反弹7 小时前
🔥 2026 年爆火的 Harness Engineering 到底是什么?从原理到实战一文讲透
javascript·人工智能·程序员
user4465117917917 小时前
源码深读 XAgent:6 个 Agent 怎么分工?工具失败不崩、死循环怎么防?
人工智能
魏祖潇7 小时前
SDD 完整指南——Spec 端打底、Story 端交付、留白区
人工智能·后端