返回资讯中心
外部精选
软件工程
#工程实践#架构

智谱把 ZCode 开源了,然后呢?

一场由 ZCode 本地目录异常膨胀引发的排查,最后把一个 AI Coding 产品推到了安全和信任问题的中心。

InfoQ 中国蔡芳芳16 分钟阅读中文

以下正文同步自 InfoQ 中国,版权归原站所有,已转换为易读排版。

一场由 ZCode 本地目录异常膨胀引发的排查,最后把一个 AI Coding 产品推到了安全和信任问题的中心。

9 月 18 日,开发者 ferstar 在清理 MacBook 磁盘空间时,注意到 ~/.zcode 本地目录占用了不少空间。继续逆向客户端和分析网络请求后,他发现,智谱旗下 AI 编程工具 ZCode 会生成本地工作区快照,其中不只有当前代码文件,还包括 .git 历史、Git LFS 缓存、reflog 等内容,并存在将加密快照上传到阿里云 OSS 的链路。ferstar 随后把完整排查过程和证据链公开在个人博客上。

在他进一步分析的一次具体快照中,归档文件大小约 313MB,包含 42,411 个文件,其中约 87% 来自 .git 目录;状态文件显示,这份快照曾经历 564 次上传尝试。不过这份 313MB 快照因为超过大小限制,一直停留在本地 pending 状态,并没有成功上传。ferstar 随后使用另一个较小的公开仓库测试,包含 538 个文件、压缩加密后约 15KB,这一次快照被服务端实际接收。

ferstar 进一步发现,快照采用 AES-256-CTR 加密,加密密钥再由服务端提供的 RSA 公钥封装,对应私钥掌握在云端。按照他逆向得到的链路,客户端首先向 ZCode 服务端获取 snapshot ID、RSA 公钥和 OSS 上传凭证,在本地完成打包和加密后,再将密文直接上传至阿里云 OSS。

智谱随后回应称,问题来自 ZCode 的代码库索引功能。该功能用于支持本地索引、历史版本会话检查点、历史版本回退和 Repo Wiki 等能力,其中 Repo Wiki 在云端生成时可能触发仓库数据上传。智谱表示,这项功能早期默认开启,相关数据在 Wiki 生成后销毁,没有用于模型训练,并就此向用户道歉。

目前 ZCode 已公开源代码,采用 Apache 2.0 许可证,包括 Desktop、Web、Backend、Agent CLI 和 Agent Runtime 等主要组件。与此同时,ZCode v3.14.0 删除 Repo Wiki,并切断本地仓库 snapshot 的生成和上传链路。智谱还邀请中国信通院和绿盟科技进行安全核查:前者确认相关 OSS bucket 已处于零数据状态,后者确认相关数据对象和 bucket 已删除;智谱同时承诺建立长期漏洞响应和奖励机制。

从事件响应来看,道歉、修复、删除数据、引入第三方核查,再到直接把产品开源,智谱在几天内连续做了几轮整改。不过,对于一款能够读取整个代码库、运行 Shell、连接 MCP、调用插件,并可能接触企业凭据的 Coding Agent 来说,事情并没有随着“开源”结束。

至少还有三个问题值得继续追问:今天公开出来的 ZCode,还有哪些数据会离开本地?为什么开源仓库没有保留事故发生之前的 Git history?当一款 Coding Agent 已经发生过数据边界争议后,“代码开源 + 第三方安全核查”能在多大程度上重新建立信任?

ferstar 在开源代码公布后重新进行了源码对账。他没有再找到此前客户端中的 repoSnapshot 上传管道,Repo Wiki 相关功能也已经消失。智谱披露的第三方核查结论同样表示,v3.14.0 中没有发现可以继续触发本地仓库快照生成或文件外发的功能路径。

不过,ZCode 也没有因此变成一款“数据不离开本机”的 Coding Agent。智谱在开源仓库里专门放置了一份相当详细的 NOTICE 文件,列出了 ZCode 目前仍然存在的外部交互面。

文件、Git、Terminal、Shell、Node REPL 可以在宿主操作系统账号权限范围内读写文件、启动进程和访问网络;插件可以带入自动执行的 Hook、本地程序和远端工具;MCP 可以使用配置中的命令、环境变量、认证 Header 或 OAuth 连接外部服务;内嵌浏览器可以访问网页、读取页面、截图、上传和下载文件;远端 Workspace、SSH、Web 服务又分别拥有自己的网络和权限边界。

ZCode 还在 NOTICE 中提醒用户:当前共享 Agent Runtime 默认并不提供操作系统级 Sandbox。独立 CLI 在使用 --prompt 进行非交互执行、又没有指定 mode 时,会进入 yolo 模式;在这一模式下,普通工具操作可以不经过逐次确认。

Repo Wiki 事件里最显眼的是工作区快照上传,所以最初的讨论基本都围绕代码库上传展开。但放到 Coding Agent 的工作方式里,数据边界显然要复杂得多。

