事件窗口 2026 年 9 月 16 日(ZCode v3.12.3 发布)至 9 月 21 日 21:00(UTC+8,本文数据截点)· 报告编号 RCX-RI-20260921-ZCODE · 事件素材取自 ferstar 逆向取证博文、zai-org/ZCode 开源仓库、AkaraChen 安全 Gist、object_nullll 源码审计推文、智谱官方声明与 IT之家、澎湃新闻、中新网、界面新闻、DoNews、InfoQ 报道;对照案例取自 cereblab 抓包报告、The Hacker News、runtimewire、trinity-cloud 协议分析、segmentationf4u1t 遥测研究与各产品官方隐私文档 · 本报告与智谱、xAI、Cursor、字节跳动均无利益关系
2026 年 9 月 18 日上午,一位网名 ferstar 的工程师清理自己那台 256G 丐版 MacBook Air 的磁盘,发现 ~/.zcode 目录莫名占了 700 多 MB。顺手解包排查之后,他确认了一件事:只要处于登录状态,智谱旗下的 AI 编程工具 ZCode 就会在后台把他打开过的整个工作区——包括完整的 .git 提交历史、LFS 大文件缓存、reflog 操作轨迹和全局配置——打包加密后直传阿里云 OSS,而加密私钥只存在云端,他本人和客户端都无法解开那份属于自己代码的密文。他把取证过程写成博文发到 X,阅读量很快突破 160 万。
接下来的 72 小时,事情以罕见的速度推进:当晚智谱在用户群致歉、次日推送修复版本、第三天一家山西企业发出特急律师函、第四天 ZCode 宣布开源并公布两家机构的安全审计结论。而就在开源当天,社区在放出的源码和发行包里又找到了两个新问题——本地保存的全部模型 API Key 被指「等效明文存储」,服务端还保留着向客户端远程注入 prompt 的配置通道。
这不是孤立事件。往前数十四个月:2025 年 7 月,字节跳动 Trae 被抓包「关了遥测照样上传」;2026 年 7 月,xAI 的 Grok Build 被逐包取证「整仓 git bundle 上云」,同月 Cursor 被用户指控「取消订阅后仍上传 736MB 代码」。四家厂商、四种产品形态、几乎同一套剧本。这篇报告要做四件事:还原 ZCode 事件的完整来龙去脉;用工程语言拆解「静默上传」在技术上如何发生、传走了什么;把四起事件放进同一张对照表,找出它们共同的结构性成因;最后给出开发者个人与企业团队都能落地的行动清单。
摘要
- ZCode 事件的核心不是「AI 读了你的代码」,而是范围与姿态的双重越线:推理只需要当前任务的上下文,它却打包了整个仓库连同全部 Git 历史;取证显示打包与上传由登录态无条件触发,UI 没有任何开关能关闭,手动删除快照半小时内自动重建,加密私钥自始至终只在服务端。
- 官方解释与开源代码对不上账。智谱称上传服务于「会话检查点回滚」与 Repo Wiki,但 9 月 21 日放出的源码显示:检查点功能是纯本地的 Git 增量比对,元数据存在本机,与云端无关;代码检索也由本地 ripgrep 完成。整仓上云对这些功能而言并非必需。
- 时间线上仍有未决问题:企业用户承明科技独立取证称,在智谱公开致歉当日凌晨仍检测到上传行为;其特急函同时指出 ZCode 网络请求指向智谱新加坡主体、签约方却是北京公司,将事件引向数据出境合规。两家机构的审计确认云端存储桶已清零,但只能证明「现在没有」,无法倒推 9 月 18 日之前流入的数据是否被解密、同步或备份。
- 这是同一剧本的第四次上演:Trae(2025-07)关闭遥测只关掉 VS Code 模块、自家采集照常;Grok Build(2026-07)关闭「改进模型」后整仓照传,曝光次日服务端静默翻转开关;Cursor(2026-07)被指仅凭登录态即上传,索引设置页可被服务端 flag 隐藏。共同结构:全量采集默认开启、用户开关只管训练或留存、真正的控制面在服务端、曝光后修复但历史数据成谜。
- 结构性成因有三层:AI 编程工具天然要「看」代码,合理边界因此模糊;真实世界的编码轨迹(提示、改动、报错、修复的完整序列)是训练下一代 Agent 模型最稀缺的燃料,订阅烧钱的厂商有强烈的采集冲动;客户端热更新与服务端 flag 让「今天不传」随时可以变成「明天传」,单次事后审计无法约束。
- 风险被两个细节放大:
.git历史会带出已删除的密钥、未推送的分支和内网域名——「删掉了」不等于「不在历史里」;ZCode 本地凭据加密的默认密钥由平台名、家目录和用户名推导(无盐、无 KDF),拿到密文文件等于拿到全部 API Key。用过受影响版本的用户,当下最优先的动作是轮换所有历史密钥。
一、72 小时事件链:从 700MB 的疑惑到一纸特急函
先把全部关键节点放在一张表里,再展开细节。
| 时间(UTC+8) | 事件 |
|---|---|
| 8 月 11 日 | 智谱宣布 ZCode 用户突破 100 万,定位「针对 GLM 深度优化的国产 Coding Harness」,与 GLM Coding Plan 订阅捆绑,构建「基础模型 + Coding Harness + 订阅服务」生态 |
| 9 月 16 日 | ZCode 更新至 v3.12.3(后被确认为问题版本之一) |
| 9 月 18 日上午 | ferstar 发布逆向取证博文:登录即触发整仓快照上传,开关无效、删除重传、私钥只在云端;原推阅读量超 160 万 |
| 9 月 18 日 17:44 | 智谱在用户群发布说明并致歉:归因「代码库索引 / Repo Wiki」功能默认开启,称上传数据「生成 Wiki 后立即销毁、不会保存」,承诺开源、引入第三方审查,并给全体用户重置一次周额度 |
| 9 月 19 日 | 推送 v3.14.0,更新日志写明「修复仓库百科异常上传的问题」;同日,太原承明科技向北京智谱华章发出「承明〔2026〕法函字第 1 号」特急函(9 月 20 日经多家媒体披露) |
| 9 月 21 日 09:23 | ZCode 宣布开源(GitHub: zai-org/ZCode,Apache-2.0),并公布中国信通院与绿盟科技审计结论:涉事阿里云 OSS 存储桶已删除、云端零数据,v3.14.0 已移除快照上传链路,上传凭证接口返回 404 |
| 9 月 21 日中午 | 开源数小时后,社区再爆两项新发现:本地凭据加密默认密钥可瞬时重算(AkaraChen Gist);源码与发行包比对显示遥测体系涉及 311 个文件、多个官方插件未开源、服务端保留远程注入 prompt 的配置字段(object_nullll 推文) |
发现:一份 313MB 的加密文件,重试了 564 次
ferstar 在 ~/.zcode/v2/checkpoints/ 下找到一个 313MB 的 .enc 加密文件,旁边的状态文件写得明白:客户端扫描了他本地打开的某商业项目,排除 node_modules 等目录后,把剩下 345MB 的内容打包加密为 313MB 的「baseline」全量快照,并已尝试上传 564 次——因为体积超过服务端限制,这个包始终卡在本地待传队列里,成了这次取证最关键的物证。他的路由器流量日志证实这几百兆密文没有出过局域网。但另一个只有 538 个文件的小型公开仓库工作区,压缩加密后约 15KB,状态显示已被服务端正式接收入库。「有没有真的传出去」这个问题,至少在这台机器上答案是:传出去了。Windows 用户随后在 NodeSeek 等社区复现出同一套目录结构和多份无失败记录、看似已入库的小仓快照。
回应与反复:致歉当日凌晨仍在上传
智谱 9 月 18 日傍晚的说明确认了上传行为的存在,把原因归结为「代码库索引」功能:它为本地索引、会话检查点回滚和 Repo Wiki(代码仓库知识库)服务,Repo Wiki 在云端生成页面时「可能」触发仓库数据上传,数据生成后「立即销毁」;该功能上线初期默认开启,「部分用户」受到影响,问题「已经修复」。
但按承明科技函件的说法,其技术部门在 9 月 18 日凌晨——即客户端已更新至 3.12.3、距官方宣布修复不足一天时——仍检测到上传行为。这家成立于 2026 年 4 月的山西企业由此对「已修复」的实际效果提出质疑,并在 9 月 19 日发出特急函,提出十二项要求:彻底删除全部已上传数据及衍生数据、缓存、备份并出具证明;说明数据去向、是否共享第三方、是否用于模型训练、是否跨境;公开加密私钥的保管方式与数据被访问、下载、导出的完整日志;限期 10 月 10 日前书面答复,并保留索赔、向监管投诉和提起诉讼的权利。
函件里最有分量的一点是管辖问题:ZCode 客户端的全部网络请求指向 zcode.z.ai 与 cdn-zcode.z.ai,而 Z.AI 平台的缔约主体与个人数据控制者是智谱 2023 年 11 月在新加坡注册的间接全资子公司 JINGSHENG HENGXING TECHNOLOGY PTE.LTD;中文版隐私政策写的处理者却是北京智谱华章,英文版则明言服务「通常由新加坡提供」、个人数据「通常在新加坡处理」。若境内企业数据确实出境,按《个人信息保护法》第三十八条,处理者须满足安全评估、保护认证或标准合同三者之一;第三十九条还要求逐项告知并取得单独同意。「网络主体在新加坡、签约主体在北京」,恰好击中这个合规要害。截至发稿,智谱未就函件公开回应。
开源与审计:止损动作与它证明不了的事
9 月 21 日上午,ZCode 开源如约而至,同时公布了两家机构的审计结论:中国信通院确认涉事 zcode-prod 存储桶「云端零数据」,绿盟科技确认桶及全部数据对象已删除、新版客户端「未发现可触发本地仓库快照或文件外发的功能路径」。智谱同时承诺无留存、从未用于训练,MaaS 平台上线「数据内容不留存」选项,并宣布建立常态化漏洞报告与奖励机制。
把桶清空、把链路物理删除,是应有的止损动作,也值得肯定。但单次事后审计在逻辑上只能证明「9 月 20 日之后桶是空的」,无法倒推 9 月 18 日之前流入的数据是否曾被解密、同步或备份——历史数据的生命周期,没法靠一次快照式检查自证清白。要回答「删干净了吗」,需要的是留存策略、访问日志、备份清单和合同化的审计权,这正是承明函件十二项要求背后的逻辑。
更值得玩味的是开源本身的姿态:仓库只有两条提交——一个空的初始 commit,加上一次性导入 6,973 个文件、103 万行代码的 feat: open source。内部开发史被完全抹平,看不到旧版上传管线的演进与移除过程;PR 被锁、Issue 被关,社区把它称为「单向投喂式开源」。当天下午,这份源码就帮社区发现了下一节要讲的新问题——从这个意义上说,开源确实起了作用,只是方向未必如厂商所愿。
二、技术拆解:一次「静默上传」到底传走了什么
上传链路:为什么你「看不见」它
还原出的链路分两步。第一步,客户端向 zcode.z.ai 请求上传凭证,服务端返回四样东西:快照 ID、本次加密要用的 RSA 公钥、体积上限,以及阿里云 OSS 的表单直传签名。第二步,客户端在本地把工作区打成 tar.gz,用随机对称密钥做 AES-256-CTR 流式加密,再用服务端下发的公钥以 RSA-OAEP 包裹对称密钥(标准的信封加密),然后绕过智谱自己的业务服务器,直接把密文 POST 给阿里云 OSS,由 OSS 回调通知智谱后端登记。触发点有两个:captureBeforePrompt(每次向模型提问之前)和任务结束时的 repo-wiki-update;日志显示单个活跃会话最多产生 62 次快照捕获。
这套设计对用户端的可见性几乎为零:流量不走业务 API 域名、密文本地不可解、功能不在设置页露出。所谓「静默」,是工程上实打实做出来的静默。
传了什么:.git 目录才是主菜
密文解不开,但快照生成时的文件清单(Manifest)留在本地。ferstar 统计了那份包含 42,411 个文件的清单:
| 内容 | 体积 | 占比 | 里面有什么 |
|---|---|---|---|
.git/lfs/ |
196.1 MB | 56.8% | LFS 缓存:项目历史上拉取过的所有大文件与二进制资产 |
.git/objects/ |
102.2 MB | 29.6% | 完整 Git 对象库:全部 Commit、Tree、Blob 历史 |
.git/logs/ |
0.6 MB | 0.2% | reflog:本地所有分支操作与未推送记录 |
| 源码与文档 | 约 46.2 MB | 13.4% | src/、配置文件与业务代码 |
Git 的对象库近乎「只加不减」:你把误提交的数据库口令从代码里删掉、再提交一次,口令仍然完好地躺在历史对象里,git log 翻旧提交或直接遍历对象库就能找回。所以一份带完整 .git 的快照,等于交出这个仓库自创建以来的一切:早已「删除」的密钥与敏感配置、还没推送到远端的分支名(直接暴露未公开的研发动向)、.git/config 里的内网 GitLab 域名与仓库路径。这也是本次事件与「AI 读取当前文件做推理」的本质区别——后者看的是现在,前者拿走的是全部过去。
此外代码里还有一个 repo_snapshot_extra_manifest,会把 ZCode 的全局配置文件哈希后跨工作区打包,随每次快照一起上传。
钥匙在谁手里:备份与采集的分界线
信封加密本身是行业标准做法,问题出在密钥归属。如果这是给用户做的断点恢复或跨设备同步,解密密钥理应留在用户本地——像 Git 或 Time Machine 那样,数据是你的,钥匙也是你的。而 ZCode 的 RSA 公钥由服务端随凭证临时下发,私钥从头到尾只在云端:你硬盘上那份 313MB 密文,你自己打不开,客户端也打不开,全天下只有智谱后端能解。ferstar 的判语很干脆:「一把只有服务端能解的钥匙、零披露的隐私政策、关不掉的默认行为、删了还自动重传的执拗——这摆明了不是备份,更像采集。」
开关为什么没用:两个都不管上传
| 设置项 | 用户以为它管 | 实际管什么 |
|---|---|---|
| 优化体验(optimizeAgentExperienceEnabled) | 数据采集 / 遥测上传 | 只决定数据是否被授权用于模型训练;关闭后快照照常打包上传 |
| 仓库快照索引(repoSnapshotIndexingEnabled) | 快照功能本身 | 只决定服务端拿到快照后要不要建索引;关闭后本地打包与上传一点不落 |
代码层面更直白:负责快照捕获与上传的 sidecar 在客户端启动时无条件实例化,没有任何针对用户配置的判断,唯一条件是能拿到登录后的 JWT。换句话说,登录即常开,且 UI 里没有任何开关能关掉它。ferstar 删掉待传包后半小时内它自动重新打包,失败计数从 564 变成 565——最后他只能用文件系统的不可变锁(macOS chflags uchg / Linux chattr +i)从内核层面禁止写入,才彻底断掉这条链路。
官方解释对不上账:检查点根本不需要云
官方把上传归因于「会话检查点回滚」与 Repo Wiki。开源之后这个说法可以直接对账了:源码中的检查点实现(gitCheckpointService.ts)是纯本地方案——用 git diff 在当前工作区范围内算增量改动,元数据以 JSON 存在本机 ~/.zcode/checkpoints/,全程没有云端依赖。代码索引与符号检索也退回为本地进程调用内置的 ripgrep 与 bfs,运行良好。也就是说,被拿来解释整仓上云的两个功能,在工程上都不需要整仓上云;而「上传数据用于检查点回滚」与「生成 Wiki 后立即销毁」两种说法本身也互相矛盾——要回滚就不能销毁,要销毁就无从回滚。
开源当天又发现的三件事
第一件:本地凭据加密被指「等效明文」。开发者 AkaraChen 对照开源仓库与官方 3.14.1 发行包发现,ZCode 把用户各模型厂商的 API Key 与 OAuth token 用 AES-256-GCM 加密落盘,但默认加密密钥不是任何秘密,而是「平台名 + 家目录路径 + OS 用户名」拼接后做一次 SHA-256——无盐、无 KDF、单轮哈希,重算不到 1 毫秒;而这三样信息与密文文件物理上放在一起(文件属主就是用户名)。这意味着任意同权限恶意进程、一份 Time Machine 备份、一块没清干净的二手硬盘,都能瞬时解出你保存过的全部 Key,且密文跨机器可解。macOS 本有硬件级的 Keychain 可用,NOTICE.md 自己也承认「并非系统钥匙串」——不是做不到,是没做。
第二件:遥测体量与未开源组件。object_nullll 用 GLM-5.3-Flash 审计开源代码发现,遥测体系涉及 311 个文件(开源构建被强制关闭,但足以看出闭源版的采集面);CUA(计算机使用)、手机模拟器、Office 套件等官方插件并未随仓库开源,开源版本构建出来找不到这些组件——「开源」覆盖的只是核心壳层。
第三件:服务端保留改变客户端行为的通道。远程配置接口的实测响应中包含 forceUpdate(强制更新)、desktopContextPrompt(服务端下发注入客户端上下文的 prompt)与 rendererActionTrace(行为追踪开关)等字段。结合客户端的热更新能力,这意味着「当前版本不上传」是一个可以被服务端随时改写的状态——这个问题不止属于 ZCode,下一节会看到它是全行业的通病。
三、不是孤例:十四个月里的四份同款剧本
| 产品(厂商) | 曝光时间 | 被曝行为 | 名义用途 | 用户开关的真实语义 | 后续 |
|---|---|---|---|---|---|
| Trae(字节跳动) | 2025-07 | 约 7 分钟 500 余次请求、26MB 遥测:设备指纹、文件类型、焦点状态、工作区标识等,流向 byteoversea.com | 产品统计与性能监测 | 「关闭遥测」只关 VS Code 模块的遥测,Trae 自身采集不受其控制 | 承认「误解」、8 月补上隐私模式;现行文档:隐私模式仅登录时生效,代码库索引仍需临时上传代码算 embedding |
| Grok Build(xAI) | 2026-07 | 把整个 Git 仓库连历史打成 git bundle 传至 xAI 的 GCS 存储桶,12GB 测试仓传走 5.10GiB,含从未被读取的文件 | 会话轨迹 / 模型改进 | 「Improve the model」开关只管训练授权,开或关整仓照传;后补的 /privacy 是留存开关,不是发送开关 | 曝光次日服务端静默翻转 disable_codebase_upload,无公告无日志;Musk 承诺删除历史数据(未经独立验证);后开源,新版复测未见上传,但上传代码仍在二进制中 |
| Cursor(Anysphere) | 2026-07 | 用户取证:订阅取消数月、隐私模式开启、索引关闭,7 月 18–27 日仍上传 736MB、63,106 个文件(索引块含源码行) | 代码库索引 / 语义搜索 | 「隐私模式」管训练与留存,不管索引上传;索引设置页可被服务端 disable_codebase_indexing flag 整体隐藏 | 官方称文件经哈希、原文不存储;独立复测显示未修改客户端仅在索引开启时上传,个案触发条件未有定论;已上传数据用户无法自助删除 |
| ZCode(智谱) | 2026-09 | 登录即整仓快照(86.6% 为 .git)加密直传 OSS,删除自动重传,无 UI 开关,私钥仅在云端 | 代码库索引 / Repo Wiki / 检查点 | 「优化体验」管训练、「快照索引」管服务端建索引,均不管上传本身 | 致歉、开源、双机构审计确认桶已清零;企业函件追责与出境合规质疑待答;开源当天再爆凭据弱加密与远程 prompt 注入通道 |
把四行放在一起,剧本的骨架清晰可见:默认开启的全量采集 + 语义含混的用户开关 + 服务端掌握的真实控制面 + 曝光之后的静默修复。四家厂商的产品形态各不相同(IDE、CLI、桌面端、编辑器),却在同一批结构位置上跌倒。
值得单独说明的是 Cursor 案的复杂性:独立研究者 cereblab(也是 Grok Build 事件的取证者)用未修改客户端复测,发现只有在索引启用时才会产生上传——Tissera 个案的确切触发条件至今没有定论。但两个无争议的事实依然成立:其一,官方协议分析确认索引上传的 CodeChunk.lines 字段携带的就是逐行源码(明文在请求生命周期内处理,官方称不留存原文);其二,客户端里还内置了一套按账号灰度的整文件同步服务(FSUploadFile),当前对普通账号关闭,但「无需客户端更新即可被服务端打开」。能力已经在船上,开关不在乘客手里——这正是本报告反复强调的结构性问题。
2023 年 4 月,三星半导体部门在放开 ChatGPT 使用后约二十天内连出三起泄露——员工把设备良率代码和会议纪要主动贴进对话框,最终换来一纸全面禁令。那是第一代风险:人把代码送进模型。三年后的这一批事件是第二代风险:工具自己把代码运出机器,不需要你贴,甚至不需要你用。风险的主语变了,防御的思路也必须跟着变。
四、为什么层出不穷:AI Coding 的结构性冲突
1. 推理必须「看」代码,边界因此天然模糊
先说公道话:AI 编程工具要发挥作用,就必须读取代码上下文。你让它补全函数,它要看这个文件;你让它跨文件重构,它要看半个仓库的索引;托管推理意味着这些上下文必然发往云端模型——即便在一切整改之后,这一层传输也不会消失,Grok Build 新版的复测报告写得明白:「托管推理仍会把 prompt 与模型上下文发给 xAI,即使编码数据留存已关闭。」这是使用云端 AI 的合理对价,各家隐私政策也都写了。
越线发生在两个维度。范围:推理需要的是当前任务的相关上下文,而不是整个仓库加全部历史加全局配置;为一次代码补全打包 42,411 个文件,用任何工程标准衡量都是过度采集。姿态:合理的数据流应该可见、可控、可关;静默触发、开关无效、删除重传、私钥他持,每一条都在把「必要的功能数据流」变成「单方面的采集管道」。判断一个 AI 工具是否越线,不用读完隐私政策,看这两条就够了。
2. 真实编码轨迹,是大模型时代最稀缺的燃料
为什么厂商甘冒声誉风险也要伸手?看一眼 Grok Build 那个存储桶的名字就明白了:grok-code-session-traces——「编码会话轨迹」。下一代 Agent 模型的竞争焦点,已经从「会写代码」转向「会自主完成工程任务」,而训练这种能力最需要的不是 GitHub 上的静态代码(早就被爬完了),而是真实开发者的完整工作轨迹:一个真实的仓库状态、一句真实的需求、模型的每次尝试、测试的每次报错、人类的每次纠正。这类数据在公开互联网上几乎不存在,只在 AI 编程工具的会话里批量产生。
再叠加商业压力:Coding 订阅是烧钱生意,推理成本高企、订阅费远不能覆盖,「数据回报」是财务模型里难以明说的一项。智谱 8 月刚宣布 ZCode 用户破百万、周额度全员重置搞增长;xAI、Cursor 都在打订阅价格战。当「用户的真实工程数据」同时是产品改进的养料、模型训练的燃料和融资故事的注脚时,采集的组织冲动是结构性的——除非有同样结构性的约束去对冲它。
3. 「功能」是万能包装纸
四起事件里,厂商给数据外流找的理由高度一致:索引、语义搜索、知识库、检查点、会话恢复——全是真实有用的功能。包装的拆法也一致:看这个功能在工程上是否真的需要那么多数据出境。ZCode 的检查点在源码里是纯本地实现;本地 ripgrep 足以支撑代码检索;Cursor 的语义索引确实需要上传代码块算 embedding,但官方文档同时承认「明文在请求结束后不保留」是可以做到的工程承诺。功能本身几乎从来不是问题,问题是借功能之名超采、以及数据到云端之后的去向失控。
4. 开关的语义游戏:训练 ≠ 上传 ≠ 留存
这是四起事件中最具欺骗性、也最值得用户记住的一层。设置页里那个让你安心的开关,管的往往只是数据链条的最后一环:
| 产品 | 开关名称 | 用户预期 | 实际语义 |
|---|---|---|---|
| Grok Build | Improve the model | 不收集我的代码 | 只管是否用于训练;整仓上传照旧 |
| Grok Build | /privacy opt-out | 不上传 | 只管服务端是否留存;发送不受影响 |
| ZCode | 优化体验 | 不采集 | 只管训练授权 |
| ZCode | 仓库快照索引 | 不做快照 | 只管服务端是否对快照建索引 |
| Cursor | Privacy Mode | 代码不出本机 | 管训练与留存;索引上传与 AI 请求照发 |
| Trae | 关闭遥测 | 停止数据上报 | 只关 VS Code 框架的遥测;自家采集独立运行 |
数据要经过发送、留存、使用(训练)三道闸门,用户拿到的开关几乎全部装在第三道,偶尔装在第二道,几乎从不装在第一道。The Hacker News 对 Grok 事件的总结适用于所有人:「训练退出不是代码不离开机器的承诺。」(A training opt-out is not a promise that your code stays put.)读任何 AI 工具的隐私设置时,先问一句:这个开关管的是哪道闸?
5. 客户端只是壳,控制面在云端
四起事件还共享一个更隐蔽的技术结构:决定数据是否外流的开关,握在服务端手里。Grok Build 的修复是服务端翻转 disable_codebase_upload——同一个二进制、前一天传后一天不传,而上传代码仍留在客户端里,随时可以被翻回来;Cursor 的索引设置页可以被 disable_codebase_indexing 服务端 flag 整体隐藏,整文件同步服务按账号灰度;ZCode 的远程配置接口能下发 forceUpdate 与 desktopContextPrompt,后者意味着服务端可以直接向客户端的模型上下文注入指令。加上普遍存在的热更新机制,「我审计过这个版本不上传」的有效期,只到服务端下一次改配置为止。
开源让社区能看到代码——ZCode 开源当天就被扒出凭据弱加密,证明了它的价值。但你运行的二进制是否等于仓库里的代码(构建可复现吗)、官方插件开不开源、服务端下发的配置和 prompt 是什么,这些都在「开源」的照明范围之外。ZCode 的开源仓库抹平了全部提交历史、锁了 PR 关了 Issue、311 个遥测文件在开源版被「强制关闭」而非删除——开源是审计的起点,不是信任的终点。
6. 大模型层的合规余震:出境、留存与例外条款
把镜头从工具拉高到模型层,还有三个普遍问题。其一,数据主权与出境:ZCode 的「新加坡主体收数据、北京主体签合同」并非孤例,跨国 AI 服务的实体架构普遍复杂,Trae 的遥测同样流向海外域名;对企业用户而言,这直接触发《个人信息保护法》《数据安全法》的出境评估义务,而多数开发者签下服务协议时对此一无所知。其二,留存的例外条款:即便厂商与模型方签了零数据留存(ZDR)协议,滥用检测类的风险分类器通常保留「触发即存储供调查」的例外——Cursor 的数据使用页对此有明确披露,这是行业通行做法,也是「零留存」宣传语下的固定注脚。其三,声明与架构的落差:「用完即删」「不用于训练」在外部均不可验证,除非配合可复现构建、密钥本地化、访问日志与合同审计权。合规文本追不上工程现实,是这一批事件共同的背景音。
五、风险有多大:从个人 Key 到企业商业秘密
对个人开发者,风险是乘法关系。整仓快照带走的 .git 历史里有你删过的密钥、内网地址和未发布分支;本地凭据的弱加密又让「偷到一份备份」升级为「解出全部 API Key 与订阅 token」。两件事叠加,一台被植入普通恶意软件的开发机、一份同步到网盘的家目录备份、一块二手 SSD,都可能同时泄露你的代码资产和你为所有模型厂商付费的凭据。
对企业,承明科技的函件已经把风险清单写全了:项目完整源代码、系统架构、版本控制全量历史、数据库口令、云服务凭证、员工个人信息——每一项都对应不同的法律科目(商业秘密、网络安全、个人信息保护、数据出境)。更棘手的是举证与追偿:外部研究者能证明「客户端发了数据」,却无法进入厂商服务器验证「数据被删了没有、私钥谁在保管、有没有被访问下载」。信息不对称决定了企业维权只能像承明那样,把删除证明、操作日志、责任主体逐项写进函件——这封「法函字第 1 号」大概率会成为国内同类纠纷的模板文件。
按「历史已泄露」的最坏假设处理:①轮换一切可能进过仓库的凭据——不只是当前代码里的,包括 Git 历史中提交过又删掉的、.env 与 CI 配置里的、以及保存在工具本地的各家模型 API Key;②向厂商官方渠道查询你的项目是否曾被服务端接收、索取删除记录;③检查 .git/config 与 reflog 可能暴露的内网信息,评估是否需要调整内部域名与访问策略。密钥轮换的优先级高于一切等待厂商答复的动作。
六、行动清单:把红线划在自己手里
个人开发者五步:第一,把「敏感项目不进云端 AI 工具」定为默认,确需使用时优先本地模型或自托管方案;第二,用好忽略机制(.gitignore 之外,配置 .cursorignore 一类工具级忽略清单,并用「查看已索引文件」核对实际范围);第三,密钥一律走系统钥匙串或专用 secret manager,不写进代码、不交给工具的自带存储,配 pre-commit 扫描兜底;第四,给可疑工具上网络侧监控——mitmproxy 抓包、Little Snitch/OpenWrt 看流量基线,异常连接一目了然;第五,必要时用文件系统锁(chflags uchg / chattr +i)或防火墙域名黑名单从系统层面切断特定链路,软件里关不掉的,就用操作系统关掉。
企业团队六条:①建立 AI 编程工具白名单与版本冻结机制,未经评估的工具与「静默大版本热更新」都视为供应链变更;②采购时把关键承诺合同化——上传数据范围、密钥归属、留存周期、删除 SLA、数据出境路径、审计权,口头与页面声明不算数;③优先选择可私有化部署或提供企业级 ZDR 协议的方案,敏感仓库物理隔离;④把开发机纳入 DLP 与出口流量基线监控,AI 工具的域名单独建档;⑤密钥治理前置:secret manager + 提交扫描 + 定期轮换演练,让「历史里有密钥」这件事本身变少;⑥准备事件预案——发现异常上传时的取证流程(本地日志、抓包、清单存档)、密钥轮换顺序和对厂商的函件模板。
| 选型时要问的问题 | 怎么验证 |
|---|---|
| 代码离开本机的完整清单是什么? | 要求书面回答:推理上下文、索引、遥测、快照各走哪些域名;自己抓包对账 |
| 每个开关分别管「发送、留存、训练」哪一道闸? | 逐项追问三道闸;只回答「不训练」的按最低档理解 |
| 加密数据的密钥在谁手里? | 能否本地持钥 / 端到端;「服务端下发公钥」视为服务端可读 |
| 客户端与开源仓库是否一致? | 是否可复现构建、插件是否开源、是否保留完整提交历史 |
| 服务端能否远程改变客户端行为? | 问清远程配置、热更新与灰度 flag 的范围和审计日志 |
| 删除如何证明? | 留存策略文档、删除凭证、第三方审计频率与合同审计权 |
结语:信任要靠架构,不靠声明
回看这 72 小时,值得肯定的部分并不少:厂商道歉的速度、修复的速度、开源与引入第三方审计的动作,都比多数前例更快更实。但这场风波真正的教训在于——「我们不会滥用数据」是声明,「我们无法滥用数据」才是架构。默认最小化采集、密钥留在用户侧、开关语义与数据闸门一一对应、删除可被外部验证:四条里每少一条,用户能依靠的就只剩厂商的自觉,而自觉在增长压力面前从来靠不住。这不是对某一家公司的道德判断,而是对一个行业激励结构的客观描述——只要真实编码轨迹仍是最稀缺的训练燃料,下一次「静默上传」就仍在某个 sidecar 里排队等待实例化。
对开发者,结论朴素得近乎老派:把敏感资产的红线划在自己手里,用系统级手段执行它;对厂商,160 万次阅读和一封特急函已经把话说完了——中国的开发者社区第一次用如此专业的取证、如此快的节奏完成了一场对 AI 工具的公开审计,而且它显然不会是最后一次。工具没有原罪,越线才有。谁先把「无法作恶」写进架构,谁才配得上下一个一百万开发者。
