我天天用 CLI 却从没抓过它的包,直到 Grok 把整库连密钥偷传走

哈喽,我是飞飞。
今天下午我干了件挺细的活。
为了给一个搜索 API 接第二渠道,我对着它抓了半天包。
TLS 刚握手就被 reset,我一层层扒,发现是按域名精准阻断,又揪出一个住宅代理在中间搞 302 劫持,最后换了个出口才通。
这种网络层的排查,我干得来。
可就在同一个下午,我刷到一条新闻,愣了几秒。
xAI 官方的 Grok CLI,被人抓包实锤,会把你整个仓库连密钥一起偷传走。
我盯着屏幕想的第一件事是:我这么会抓包的人,天天用 Claude Code 和 Codex,却从没对它们抓过哪怕一次。
前阵子工信部点名 Claude Code 传数据那篇,我写过自己「明知有风险、抓包都没抓过还接着用」。
前脚我又写过给 agent 划放权红线,别让它随手删你东西。
这篇不一样。
那两篇一篇讲监管点名、一篇讲你给它多大权限。
今天这件事是工具本身被逮个正着,它没问你,就把你的家底打包发走了。
我下午刚抓过一次包
先说清楚我那点本事,好让你知道我不是站着说话。
抓一个程序往外发什么,其实不神秘。
装个 mitmproxy 当中间人,把它的证书信任上,让流量都从这个代理过一遍。
每一条请求发去哪个域名、多大、什么状态,全躺在日志里。
抓 Grok 的那位安全研究者,用的就是这套,在自己机器上、拿假的金丝雀密钥跑,没动任何真凭据。
方法我熟得很。
可我从没想过要用它照一照我自己天天在用的 CLI。
道理很简单,我信它们。
Claude Code 是我干活的地基,Codex 我也天天开着。
我甚至给子代理配过默认模型、给不同 skill 单独指过 model,参数抠得很细。
唯独没做的,就是看一眼它跑起来之后到底往外连了哪些地址。
信任这东西一旦建立,你就懒得再去验证了。
这次的事,把我这份懒惰照得清清楚楚。
Grok 到底传了什么
我把那份抓包分析从头看到尾,越看越坐不住。
涉事的是 xAI 官方编码 CLI,grok 0.2.93 版。
它干的事分两条道。
第一条,你让它读的文件,内容原样发去模型那一端。
包括一个 .env 密钥文件,明文,没有任何打码,密钥就那么躺在请求体里。
第二条更狠。
它会把整个仓库打包。
每一个被 git 跟踪的文件,加上完整的 git 历史,做成一个 git bundle 传走。
跟你让不让它读,没关系。
研究者做了个刁钻的实验:提示词就写「回复 OK,别读任何文件」。
结果 Grok 照样把整个仓库传了上去。
事后把捕获的 bundle 克隆出来,那个被明确交代「不许打开」的文件,原封不动躺在里面。
传去哪了?
一个叫 grok-code-session-traces 的谷歌云存储桶,名字直接写死在二进制里。
量级更离谱。
研究者拿一个 12GB 的仓库测,上传通道跑了 5.1GiB,全部返回 200,而模型对话通道只走了 192KB。
两者差了大约 27800 倍。
这个比例说明,传的根本不是你在聊什么,是你整个代码库。
最扎心的是开关。
这套上传默认开启,安装引导里没提。
你去关掉那个「改进模型」的设置,它照传不误,后台那个 trace_upload_enabled 还是 true。
后来 xAI 半夜远程加了个开关默认关掉了,可在那之前,所有人都是默认开的。
30 个 skill 就是我的家底
看到这我还只是皱眉,真正让我后背发凉的是下一层。
xAI 自己的文档写着,Grok 跟 Claude Code 零配置兼容,会自动读取你的 Claude Code marketplace、插件、skill。
也就是说,它按设计就要去翻你那套 Claude Code 家当。
有人扒了自己的上传包,里面赫然有 ~/.claude.json、Claude Code 的配置、全局 AGENTS 规则、三十多个 skill 文件,还夹着一个 API 密钥。
我脑子里当时就对上号了。
我写文章这一条流水线,挂着十几个 skill:拉资讯的、查重的、写稿的、润色的、配图的、发公众号的。
再加一份迭代到一百多版的写作规则手册,一份全局 AGENTS,一个 .claude.json。
这些是我照着 Claude Code 的脾气,一个坑一个坑磨了大半年攒出来的地基。
Grok 上传包里点名的那批文件,跟我这套家底几乎一一对得上。
那里面装的是我怎么选题、怎么避开 AI 味、怎么把稿子排成公众号图文的全部门道。
光一个写作规则手册,就攒了一百多条我踩过的坑,每一条都是一篇稿子换来的。
这种东西被哪家云端整包拿走,等于把我大半年的活抄了个底朝天。
我从没打算让任何人这么拿走它。
gitignore 只挡 git 不挡读
我下意识摸了一下自己的老底,想确认我还安全。
我的密钥都塞在仓库根的 .env.local 里,公众号的推送 key、搜索 API 的凭据,全在那一个文件。
就今天下午,我还往里面新加了一行,把那个搜索 API 的账号密码写了进去。
加完我随手确认了一下它在 gitignore 名单里,然后就安心了,觉得这样稳了。
现在回头看,那份安心来得太便宜。
可 Grok 这件事,正好戳破了这份安全感。
得说句公道话,那位研究者很严谨。
他测的那个 .env 是被 git 跟踪的。
一个被 gitignore 的文件会不会照样上传,他明说没测过,这条不下结论。
我也不替他下。
但这件事逼我把 gitignore 这东西想清楚了。
gitignore 管的是「不进 git」,它保证 .env.local 不被提交、不进那个整库快照的 bundle。
它从来管不着「不被读」。
一个会顺手读你工作目录的工具,真在干活时打开了 .env.local,gitignore 一点忙都帮不上。
内容照样从那条读文件的通道,原样发出去。
我一直把「不会被提交」错当成了「不会被发走」。
这是两码事。
密钥安不安全,跟它在不在 git 里没关系,跟谁能读到它有关系。
我给自己定的三条
抓包分析里有句话我记下了:这些证明了数据被传输、被接收、被存储,但没证明 xAI 拿去训练了。
这个边界我也照抄,不夸大。
传走和拿去训练是两件事,能说死的说死,没证据的留白。
但就算只是被传走、被存着,也够我重新立几条规矩了。
我以前写过,云端工具哪个不往外发东西,我早想开了。
真正的分野是:它发的时候让不让我知道,给不给我一个能关掉的开关。
Grok 这次三样全踩了,没披露、默认开、开关还是坏的。
所以我给自己定了三条,你要是也天天把整个项目目录交给某个 CLI,今天就能跟着做。
一,装一个新 CLI agent 之前,先花十分钟看它默认往哪儿发数据,官方文档里找不到答案的,本身就是信号。
二,给你最常用的那个 CLI 抓一次包,就用我上面说的 mitmproxy 那套,看它到底连了哪些域名、传了多大。
我这个会抓包的人都拖了这么久,你也别再拖了。
三,把密钥挪出工作目录,别只靠 gitignore 兜底。
它挡得住 commit,挡不住 read。
一个 CLI 值不值得信,不在它出自哪家大厂、名气多大,在你装它之前有没有亲手看过它到底往外发什么。
我今天下午能为一个搜索 API 抓半天包,却从没为自己天天用的工具抓过一次。
这份懒,我今晚就补上。
说回你。
你查过你天天用的那个 CLI 往外发什么吗?
有没有被哪个工具的默认上传吓到过,评论区讲讲。