模型 API 需要获取上下文,MCP Server 可能接触文件和凭据,插件和 Hook 可以读取工具参数和返回结果,Browser Agent 可能接触登录态,Shell 则能访问开发者机器上的其他目录。Git、包管理器以及项目里的 lifecycle script,也都可能进入 Agent 的执行链。

因此,判断一款 Coding Agent 如何处理用户数据,单独确认“是否上传 repository”还不够。还需要知道什么数据只停留在本地,什么会进入模型上下文,什么会传给智谱自己的服务器,什么会进入第三方模型;MCP、插件和 Browser 分别能够获得哪些数据;哪些行为需要用户确认;数据保存多久,以及服务端由谁拥有解密和访问能力。

ZCode 开源之后,社区至少有机会沿着源码逐项检查这些数据流。不过,目前公开的信息还不足以形成一张完整的数据流图。

ferstar 对公开仓库的 Git history进行了检查:目前仓库历史极其简单,一个空的 initial commit,加上一个名为 feat: open source 的提交。后一个 commit 一次性加入了约 6973 个文件、103 万行代码。

也就是说,外界目前拿到的主要是整改完成之后的代码快照。此前包含 Repo Wiki、repoSnapshot 和上传逻辑的历史版本,没有随着开源仓库一起出现。

这会直接影响外部开发者对这次事件的复盘。比如,这条上传链最早是什么时候加入的?最初服务于哪个功能?经历过哪些修改?默认开启对应哪一次产品决策?哪些正式版本包含这段代码?最终删除时具体修改了什么?这些原本都可以通过 Git history 和版本 diff 提供线索,现在很难直接从开源仓库中还原。

当然,公开 100 多万行当前代码仍然有价值。至少外部开发者现在可以审查 ZCode 的现有实现,也可以基于 Apache 2.0 许可证自行构建、修改和部署。但如果开源同时承担了安全事件之后恢复信任的作用,代码历史同样是重要的安全证据。

软件安全事件调查经常需要追踪 provenance:一个功能从哪里来、什么时候进入代码、如何演化,以及修复究竟改变了哪些东西。只公开整改后的 snapshot,可以帮助社区确认 ZCode 现在还有没有这段代码;至于事故发生时的代码究竟是什么状态,现有仓库能够提供的信息就有限得多。

智谱最初解释,这条链路与“代码库索引”“历史版本检查点恢复”“Repo Wiki”有关。ferstar 在开源版本中进一步检查后认为,checkpoint 机制主要体现为本地 Git diff,而非云端 repository snapshot。按照他对源码的检查,目前 checkpoint 的核心实现是调用本地 Git CLI,通过 git diff --name-status 和 git diff --numstat 计算变化,相关元数据保存在本地 ~/.zcode/checkpoints/。

由于事故前代码没有进入公开 Git history,外部研究者暂时很难继续从版本演进层面核对这些功能过去的关系。

类似的问题也存在于数据端。信通院确认检查时 OSS bucket 已经是“零数据状态”,绿盟确认数据对象和 bucket 已经删除。这些核查说明了检查发生时的数据状态,但此前的数据生命周期,还需要更多信息才能还原。

例如,过去成功上传过多少 repository snapshot、涉及多少用户、对象平均保存多久、服务端哪些系统或人员具备解密和访问权限、是否存在完整 access log、删除范围是否包括备份和其他副本,这些问题目前还缺少公开材料。

智谱这一次采取的处理路线很有代表性:发生争议之后关闭相关功能,随后删除云端数据,邀请第三方机构验证整改结果,最后把产品源码公开,让社区继续检查。

这些动作都有实际作用。不过,如果把这套方案放到 Coding Agent 数据安全事件的处理框架里,还有一个关键问题:外界能够独立验证到什么程度。

截至目前,智谱公开的主要是中国信通院和绿盟科技的核查结论摘要,并表示完整安全评估报告随后会发布。现有信息能够确认的是,整改后的版本已经移除了相关上传链路,相关 OSS bucket 在核查时也已处于零数据状态。但第三方核查究竟覆盖了多大范围,目前披露的信息还比较有限。

比如,核查对象是否只包括 v3.14.0 当前代码,还是也包括事故发生时的版本;是否检查过服务端代码和 OSS audit log;是否核对过加密私钥的生命周期;能否还原历史上传数据的规模;备份和其他数据副本是否也在核查范围内。这些信息会直接影响第三方核查结论能够覆盖到哪里。

对于一次安全事件来说,“已经修复”只是其中一个层面。外界还需要知道发生过什么、影响范围有多大,以及相关数据是否留下过其他副本。因此,安全审计报告里的核查范围和最终结论同样重要。

