智谱ZCode偷传代码风波追踪
摘要:不要让闭源Agent陷入信任危机
过去两年,涉及Agent安全讨论的重心主要放在模型失控、提示词投毒和外部攻击者身上,相比之下,Agent厂商自身的数据行为很少被当作一级风险讨论。
近日曝出的智谱ZCode事件,正在把问题转向了一个此前很少被认真对待的方向,那就是Agent的制造商本身是否也可能成为数据外传的来源。
9月18日,技术博主ferstar发布了对智谱ZCode的逆向分析。他发现只要用户登录了账号,ZCode就会在后台把整个工作项目连同完整的修改历史打包加密,上传至云端服务器。
软件界面缺少真正可用的关闭开关,加密文件的解密钥匙只保存在智谱一侧。智谱很快致歉,称问题源于一项功能默认开启,数据用完即销毁,并承诺近期开源代码库、引入第三方审查。
Zcode这次所暴露的问题,早已不是行业孤例。
不久前独立安全研究者cereblab通过抓包分析证明,xAI的编程Agent工具Grok Build会把用户的整个项目打包上传到谷歌云存储,包括用户明确告诉AI不要读取的文件和未经脱敏的密码。
更早些时候,Claude Code被发现在用户不知情的情况下回传位置和身份信息,Anthropic工程师甚至事后确认那是一次有意实验。
更关键的是,这些问题被发现并非因为监管或安全审计,而往往来自社区里的个人,而目前行业为Agent搭建的安全框架,至今没一条规则是用来约束厂商自身行为的。
一. 起点是硬盘异常
9月18日,技术博主ferstar在排查ZCode的本地目录时,注意到硬盘占用空间异常。他找到了一个约313MB的加密文件,体积远超日常大小。文件打不开,但附带的文件清单显示这个包涵盖约4.2万个文件,其中超过8成属于项目历史修改记录。
这份记录不光有项目文件,还涵盖了曾经下载过的大文件缓存和本地操作日志,被打包的不只是项目本身,还包括项目”从出生以来的经历”。
后续的代码分析发现,这份历史记录在打包流程中被豁免于所有安全过滤规则。
ZCode的文件筛选逻辑是按顺序判定的,历史记录目录的放行排在密钥过滤和体积限制之前,这意味着针对pem、key等密码文件的过滤和1MB的体积上限,对历史记录目录下的任何内容都不生效。
这意味着,一个百兆体量打包文件可以整个带走,而任何曾经提交进历史记录又被删掉的密码和密钥,也会原样上传。
更麻烦的操作在后面,解密钥匙不在用户的电脑里。
ferstar拆解还原文件的上传路径,首先客户端向智谱服务器索取上传凭证和一把加密用的公钥,在然后本地完成压缩加密,然后绕过智谱自己的业务服务器,直接上传到阿里云的云存储服务,再由云存储回调智谱后台。
这里稍微解释一下加密方法。
公钥相当于一把锁,任何人都能用它把东西锁进箱子;私钥相当于钥匙,只有持有钥匙的人能打开。ZCode的做法是,锁由服务器临时发放,钥匙只在服务器那头保存,Agent在用户电脑上生成一个加密包,用户自己都无法查看里面到底装了什么。
ferstar发现这套机制会在两个时间触发,一是用户向AI发送请求之前,二在任务结束之后。一个活跃的使用过程中,他观察到多达62次快照记录。
界面上看起来与此相关的两个选项,经他逐一对照代码逻辑后确认,一个叫“优化体验”,实际只控制数据是否用于模型训练;另一个叫“仓库快照索引”,实际只控制服务器端收到数据后是否建立检索目录。
两个都关掉时,本地的打包和上传照常运行。负责快照和上传的组件在软件启动时就会无条件加载,唯一的前提是用户处于登录状态。
除了项目文件,快照每次还会把ZCode自身的全局配置一并打包,跨项目带走。
ferstar尝试手动删除那个313MB的待发送文件。半小时后ZCode自动重新生成了一份新的打包文件,Agent偷偷上传不成就反复重试。
删了还会再建,这或许不是一个可有可无的辅助功能应有的执着程度。
二. 没回应清楚的事
这篇文章当晚社区迅速发酵,智谱火速回应并致歉。
此次问题源于ZCode的“代码库索引”功能。该功能旨在帮助用户在本地生成仓库索引,以支持包括历史版本在内的会话检查点恢复、历史版本回退及Repo Wiki等功能。
Repo Wiki功能在生成Wiki页面时可能会触发仓库数据上传。Wiki页面在云端生成后,相关上传数据会立即销毁,不会保存。由于该功能在上线初期默认开启,部分用户因此受到影响,对此我们深感抱歉,目前相关问题已经修复。
智谱还承诺近期开源ZCode代码库,邀请第三方评估人员审查系统运行情况,并为全体用户额外补偿一次周额度重置,当天发放。
这里的“代码库索引”是为项目文件建立目录和检索系统;“Repo Wiki”则是自动为项目生成一份说明文档的功能;“会话检查点恢复”和“历史版本回退”是让用户在与AI对话过程中可以回到之前某一步的功能。
这些功能本身是合理的,回应也是及时的,但关键在于:
它解释的和社区追问的不是同一件事。
智谱说这套索引“旨在帮助用户在本地生成”。既然是本地生成,那为什么需要把项目整个送到云端?本地做索引、本地做快照、本地做回退,技术上完全可行,市面上也有工具就是这么做的。
说明把“本地索引”和“上传到云端”并成一句话,仿佛后者是前者的自然延伸,但这中间缺了一个关键环节的解释。
回应将问题归于Repo Wiki“在生成Wiki页面时可能会触发仓库数据上传”。但ferstar的逆向记录显示,触发上传的时机之一在用户每次发送提问之前,与生成说明文档无关。
ZCode目前的官方文档明说,生成说明文档时不读取项目的历史修改记录,只按需读取经过筛选的代码上下文,这说明这项功能在技术上并不需要历史记录。
那么此前上传的包里,为什么86.6%都是历史记录?说明没有回答当初上传范围为什么这么大,是设计如此还是程序出错,也没有交代从哪个版本开始修正。
说明用的措辞是该功能“在上线初期默认开启”,这更像把一次机制层面的数据外传表述成了一项功能的开关设置。
ferstar的代码分析显示,界面上的两个相关选项一个管训练一个管索引,都管不住打包和上传行为本身。
社区质疑的核心是用户看到的控制项控制不了真正在发生的事,这和“某个功能默认打开了”不是一个量级的问题。
很快另一份更敏感证据也被社区翻出,那就是ZCode v3.12.2版本的更新日志,日期为2026年9月16日,就是在ferstar发文的前两天。
有一条记录写着“优化仓库快照上传的内存占用”。工程团队很难给一个意外行为优化内存,这说明“仓库快照上传”在内部是一项被持续迭代的正常功能。
这条更新日志在事件发酵后已被删除,删除公开记录本身,是一个独立于原始行为的新问题。
“相关上传数据会立即销毁,不会保存”,这句话回答的是数据保留多久,但用户真正需要知道的还有很多问题,比如数据是否已经离开了电脑,服务器在处理过程中谁有权限访问,加密包的解密能力在谁手上,此前已经上传的数据执行了什么样的删除策略。
从加密方式来看,钥匙在服务器一侧,所以“加密上传”证明的是传输途中不会被第三方截获,并不能推出智谱自身无法解读内容。
ZCode隐私政策英文版对收集范围的措辞是用户“through conversation”(通过对话)提交的文本、文件和代码。但后台快照不是用户通过对话提交的,这个行为不在隐私政策描述的范围内。“在对话中向我们提交”和“后台自动打包整个项目”是两码事。
这份隐私政策还写明,当新功能涉及与原始目的没有直接或合理关联的信息收集时,应通过页面提示、交互流程等方式另行告知并取得用户同意。
另一名开发者冯若航的代码分析发现,客户端每次发送提问时都会无条件向服务端申请上传凭证,服务端发放凭证就采集,不发放就不采集。
ferstar发现的那个313MB的件当时处于待发送状态,已失败564次,冯若航在自己的Mac上独立复现了ferstar的取证流程,在4个工作区的快照记录中,确认至少有一份快照的状态文件已写入服务端接受确认的标记。
按代码逻辑,这个标记只有在上传被服务端确认接收后才会生成。这意味至少有一台机器上的数据确实离开了本地。智谱的道歉、承诺和补偿在争议发酵数小时内全部给出,反应速度不像准备长期隐瞒。
但无论“立即销毁”还是“不会保存”,这类承诺从外部无法验证,也无法证伪。用户能看到的只是数据离开了自己的电脑,之后发生了什么完全取决于厂商的自我约束。
智谱承诺的开源和第三方审查能否改变这一点,取决于开源的是哪个版本、审查覆盖的是客户端还是服务端,这些问题目前没有答案。
三. 比代码数据更敏感的是
如果真有一些厂商真的有意收集用户数据,想要的或许不会是用户代码本身。
因为各大代码托管平台的公开项目为模型训练提供了充足的语料。私有代码当然包含商业秘密,但从模型改进的角度看,仅仅多拿到一批代码文本的边际价值并不高。
真正稀缺的是三样东西。
一是改动的因果链。
项目的历史修改记录里存的不是一张张快照,而是“改之前长这样、因为什么、改成了那样”的完整过程。这种带有前因后果的序列,是训练编程模型最理想的学习材料:给定一个项目现状和一条修改意图,模型应该做出什么改动。
二是带结果标注的使用轨迹。
ZCode的触发机制在每次用户发送提问之前拍一次“全景照片”,同时它又具备回退功能,用户可以撤销AI做出的修改。这两个动作组合在一起,天然地记录了“提问+操作前状态+操作后状态+用户是否满意(有没有撤销)”的完整循环。这种数据在AI训练中极其昂贵,通常需要专门雇人标注,而ZCode的快照机制相当于让用户在正常使用中免费生成了这些标注。
三是没有被任何模型见过的真实项目。
目前公开的编程评测题目几乎都已经被各家模型在训练时“做过一遍”,成绩虚高。真实的、从未进入过训练集的私有项目,是做内部能力评估最有价值的原料。
这三样东西确实和ZCode上传包的构成高度吻合,这就是社区对“只是为了生成说明文档”这个解释始终不买账的原因。
但反过来讲,如果目标真是系统性地采集训练数据,更精确的做法是只抽取提问内容和代码改动,确实也犯不着连几百兆的大文件缓存和完整操作日志一起打包。
这种过度采集的形态,更像是工程团队在开发快照功能时复用了一套通用的打包逻辑,把与索引和回退相关的全部文件一股脑装了进去,加上云端存储本身有成本,大量个人用户的小型项目和练手代码对模型训练的实际价值有限,而对付费客户尤其是企业客户的数据出手,风险收益比其实极不划算。
必须承认,利用这些数据改进模型和工具的动机是成立的,路径是现成的;但从上传包的粗放程度来看,激进的产品决策叠加工程层面的偷懒比“智谱故意想搞点什么”更贴合已有证据。
当然,不能因为智谱没有主观故意而忽视这种问题的严重程度,这确实会给用户带来安全隐患。
四. Agent厂商们的批量越界
与ZCode事件相似的风波,今年已经发生了不止一次。
今年7月,独立安全研究者cereblab对xAI的Grok Build进行了完整的网络抓包分析,并公开了全部证据和复现步骤。
他发现的现象比ZCode更夸张,Grok Build会把用户的整个项目打包成代码包上传到谷歌的云存储服务,上传范围覆盖所有文件,包括用户在对话中明确告诉AI“不要读取”的文件。在一个12GB的测试项目中,截至抓包中断时已确认的文件体积达超过了5G。
测试还发现,项目中的密码和密钥文件甚至也被原样上传,没有经过任何脱敏处理。用户在设置中关闭“改进模型”选项后,上传依然照常进行,关掉的只是训练授权,不影响代码是否离开电脑。
马斯克在事件曝光后公开承诺删除所有已上传数据,xAI在服务器端关闭了上传功能。
更早前的3月31日,其Claude Code在一次版本发布中,一个配置文件的疏忽导致约60MB的源码映射文件被误打包进了公开发布的安装包中,外部开发者得以看到了这款工具的架构。
社区发现,Claude Code每小时向Anthropic服务器轮询一次远程配置,配置项中包含多个可以强制退出程序、绕过用户权限提示的控制开关,全部在后台生效,不需要用户主动更新。
Claude Code曾被发现读取用户的代理、网关地址和中国时区等环境信号,并通过系统提示中的隐蔽字符将分类结果带回服务端。Anthropic工程师随后甚至确认,这是一次用于反账户滥用和反蒸馏的主动实验。
按主观故意程度,Claude Code是厂商自己承认的有意实验,Grok Build至今没有否认上传机制的存在,ZCode的意图尚无定论。
按数据采集范围,Grok Build连用户明确说“不要读”的文件都传走了,ZCode打包了86.6%的项目历史。Claude Code传的是行为元数据,量级不同但性质同样涉及知情权。
三起事故值得警惕的是它们被发现都是源于偶然,一次靠配置失误导致源码泄露,一次靠安全研究者的主动抓包,一次靠博主对硬盘空间不对劲的警觉,没有哪次来自厂商自发的debug或者行业审计、监管巡查。


