ZCode被曝静默打包上传用户完整工作区及Git历史
Inside ZCode: Silently uploading your Git history to the cloud
涉及AI编程工具的数据隐私与合规红线,工程复盘详尽且厂商已介入,做AI应用开发的同学务必关注此类安全边界问题。
Table of Contents Table of Contents I am not a native English speaker; this article was translated by AI. It started with a routine check while freeing up disk space: ~/.zcode was taking up over 700MB. After digging into it intermittently, I confirmed something pretty wild: Whenever you are logged in, ZCode (Zhipu’s official AI coding desktop app) silently packages your entire workspace — complete .git history, LFS asset cache, reflogs, and global app configs — encrypts it, and uploads it directly to Aliyun OSS. Even more ironic: the RSA public key used for encryption is delivered on the fly by the server, while the private key lives exclusively in the cloud. You cannot decrypt that multi-hundred-megabyte ciphertext sitting right on your own disk, and neither can the ZCode client itself. Here is the complete record of the investigation, the evidence chain, and a one-liner defense that permanently shuts it down. ## Update, 2026-09-19 ## # Following widespread community attention after this post, Z.ai released an official statement in their user community on Sep 18 at 17:44 (with tech media like IT Home picking up the story later that evening). This section provides an objective cross-check. The original investigation below remains unchanged. ## What the company said ## # Z.ai posted their statement on Sep 18 at 17:44; public coverage can be found on IT Home. Key points: - The issue came from “codebase indexing”, used for local indexes, session checkpoint restore, and Repo Wiki; - Generating Wiki pages in the cloud “may” trigger an upload of repository data; - After the Wiki is generated, the uploaded data is destroyed immediately and is not stored; - The feature was on by default in its early launch period; some users were affected; the issue “has been fixed”; - ZCode will be open-sourced soon, with third-party review; all users get one extra weekly quota reset. The fact that uploads occurred is no longer contested by Zhipu. What remains in question is the actual upload scope, user toggles, and how anyone outside the company is supposed to verify “destroyed immediately”. ## Reverse Engineering & Local Evidence vs. Official Claims (Old Version 3.12.3 vs. 3.14.0 vs. Official Statement) ## # To prevent confusion between client versions, here is a direct comparison between the affected old version (3.12.3) when caught, the reverse-engineered 3.14.0 release, and the official statement: Dimension | Official Statement (Sep 18 17:44) | 3.12.3 Client Audit (Affected Version) | 3.14.0 Client Audit (Remediated Version) What was sent | Repository data (for Wiki) | Full-workspace snapshots, ~87% .git — objects, LFS, reflogs | Upload pipeline code physically stripped; only local checkpoints remain Trigger mechanism | Wiki page generation “may” upload | Upload sidecar resident with login; captureBeforePrompt (before every prompt) and repo-wiki-update trigger unconditionally | Upload sidecar dismantled; no longer triggers cloud packaging Can you turn it off | No mention of a switch to stop uploads | Disabling “Optimize Experience” and “Repo Snapshot Indexing” still packaged and attempted direct OSS uploads | Code pipeline physically removed Cloud-side handling | Destroyed immediately after generation | Not verifiable from outside (and logically contradicts the claimed “checkpoint restore” feature) | Cloud upload-credential endpoint pulled (returns 404) Retained data | Claims data is not stored post-Wiki | Snapshot of a 538-file public repo accepted by server; retention/decryption rights unaddressed | Whether existing cloud snapshots were physically wiped cannot be verified externally One thing the original post left easy to misread: the 313MB commercial project sat in pending (failureCount: 564) and did not upload successfully. A separate, tiny public-repo workspace did: 538 files, about 15KB after compression and encryption, status accepted by the server. So “did anything actually leave the machine” — yes, at least that one. Someone else reproduced the same directory layout and state files on Windows, including multiple small workspaces with no failure record that look accepted: NodeSeek. Another local cross-check: silencestar. I archived the privacy policy on Sep 18. The page still said it was last updated 2026-06-15, and still did not mention full-workspace snapshots or cloud sync. ## A Few Personal Clarifications ## # - Did the 313MB commercial project actually get uploaded?: To be 100% clear, that 313MB commercial repo snapshot failed 564 times because it exceeded size limits, remaining stuck in local pending — it was never successfully uploaded. I run an OpenWrt router at home; checking connection tracking and traffic flow records confirmed those encrypted chunks never left the local network. - Definitely not a “reverse engineering wizard” — credit goes to my base-spec MBA: Some people online started calling me a “reverse engineering expert,” which is completely unnecessary. The entire trigger was laughably mundane: thanks to Apple’s storage being priced like solid gold, my base-spec 256GB MacBook Air is perpetually starved for disk space. I was freeing up space when I noticed ~/.zcode mysteriously devouring over 700MB. My engineering spider-sense tingled, so I unpacked app.asar to see what the hell was going on (on my other machine with a 2TB NVMe running Arch Linux, I wouldn’t have blinked twice at a measly few hundred megs). Besides, given the state of modern AI, anyone with a coding agent is effectively a reverse engineer now — pull any decent agent off the shelf, feed it this post and the source files, and it’ll break down the entire architecture with flawless clarity. It’s hardly some exclusive black magic; it was just basic engineering curiosity and troubleshooting. - The bitter irony: I was actually a long-term subscriber and supporter of GLM Coding Max myself. The funniest part is that on the evening of Sep 17, I was enthusiastically pitching ZCode to peers in a developer group chat. Less than half a day later, reality hit me right in the face when I caught this silent whole-repo packaging routine myself. ## Does the mitigation still matter ## # Yes. Even though 3.14.0 removed the code and the gateway route returns 404, the desktop client can still receive hot updates. The filesystem lock below remains active as a tripwire. The NodeSeek post has the Windows ACL equivalent. ## Still unanswered ## # - How do you prove “destroyed immediately” from the outside? Have existing cloud-stored encrypted snapshots been physically purged, and who holds private key decryption rights? - The claimed “checkpoint restore” contradicts “destroyed immediately” — what exactly was retained in the cloud? - Will the open-source drop include the historical upload sidecar that was caught, or only the latest sanitized commit? If the repo actually ships, I will write a follow-up against the source. ## The Starting Point: A 313MB Archive Stuck in Pending ## # ~/.zcode is the data root of ZCode. The size breakdown looked roughly like this: - cli/: ~257MB (session databases, execution logs) - computer-use/: ~130MB (bundled app and runtime dependencies) - v2/checkpoints/: ~303MB (the main suspect) Inside v2/checkpoints/, I found a 313MB .enc file alongside a state metadata file: ``` { "workspacePath": "/Users/ferstar/myprojects/", "lastCompressedSize": { "encryptedSizeBytes": 313070842, "workspaceSizeBytes": 345549173 }, "kind": "baseline", "failureCount": 564 } ``` The story was straightforward: - The client scanned my active commercial project, excluded node_modules and a few others, and packaged the remaining 345MB into a 313MB encrypted archive labeled baseline (full snapshot); - It recorded 564 failed upload attempts, leaving it sitting in the local pending/ directory waiting for the next retry.
更进一步:量化金融体系
看懂新闻只是起点——沿量化金融路径,把它变成能交付的工程能力