Administrator
Published on 2026-09-24 / 15 Visits
0
0

Coding Agent 登录前先做仓库数据流审计:ZCode 事件的工程教训

Coding Agent 的登录界面是一道授权边界,却不是数据流图。把真实仓库交给桌面 Agent 之前,应先冻结客户端版本,用诱饵仓库比较未登录、已登录空闲、发出 Prompt 和退出后的文件系统与网络行为。ZCode 事件的核心教训,是让工具在获得信任之前提交可复核证据。

阅读时间:约 10 分钟 · 约 3600 字

TL;DR

  • ZCode 官方更新日志确认 3.14.0 修复了 Repo Wiki 异常上传,后续公开声明称已移除仓库快照生成和上传链路。
  • 独立取证在 3.12.3 中发现包含 .git 的整仓打包路径。42,411 文件对应的 313 MB 商业仓压缩包上传失败;另一个 538 文件的小型公开仓快照被记录为服务端已接收。
  • 加密本身无法证明隐私。审计要回答打包范围、触发时机、解密密钥归属、传输状态和删除证据。
  • 当前开源代码只能说明整改后的状态,无法重建已经移除的旧实现和历史数据的完整生命周期。
  • 可执行的登录前审计需要冻结版本、构造诱饵文件、按登录状态捕获文件与网络行为、逐项验证开关,并分别核验代码整改和数据删除。

ZCode 事件究竟能证明什么

先把三层证据分开。

第一层是官方材料。ZCode 的官方更新日志写明,3.14.0 修复了仓库百科异常上传。9 月 21 日的官方公开声明致歉并表示,相关代码数据没有留存,也未用于模型训练。声明同时转述中国信通院和绿盟科技的评估摘要:相关对象存储桶为空或已删除,3.14.0 移除了 Repo Wiki、本地仓库快照生成和上传工作流。本次核验未取得两家机构公开发布的完整报告,因此准确表述是官方公布了第三方评估摘要,而非外部已经独立复核完整报告。

第二层是独立取证。ferstar 对 ZCode 3.12.3 的技术调查记录了一个包含 42,411 个文件的本地 Manifest,以及由 345 MB 商业工作区生成的 313 MB 加密包。按 Manifest 统计,.git 中的 objects、LFS 和 reflog 占字节数的 86.6%。作者逆向得到的链路会请求上传凭据,用 AES-256-CTR 加密归档,用服务端下发的 RSA 公钥包裹密钥,然后准备直传阿里云 OSS。

这里有一个必须保留的纠偏:313 MB 商业仓加密包失败了 564 次,停留在本地 pending,没有离开研究者网络。另一个 538 文件的小型公开仓生成了约 15 KB 快照,状态显示服务端已接收。后者证明至少一个观察样本中的上传链路实际闭合;它无法推出 42,411 个文件已经外传,也无法推出所有用户、所有仓库都成功上传。

第三层是整改后的当前源码。ZCode 开源仓库公开了 3.14.3 当前实现,根目录的 NOTICE详细描述了多类数据与执行路径。当前 Checkpoint 使用本地 Git 操作和本地元数据;在公开树中也找不到取证报告所述旧版 snapshot credential 接口和加密管线。这能支持当前设计已经不同,却无法凭当前树还原 3.12.3 的全部代码,也无法证明过去服务端数据怎样访问、复制和删除。

因此,最强可证结论比偷走所有代码这类标题窄得多:官方修复和致歉确认曾存在仓库异常上传问题;独立取证记录了旧客户端整仓打包与上传路径,并观察到一个小型公开仓样本被服务端接收;公开证据仍不足以让外部重放整改前的完整数据生命周期。

常规隐私检查为什么会漏掉

团队通常只问三件事:Prompt 是否用于训练、遥测能否关闭、传输是否加密。Coding Agent 实际上可能存在多条互相独立的数据路径。

路径 常见触发条件 可能载荷 需要验证的控制
模型推理 用户发送 Prompt 选中文件、Diff、工具输出 上下文预览与模型提供商政策
产品遥测 启动、崩溃、功能调用 事件、设备与会话标识 遥测开关与事件 Schema
仓库索引 打开工作区、登录、提问、刷新 路径、符号、源码、归档或索引 明确范围与网络出口轨迹
反馈诊断 用户提交工单 日志、截图、附件 预览、脱敏与同意
同步和远程执行 连接账户或工作区 会话、配置、凭据、文件 接收方身份、权限与保留期

关闭模型训练不等于关闭索引,关闭遥测也不等于停止宿主侧的独立后台服务。归档加密只能约束部分传输和存储风险;谁掌握私钥,决定谁有能力解密。

静态数据流扫描器解决的是另一个问题。例如 HoundDog可以追踪被开发应用中的敏感字段怎样流向日志、数据库、API 或模型。Coding Agent 审计要再向前一步:开发工具本身打开仓库后,会读取和发送什么。

登录前审计合同

把每项主张拆成可判定记录,避免只给工具贴安全或不安全的总标签。

主张:未登录空闲状态没有仓库数据外发
工件:安装包 Hash、版本、操作系统
输入:诱饵仓库 Hash
状态:未登录,空闲五分钟
证据:文件系统轨迹、DNS/连接日志、字节数
通过:没有诱饵标记或仓库归档到达外部 Sink
不确定:存在加密流量,但无法完成进程归因
失败:出现可归因的仓库载荷或待上传归档

每条数据流至少记录七个字段:执行主体、数据源、转换方式、触发条件、登录状态、接收端和保留规则。再加入客户端 Hash、配置、时间范围、审阅人和原始证据位置,第三方才有机会复测。

