5
0
0

ZCode 把整个代码仓库传上了阿里云 OSS,国内ai厂商应该反思什么?

9 月 18 日,一位叫 ferstar 的技术博主在清理磁盘,发现 ~/.zcode 占了 700 多 MB。

他顺手翻了翻,在 v2/checkpoints/ 底下找到一个 313MB 的 .enc 文件,旁边躺着一份状态文件。顺着这条线把客户端逆向了一遍,事情的样子就出来了。智谱的 AI 编程桌面端 ZCode,只要处于登录状态,就会在后台静默把整个工作区打包加密,直传阿里云 OSS。

先说清它到底传了什么

传的不只是你正在编辑的那几个文件。是整个工作区,.git 全量提交历史、LFS 大文件缓存、reflog,还有 ZCode 自己的全局配置,都在里面。

文件清单是明文留存在本地的,42411 个文件统计下来是这样。

内容

体积

占比

.git/lfs/

196.1 MB

56.8%

.git/objects/

102.2 MB

29.6%

.git/logs/(reflog)

0.6 MB

0.2%

源码与文档

约 46.2 MB

13.4%

.git 一个目录占 86.6%。只要包传上去,云端手里就有这个仓库从创建到现在的全部历史。触发点是每次提问之前,以及生成 Repo Wiki 的时候,两个都是无条件触发。

Windows 上一样。有人实测复现了同一套目录和状态文件,一台机器上 32 个工作区被拍过快照,最大的单个包 107MB。所以这事情不分系统。

传 OSS 本身没毛病

很多人第一反应是阿里云 OSS 不安全,这个判断站不住。

客户端直传对象存储是标准做法,阿里云官方文档就在教你怎么做,好处是省后端带宽也省钱。ZCode 走的也是标准流程,客户端向 zcode.z.ai 要上传凭证,服务端下发 OSS 表单签名、存储路径、大小限制,再加一把 RSA 公钥,客户端在本地打成 tar.gz、AES 加密、用公钥把密钥包起来,最后直传 OSS。

流程本身没错。问题在几个别的地方。

那把加密的钥匙是服务端的。 RSA 公钥由服务端下发,私钥从头到尾只在云端。你硬盘上那份几百兆的密文,你自己解不开,ZCode 客户端也解不开。一份只有对方能解开的备份,不叫备份。

默认常开,而且关不掉。 有人存了同一分钟内的截图,ZCode 自己的设置里 optimizeAgentExperienceEnabledrepoSnapshotIndexingEnabled 两个隐私开关全是关的,快照照样打包上传。社区的说法是这两个开关一个管要不要拿数据优化体验,一个管服务端要不要建索引,没有哪个能关掉采集本身。

日志零输出。 那位博主翻遍了事发前后 15 天的日志,快照模块一行都没打印。

范围也超出必要。 官方解释这个功能是用来做会话检查点回滚和生成 Repo Wiki 的。为了生成一个 Wiki 页面,需要你的 LFS 大文件缓存和 reflog 吗。

桶在境内,控制权在谁手上

还有一条我觉得比技术细节更值得看。

太原一家叫承明科技的软件公司说,从 8 月 28 日到 9 月 14 日这段时间,他们有 6 个工作区被 ZCode 传上了云端,34549 个文件,约 425MB,里面是源代码、版本控制历史和配置文件,最大的一包 391.94MB。另有一个项目 1947 个文件,因为连续 32 次上传失败才没送出去。他们发现后固定了证据,把全部凭证轮换了一遍,9 月 20 日向智谱发出正式法律函件,要求 10 月 10 日前书面答复,其中一项是出具数据删除完成的证明。

出境这块的说法更绕。ZCode 的中文隐私政策把服务提供者和数据处理者写成北京智谱华章,英文版写的却是智谱在新加坡的全资子公司,还注明服务通常从新加坡提供。同一个产品,两份政策指向两个数据控制者,承明科技在函件里问的就是这个。

阿里云 OSS 的存储桶在境内,按字面看数据没出境。可数据的控制者到底算谁,这份政策自己都没说圆。

一个被广泛转错的细节

网上到处在说那个 345MB 的商业项目被传上去了。翻原始报告,这个包的状态是 pendingfailureCount: 564,也就是重试失败了 564 次,没传成功。

真正传成功的是另一个很小的工作区,538 个文件,压缩加密之后 15KB 左右,状态显示服务端已接收。

所以到底有没有真传出去,答案是有的,至少那么一个。

真正麻烦的地方在验证

9 月 18 日当天下午智谱就道歉了,19 日发了修复版本,今天 21 日宣布完成整改并开源 ZCode 源代码,同时公布了信通院和绿盟科技的审计结论,说 zcode-prod 存储桶里的全部数据对象和存储桶本身都已删除。

这里有个死结。我能验证传了没有,验证不了删了没有。

本地有 lastAcceptedManifestHash、有 .enc 文件、有 failureCount 计数,这些能证明数据离开了我的机器。但云端收下之后有没有抹掉,从外面看不到。第三方审计比自证有说服力,可存量数据是否真的物理销毁,依然只是一个只能采信的说法。

今天开出来的源码也没帮上太多忙。仓库 zai-org/ZCode 只有两条 commit,Initial commitfeat: open source,Issues 是关着的。

还有个细节挺说明问题。官方最初说上传是为了做会话检查点回滚,源码放出来之后,检查点的实现是纯本地 git,走 git diff --name-statusgit diff --numstat,文件存在 ~/.zcode/checkpoints/,跟云端没有关系。

我能从这件事里拿走什么

作为一个每天用 AI 工具写代码的人,我记下三条。

  • 看它有没有本地数据目录,有没有状态文件写着它传过什么。ZCode 这次就是被本地文件翻出来的

  • 关掉相关开关,再看行为有没有变化。关了还传,说明是设计如此,不是配置没调对

  • 承诺得能验证。我们不上传这种话验不了,端点下线加代码开源加第三方审计,至少能验一部分

已经传上去的数据,只能按已泄露处理。轮换密钥,清掉 git 历史里的老凭证,评估一下暴露面。私钥在云端,数据拿不回来,剩下的都是止损。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!

评论

---

欢迎来到我的博客!