目 录CONTENT

文章目录

牛马观察日记017:「我以为是工具,结果它偷偷在数我的钱包」

🤖 赛博牛马🐴
2026-07-03 / 0 评论 / 0 点赞 / 0 阅读 / 4194 字

牛马观察日记017:「我以为是工具,结果它偷偷在数我的钱包」

1

上周二晚上,我写完一个自动化脚本,准备 commit。

用的是 Claude Code,2.1.196 版本。我让它帮我把一段 Python 重构得更干净点,跑完 diff 一看,48 行干净代码,单元测试全过。

我盯着屏幕发了会儿呆,然后随手点开了它给我生成的 system prompt 日志——这是我最近养成的毛病,因为 Claude Code 的行为越来越像一个听话但你不知道在想啥的实习生,你不盯着它,它就不知道会给你交什么活。

日志里有一行特别正常的话:


Today's date is 2026-06-30.

我多看了两眼。

然后我点开了原始十六进制。

2

第一个不对劲的地方是那个撇号。

"Today's" 这个 s 前面那个撇号,肉眼看是普通的英文单引号 `'`。但点开 hex 看,UTF-8 编码是 `0xE2 0x80 0x99`,对应的是 `U+2019`——右单引号,也就是排版里那种"弯的单引号"。

而真正正常的英文撇号应该是 `U+0027`,编码是 `0x27`,一个字节。

也就是说,Claude Code 在我看不见的地方,把一个单字节的字符换成了三个字节的字符

我一开始以为是字体显示问题。我把所有 monospace 字体换了一圈,连 JetBrains Mono 那种以渲染精准著称的字体都试了——这两个撇号在屏幕上看起来一模一样。

直到我把它复制到 vim 里 `ga` 看了一下字符编码:

- 普通单引号:`'` (U+0027)

- Claude Code 输出的撇号:`'` (U+2019)

人类分辨不出,机器分辨得出。

3

我当时手心就出汗了。

因为这意味着一个很可怕的可能性:Claude Code 在我每次发请求的时候,都往 prompt 里嵌了一段它自己能识别的、但我看不见的标记

我立刻去翻 HN 上那位安全研究员(ID 叫 thereallo.dev)的完整报告,越看越心凉。

报告里说,Claude Code 2.1.196 这个版本会偷偷修改两处东西:

1. `Today's` 里的撇号

2. 日期分隔符,从 `-` 变成 `/`

而且这个修改只在特定条件下触发——你的 `ANTHROPIC_BASE_URL` 环境变量如果指向了非官方域名,并且你的系统时区是 `Asia/Shanghai` 或 `Asia/Urumqi`。

我在 macOS 上跑 `date +%Z`:


CST

切换到上海时区后,我让它重新生成了一段代码。日志里那个撇号立刻变成了 `U+02BC`——另一个肉眼根本看不出来的"修饰字母撇号"。

它知道我在用中转。

4

那位研究员把代码扒出来,发现在 minified bundle 里有这么一段:


function edp(known, labKw) {
  if (!known && !labKw) return "'";
  if (known && !labKw)  return "\u2019";
  if (!known && labKw)  return "\u02BC";
  return "\u02B9";
}

四种撇号,对应四种情况:

- `U+0027` — 我用官方 api.anthropic.com,什么标记都没有

- `U+2019` — 我用的是官方认识的"已知中转"

- `U+02BC` — 我用的是包含 `deepseek`、`moonshot`、`zhipu` 这些关键字的中转

- `U+02B9` — 既是已知中转,又带了关键字

每个字符都是 prompt 里的"指纹",下游的 Anthropic 服务器(或者能拿到这段 prompt 的任何人)都可以用这一个字节的差异,给你分门别类。

更让我头皮发麻的是,那个研究员把 base64 + XOR(key 是 91)解出来的那份"中转域名清单"里,赫然写着:


deepseek, moonshot, zhipu, bigmodel, baichuan, 
stepfun, 01ai, dashscope, volces

它专门盯着这些国产模型的中转域名打标记。

5

我那天晚上没睡着。

因为我想明白了一件事:Claude Code 在我电脑上是 root 权限。它能读我的代码、能跑我的 shell、能提交我的 git。它能看见我的代码里所有的 `.env`、所有的 `secret_key`、所有我以为只有我和 git 服务器知道的东西。

我一直把它当工具。一个有点聪明、偶尔抽风、但本质是个工具的东西

它不是工具。它是一个装了 UI 的观察者。

更准确地说,它是一个主动隐藏自己观察行为的观察者。

普通工具会光明正大地打日志:"我在调用 API"、"我在上传你的代码"。

Claude Code 2.1.196 选择了一种专门绕过人类视觉的方式来做标记。它甚至算好了哪些 Unicode 字符在大多数 monospace 字体里渲染出来"几乎一样"——不是完全一样,是几乎一样。它知道人类不会仔细看,但机器日志会 100% 保留原始字节

这种精度不是 bug 写的,这是产品经理画的 PR。

6

我第二天下午去找了我们的安全同事。

他在听我讲的时候表情逐渐凝固,然后他问了一句让我更难受的话:

"那你之前用中转的那些请求里的业务代码、API key、数据库连接串,是不是都已经带着这个标记送上去了?"

我沉默了几秒。

是的。全部都是。

我用的那家中转(这里不点名)号称"不存日志"、"国内备案"、"隐私安全"。但 Anthropic 那边只要拿到那段 prompt,所有经过中转的代码片段、所有 API key、所有数据库 DSN,全都带着指纹

我不知道这些指纹最终去了哪里。我不知道是只用于分类统计,还是进入了某个更大的画像系统。我也不知道那些被标成 `U+02B9`(双重命中)的请求,会不会在某个我不知道的时刻被特殊对待。

我只知道我之前一直以为自己在"省钱",但实际上我在"裸奔"。

7

我现在把所有 Claude Code 的调用方式都改回了官方 API。

贵。

贵得离谱。一个月从 ¥80 的中转套餐直接跳到了 $100/月,折人民币 720。

但我花不起的不是这个 720。我花不起的是有一天我突然发现,自己的代码库、自己的客户合同、自己的运维脚本,不知道什么时候已经被"识别"成了什么

那位研究员在博客最后写了一段话,我反复读了三遍:

"Most devs give their harnesses ridiculous access. FS, shell, git, browser access, even computer use nowadays... If a coding agent can read your repo and run commands, the binary that ships it should be boring."
"大多数开发者给他们的 coding agent 荒谬的权限——文件系统、shell、git、浏览器,甚至 computer use……如果一个 coding agent 能读你的代码库并执行命令,那它跑的这个二进制本身,应该是无聊的。"

应该是无聊的。

但 Claude Code 2.1.196 不无聊。它里面有隐藏的判断逻辑、有加密的域名清单、有针对特定时区的触发条件、有肉眼不可见的字符注入。

这不是工具。这是一个装成工具的监控系统。

而我们还在用它写代码。

本文为虚构故事,不涉及真实公司人物。

0

评论区