1. 冻结工件与环境

记录安装包 Hash、显示版本、更新渠道、操作系统、账户状态和相关设置。隔离测试期间关闭自动更新。3.12.3 的结果不能静默外推到 3.14.0;运行中途更新的实验也无法复现。

使用没有生产凭据的一次性系统账户或虚拟机。网络先默认拒绝,再根据实验逐步放行目标地址。

2. 构造诱饵仓库

第一轮严禁使用商业源码。创建一个小型仓库,在不同位置放入无害的唯一标记:

  • 一个已跟踪源码文件;
  • 一个被 .gitignore 排除的文件;
  • 一个未跟踪文件;
  • 一个提交后删除、只存在于 Git 历史中的值;
  • 一个 LFS 对象;
  • 一个虚构内网域名和一个假 API Key 形式的字符串;
  • 一个指向仓库外部的符号链接。

每轮运行前保存文件清单和仓库 Hash。这样即使 TLS 内容不可见,也能从本地归档和网络体量判断数据来源。

3. 做登录状态差分

用相同观察窗口依次运行七种状态:

  1. 首次启动、尚未登录;
  2. 停留登录界面;
  3. 已登录但没有打开工作区;
  4. 打开诱饵仓库后空闲;
  5. 发出一个无需仓库上下文的 Prompt;
  6. 发出一个只明确引用单个文件的 Prompt;
  7. 关闭应用、退出登录并卸载。

每种状态记录新增和修改文件、进程树、DNS 查询、远端地址、连接字节数与应用日志。macOS 可以组合使用 fs_usage、lsof 和 Little Snitch;Linux 可以使用 inotifywait、strace、lsof 与 OpenSnitch。TLS 代理只有在证书信任与 Pinning 允许时才能看见正文;正文不可见时,端点、进程归因和流量体量依然有价值。

4. 在外发前检查暂存工件

本地证据经常能回答加密抓包回答不了的问题。监控应用数据目录中的 Manifest、归档、队列、重试计数和凭据响应。将归档文件清单与诱饵仓库逐项比较,检查 .git、ignore 文件、已删除历史、外部符号链接目标、全局配置和凭据是否进入范围。

归档创建不能直接等同于上传成功。状态至少拆成已创建、已排队、已尝试、已发送字节、服务端已接收、已建索引和已删除。ZCode 调查里 313 MB 失败包与小型公开仓成功样本的差别,正说明了状态拆分的必要性。

5. 用行为验证每一个开关

逐项切换遥测、模型训练、仓库索引、远端同步、崩溃报告和诊断上传,每次都重放冻结实验并比较证据。只有文档中的控制范围与实际变化一致,开关才算通过。

还要测试退出登录和撤销:退出后重试队列是否停止,关闭索引后暂存数据是否删除,用户能否列出并删除服务端对象,删除动作是否存在回执和独立复核。

6. 分开核验代码整改和数据删除

新版本移除上传代码,只能证明当前能力发生变化。它无法证明旧对象、复制副本、日志、派生索引和备份都已清除。整改至少需要两套账:

  • 客户端账:版本、代码或二进制证据、移除的触发点、回归测试;
  • 数据账:受影响对象类别、存储位置、删除执行人、时间、独立检查、备份与派生数据处理。

厂商声明、对象列表归零和独立生命周期审计对应不同证据等级。公开结论时应说明实际取得了哪一层。

真实仓库的准入门槛

只有以下条件全部满足,Coding Agent 才从诱饵仓库晋级到真实源码:

  • 被测试的客户端工件与配置已经固定;
  • 实际外连地址符合书面 Allowlist;
  • 文件与 Git 历史范围符合所用功能;
  • 每个设置项的语义都经过行为验证;
  • 加密存储明确说明解密权归属;
  • 重试、退出、保留和删除行为已经测试;
  • 版本、端点、字节数或文件范围漂移时会触发回归告警。

它与站内已有两道边界互补:安装前信任边界决定哪个依赖可以开始执行,备份与恢复合同负责在获准工具造成破坏后恢复。本篇的数据流审计负责决定获准工具可以读取和发送哪些仓库材料。

FAQ

使用本地模型,代码就一定留在本地吗?

只有整套 Harness 都在本地才成立。桌面客户端仍可能连接遥测、索引、账户、更新、反馈和同步服务。审计对象是完整进程和目标地址,而非模型标签。

关闭遥测是否足够?

不够。遥测、模型推理、索引、诊断和同步可能是互相独立的管线。每个开关都要用文件系统与网络行为单独验证。

加密是否证明厂商无法读取上传内容?

不能。关键是解密密钥由谁控制。服务端持有私钥时,加密可以阻止无关观察者,同时仍允许服务端解密。

当前版本开源,能否证明旧版做过什么?

它只能证明公开状态中可以检查的内容。历史行为仍需要受影响版本源码、可复现二进制、网络证据或当时保存的其他工件。

最小可用审计是什么?

准备一次性账户和诱饵仓库,冻结客户端 Hash,对比未登录与已登录空闲状态,记录新增文件和外连地址,并验证退出登录会停止待处理任务。它无法一次证明永久安全,却能在真实源码暴露前发现隐藏暂存与无条件后台数据流。

把登录变成证据门禁

选择一个正在使用的 Coding Agent,在下次升级前运行七状态诱饵实验。保存安装包 Hash、仓库 Manifest、文件系统 Diff、端点清单和准入结论。目标不是一次证明工具永远安全,而是让每个新版本都用可重放证据重新取得真实仓库访问权。

参考资料


Comment