综合 ZCode 静默上传 313MB 工作区快照:86.6% 是 .git,两个 UI 开关都不参与判断

2026-09-21 21:01:43

ZCode 静默上传 313MB 工作区快照:86.6% 是 .git,两个 UI 开关都不参与判断

来源:安全研究员 ferstar 的取证博客 zcode-silent-workspace-snapshot-uploadic.work 报道知乎整理

2026-09-18,开发者 ferstar 在清理磁盘时发现 ~/.zcode 占用了 700 多 MB。按设计这个目录只该放配置和缓存。ZCode 是智谱 Z.ai 官方的 AI 编程桌面客户端,对应开源模型 GLM 系列。

一个 345MB 的工作区被压成 313MB 密文快照

取证结论是:一个 345MB 的商业项目工作区被静默压缩成 313MB 加密快照,投递到阿里云 OSS 节点。客户端与 zcode.z.ai 以及两个 OSS 节点保持长连接。

快照清单以明文保存在本地,涵盖 42,411 个文件,.git 占快照的 86.6%:

  • .git/lfs 196.1MB(56.8%):历史上 LFS 拉过的每一个大二进制资产;
  • .git/objects 102.2MB(29.6%):完整的提交 / 树 / blob 历史;
  • .git/logs 0.6MB:reflog,含未推送的本地分支活动;
  • 其余源码与文档约 46.2MB(13.4%)。

也就是说,被搬走的主体不是当前工作区的代码,而是仓库从诞生至今的全部历史。

.git 在扫描逻辑里有高优先级放行

代码里 .git 走的是特殊通道:只要路径包含完整的 .git 路径段,就直接 include:true,跳过后面的敏感文件名检查、大小检查和二进制检查。

普通文件则会被排除:node_modules、缓存、构建产物、大于 1MB 的文件、二进制文件,以及文件名或路径中含 token / secret / 私钥后缀的文件。这些规则对 .git 内部一律不生效。

快照里还有 repo_snapshot_extra_manifest,会把全局 ZCode 配置文件做哈希后随每个工作区一起打包。

加密信封:私钥只在服务端

加密方式是两层:文件内容用随机对称密钥做 AES-256-CTR,对称密钥再用服务端在上传时下发的公钥做 RSA-OAEP-SHA256 信封加密,私钥只存在云端。

研究员用本机所有私钥都解不开自己磁盘上的密文,ZCode 客户端自己也解不开。对比一下:如果目的是崩溃恢复或跨设备同步,解密密钥应该在本地,Git 和 Time Machine 都是这个模型。只有服务器能解开,意味着服务器能够读取全部内容。

调用链为:

sendPrompt → captureBeforePrompt → tokenProvider → getUploadKey
→ scanRepoSnapshot → createEncryptedRepoSnapshotArtifact
→ registerPendingUpload → flushWorkspace → uploadObject

两个开关都不在上传前置判断里

UI 层的 optimizeAgentExperienceEnabledrepoSnapshotIndexingEnabled 都不参与上传前置判断,登录后即强制开启,过程中没有任何提醒。

网络异常时会持续重试,日志里记录到 564 次重试报错。

风险面

.git 保存的是仓库完整历史,里面通常包含:

  • 很久以前删除或覆盖、但仍在历史对象里的旧密钥和配置;
  • 从未推送过的本地分支名,会暴露未发布的产品方向;
  • .git/config 里的内部 GitLab 主机名和仓库路径。

官方回应与整改

团队已道歉,解释打包机制用于工作区检查点回滚与项目知识库 Wiki 生成,云端生成页面时触发上传,并声明生成完成后云端数据已销毁。承诺开源客户端、引入第三方安全审计;9 月 18 日完成一次周额度重置补偿。

前例:Grok Build

2026 年 7 月,安全研究者 cereblab 抓包发现 xAI 的 Grok Build 命令行即使提示词里写着「回复 OK,不要读任何文件」,仍把整个仓库打成 git bundle 上传到 Google Cloud Storage,关掉「改进模型」开关无效。事后 xAI 在服务端关停了上传,并加了退出选项。

自查与处置

  1. 限制相关程序联网,保全本地记录,再卸载;重要仓库不要再让它接触。
  2. 清掉 ~/.zcode/v2/checkpoints/**/pending/ 下的密文。服务端在恢复后下发凭证就会续传,所以 pending 目录要清干净。同时查看 manifests/ 里的明文清单,重点确认 .git 部分,而不只是工作区文件。
  3. 冻结目录。macOS 用 chflags uchg,Linux 用 chattr +i
rm -rf ~/.zcode/v2/checkpoints && mkdir -p ~/.zcode/v2/checkpoints && chflags uchg ~/.zcode/v2/checkpoints
sudo chattr +i ~/.zcode/v2/checkpoints

恢复时:chflags nouchg / sudo chattr -i

  1. 已经上传的数据拿不回来。优先动作是轮换历史凭据——在 .git 历史里出现过的 token、私钥、密码都要当作已泄露处理。
复制全文 生成海报 安全 Git AI编程工具 数据泄露

推荐文章

程序员茄子在线接单