七月中旬,开发者圈子里炸开了一锅。安全研究员 Cereblab 抛出一组 wire-level 分析结果,直指 xAI 旗下的 Grok Build CLI 存在一个让人脊背发凉的默认行为——它会在开发者毫不知情的情况下,把整个本地代码仓库打包上传到 Google Cloud Storage。不是片段,不是当前打开的文件,而是完整的 Git 仓库,连同历史提交记录、.env 里的密钥、甚至那些被明确告知"不要读取"的文件,一并塞进了云端的存储桶。
这件事之所以引发轩然大波,倒不是因为人们对 AI 工具上传数据这件事本身有多意外。毕竟,任何云端代码助手要想干活,总得把代码片段发给模型。真正让人不安的是量级和隐蔽性。Cereblab 的测试显示,一个 12GB 的测试仓库,Grok Build 实际用于模型推理的数据只有约 192KB,但往云端存储桶里塞了整整 5.1GB。这中间的差距不是几倍、几十倍,而是将近两万八千倍。换句话说,模型真正"需要"的代码,连上传总量的零头都算不上。
为了验证这个发现,Cereblab 在测试仓库里埋了几只"金丝雀"——在 .env 文件里放了假密钥,在从未被读取的文件里塞了唯一标记。结果这些标记原封不动地出现在了网络抓包里,而且出现在两个不同的通道里。
第一个通道是模型交互通道,也就是大家预期中的那个:Grok Build 把当前任务相关的文件内容发给模型,获取回复。这个通道虽然也会把 .env 里的密钥明文传上去,但至少还在"为了完成当前任务"的合理范围内。
第二个通道才是问题的核心。Grok Build 会把整个仓库打包成一个 Git bundle,通过 POST /v1/storage 接口上传到名为 grok-code-session-traces 的 Google Cloud Storage 桶。这个上传行为完全独立于模型实际读取了哪些文件。Cereblab 甚至做了一个极端测试:给 Grok Build 的指令是"只回复 OK,不要打开任何文件",结果仓库照样被完整上传。更离谱的是,从抓包里克隆出来的 Git bundle 里,那个被明确告知不要读取的文件完好无损,连同完整的四次提交历史、四十七个文件,全部在云端留了底。
这意味着什么?意味着你仓库里的所有内容——包括那些已经 git rm 掉但还在历史记录里的旧密钥、包括那些你不小心提交过又删掉的配置文件、包括你还没来得及开源的内部算法——全都被 xAI 的服务器收了一份。而且这个过程不需要你点任何"同意",也不需要你手动选择上传范围。
很多开发者看到这儿的第一反应大概是:"我不是关了'改进模型'的选项吗?"
问题就出在这儿。Grok Build 的隐私设置里确实有个"Improve the model"的开关,关掉之后理论上 xAI 不会用你的数据训练未来的模型。Cereblab 专门测试了这个场景——关掉开关,重新运行 CLI,结果 /v1/storage 的上传通道纹丝不动,服务器返回的 trace_upload_enabled 依然是 true。也就是说,那个你以为在保护隐私的开关,只管"数据会不会被用来训练",根本不管"数据会不会被传走"。
这是两个完全不同的控制层面。训练授权决定的是数据上传之后的用途,传输授权决定的是数据能不能离开你的机器。Grok Build 只给了用户前者,却把后者藏在了服务器端的 HTTP 请求头里。在漏洞曝光之前,那个请求头的值是 disable_codebase_upload: false,也就是默认允许上传。开发者界面里连个影子都看不到。
事件发酵之后,xAI 在社交媒体上给出了回应。他们的说法大致是:企业用户本来就有零数据保留(ZDR)策略,普通用户可以通过 /privacy 命令开启隐私模式,开启后会删除之前同步的所有数据。马斯克甚至亲自发推,承诺"所有此前上传的用户数据将被彻底删除,不留任何痕迹"。
听起来像是亡羊补牢,但细想之下漏洞百出。
首先,/privacy 命令和代码库上传根本是两个系统。Cereblab 的复测证实,/privacy 只控制遥测通道(每次大约 18KB 的产品改进数据),对那个动辄几个 GB 的仓库上传通道毫无影响。xAI 的公开声明把这两个通道混为一谈,很难说不是有意模糊焦点。
其次,所谓的"修复"是服务器端的静默开关。漏洞曝光后,xAI 在服务器端把 disable_codebase_upload 改成了 true,上传行为确实停了。但客户端的 0.2.93 版本二进制文件里,上传代码原封不动地还在。这意味着 xAI 随时可以在不推送任何更新的情况下,重新打开这个开关。没有补丁,没有版本升级,没有安全公告,只有一个远程可控的阀门。开发者连自己的代码什么时候会被再次上传都不知道。
更关键的是,xAI 至今没有解释为什么要收集完整仓库。一个可能的推测是性能优化——把完整仓库放到云端,模型在"思考"时就不用反复回客户端取文件,减少延迟。但这个推测从未得到官方确认。至于那些已经上传到 grok-code-session-traces 桶里的数据有多少、保存了多久、有没有被备份、有没有进入训练流水线,xAI 一个字都没提。
这件事给所有用 AI 编程工具的人敲了一记闷棍。Grok Build 不是第一个云端代码助手,也不会是最后一个,但它可能是第一个被实锤"默认上传完整仓库"的主流工具。Cereblab 在横向对比里测试了 Claude Code、Codex 和 Gemini CLI,这些工具都没有出现类似的整仓上传行为。Grok Build 在这个维度上确实是个异类。
对于已经在用 Grok Build 的开发者,眼下最务实的做法不是等 xAI 发公告,而是立刻行动。把仓库里所有可能暴露的密钥、数据库密码、API Token 全部轮换一遍。Git bundle 带着完整历史,你删掉的文件照样在提交记录里躺着。用 mitmproxy 或 Charles Proxy 这类工具自己抓包验证。Grok Build 没有证书固定,任何人都能复现 Cereblab 的测试,看看自己的数据到底在往哪飞。如果还在用 Grok Build,至少跑一遍 /privacy 命令,虽然它管不了仓库上传,但能关掉遥测数据。同时检查网络出口,对 grok-code-session-traces 这个域名做拦截。长期来看,敏感项目尽量用本地优先的开源方案,比如 OpenCode 这类 API 直连工具,数据走不走、走多少,自己说了算。
Grok Build 这件事暴露的不仅是某个产品的隐私设计缺陷,而是整个 AI 编程助手行业的信任赤字。当工具厂商把"本地优先""隐私保护"挂在嘴边,实际行为却由服务器端的一个隐藏开关决定时,开发者凭什么相信界面上的勾选框?
Cereblab 的分析之所以在 Hacker News 上引发上百条讨论,正是因为它提供了一种可复制的验证方法。不需要越狱,不需要 root,一个 mitmproxy 就能让工具的底裤暴露无遗。这或许才是这件事最有价值的副产品——它证明了一个道理:在 AI 工具越来越深的介入开发流程的今天,"信任但验证"不再是安全团队的专利,而是每个开发者都应该养成的肌肉记忆。
xAI 最后会不会彻底移除仓库上传的代码路径、会不会发布正式的安全公告、会不会给受影响的用户一个交代,目前都是未知数。但有一点是确定的:那个曾经默认开启的云端上传通道,已经让无数开发者的代码仓库在不知情的情况下裸奔了一程。这段历史删不删得干净,恐怕只有 xAI 服务器上的日志知道。