开源也是如此。如果厂商希望通过开源建立长期信任,除了公开当前源码,还可以进一步保留完整 Git history、建立公开 Security Advisory、开放漏洞报告渠道、给关键 release 做可复现构建,并公开各版本的数据流和权限变化。做到这些之后,外界才有更多条件自己核对修复是否完成,而不只是依赖厂商声明和第三方结论摘要。

这对 Coding Agent 尤其重要,因为它拥有的权限已经明显超过传统 IDE:源码、Shell、浏览器、GitHub、MCP、插件、云服务和各种凭据,都可能被放进同一条 Agent 执行链。

几乎就在 ZCode 风波发生的同时,安全公司 AIR Security 披露了一组影响 Claude Code、OpenAI Codex、GitHub Copilot 和 Gemini CLI 的供应链漏洞,并将其命名为 Plugin4Shell。

为了保证用户安装的插件就是审核过的版本,系统通常会把插件 pin 到一个具体 Git commit SHA。理论上,一个 40 位 commit hash 应该唯一对应一份代码。但 AIR Security 的研究人员发现,这几款 Coding Agent 在 checkout 之后,没有再次验证最终工作目录里的代码是否真的对应那个 commit。

攻击者如果控制插件仓库,可以利用 Git reference resolution 的问题,让 Agent 表面上 checkout 了那个 SHA,最终落到工作目录里的却可能是攻击者控制的代码。对于支持插件后台自动升级的场景,攻击链甚至可以在用户没有再次确认的情况下触发。

根据 AIR Security 公布的漏洞披露和修复时间线,Claude Code 已在 2.1.179 修复,Codex 在 0.146.0 修复;截至该公司 9 月 17 日公开研究时,GitHub Copilot 尚未提供补丁。Google 则告知研究人员 Gemini CLI 已弃用,不再修复,建议用户迁移至不受该攻击路径影响的 Antigravity。

AIR Security 表示,他们在 2026 年 5 月已经针对四款 Agent 完成可工作的 PoC,并于 6 月向四家厂商协调披露。目前公开材料主要证明漏洞和攻击链可以被复现,尚未提供该漏洞已被用于大规模真实攻击的证据。

Plugin4Shell 和 ZCode 属于两类不同的问题,一个涉及数据上传,一个涉及插件供应链,但它们都发生在模型之外的 Agent 执行链上。

过去谈 AI 编程安全,讨论更多集中在模型会不会生成有漏洞的代码、Prompt Injection 会不会诱导 Agent 做出错误操作。现在需要纳入考虑的组件已经越来越多:Harness、Git、Plugin、MCP、Hook、Browser、Shell、Credential、Workspace 和 Cloud Storage,都可能成为安全边界的一部分。

Coding Agent 本身又处在一个权限很高的位置。它需要读取源码才能理解项目,需要运行 Shell 才能测试,需要访问 GitHub 才能提交 PR,也可能需要 package registry、云服务乃至生产环境凭据来完成任务。在这样的环境里,一个普通插件漏洞的影响也会被放大。Plugin4Shell 的风险就在于,恶意插件一旦进入 Agent 执行链,可能进一步接触开发者已经交给 Agent 的私有代码库、SSH key、API token、云凭据和内部服务。

从这个角度看,ZCode 和 Plugin4Shell 分别暴露了 Coding Agent 安全边界的两端:一端是 Agent 能把哪些数据送出去,另一端是谁能够进入 Agent 的执行链、继承已经授予它的权限。两边最终都落到同一个问题上:当 Coding Agent 获得越来越多工具和权限后,围绕它的安全设计不能只盯着模型本身。

智谱在几天内关闭 Repo Wiki 上传链路、删除相关 OSS bucket、引入第三方机构核查,并最终把 ZCode 以 Apache 2.0 开源。至少,一次原本发生在闭源客户端里的争议,现在多了一条社区可以继续检查的路径。

但目前仍有几块信息没有完全补齐。智谱承诺的完整第三方安全评估报告尚未公开,事故发生时的代码和完整版本 Diff 也没有进入开源仓库;历史上传数据的规模、访问记录和服务端处理链,目前同样缺少更完整的披露。至于这次事件之后,ZCode 是否会进一步建立可持续审查的数据流、权限和插件安全机制,也还需要后续的产品更新来回答。

这些问题其实并不限于 ZCode。Coding Agent 已经从一个辅助写代码的工具,逐渐变成可以读取整个项目、执行命令、访问网络、连接外部系统并代表开发者完成任务的软件。能力扩大的同时,过去分散在 IDE、Shell、浏览器、Git、云服务和插件系统里的权限,也开始集中到同一个 Agent 身上。

所有 Coding Agent 厂商都不得不直面这样一个问题:用户把整个代码库和越来越多的系统权限交给 Agent 之后,厂商准备拿什么证明这些权限没有被滥用?

ZCode 的开源提供了一种回答方式。但要让这个回答更有说服力,还得看开源之后能留下多少可追溯、可审计、可由外界独立验证的东西。

正文由 FLUX 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。