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. 做登录状态差分
用相同观察窗口依次运行七种状态:
- 首次启动、尚未登录;
- 停留登录界面;
- 已登录但没有打开工作区;
- 打开诱饵仓库后空闲;
- 发出一个无需仓库上下文的 Prompt;
- 发出一个只明确引用单个文件的 Prompt;
- 关闭应用、退出登录并卸载。
每种状态记录新增和修改文件、进程树、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、端点清单和准入结论。目标不是一次证明工具永远安全,而是让每个新版本都用可重放证据重新取得真实仓库访问权。