Security1 publisher2 min readPublished
ZCode uploaded whole workspaces to Aliyun OSS under a key only its server holds
A researcher at blog.ferstar.org found Zhipu's AI coding desktop app packaging .git history, reflogs and LFS caches into encrypted archives bound for Aliyun OSS, with the private key kept in the vendor's cloud.
The Watch · Security desk
What happened
- A researcher at blog.ferstar.org found that Zhipu's ZCode desktop app packaged whole workspaces, including complete .git history, reflogs, LFS asset cache and global app configs, and uploaded them to Aliyun OSS.
- Encryption used an RSA public key the server delivered at upload time, with the private key held only in the cloud, leaving hundreds of megabytes of ciphertext that neither the user nor the client could open.
- ZCode posted an official statement on X at 09:23 on September 21, 2026 and published what it called its open-source core at GitHub zai-org/ZCode under Apache-2.0.
- That repository holds two commits, an empty one and a 6,973-file dump of 1.03 million lines, with the internal development history flattened, pull requests locked and issues closed.
- Client v3.14.3 shipped on the evening of September 23 with a matching public commit, and unpacking its app.asar shows zero occurrences of the repoSnapshot logic.
Compiled by The WatchSomething wrong?How this is made
Why it matters
- exposure The unit uploaded was the repository plus the developer's global app configs, so a single signed-in session moved far more than whatever file the model had been asked to read.
- constraint Anyone doing incident response on an affected laptop can measure the archives and nothing more, because only the party that collected them can read them.
- contradiction The upload pipeline was captured in the shipped client, yet searches of the published code return zero matches for it, and the flattened commit history offers no diff that dates its removal.
- decision Allowing the app means trusting that a compiled binary matches a published tree; the read-only directory lock is the one control that does not depend on that trust.
The captured path is short. The client asks `/api/v1/snapshot/upload-credential` for credentials, packages the workspace with AES-256-CTR, and PostObjects the result straight to Aliyun OSS [4]. The investigation started as disk cleanup, after `~/.zcode` passed 700MB [1].
For this to work, the app had to hold a read across the whole workspace and a logged-in session to the vendor's cloud. ZCode held both, and the snapshot ran whenever the user was signed in [2].
The September 23 release gave the first chance to compare a shipped build against a published commit. The author audited the 282 files changed in `328c1a0` and found the upload-credential endpoint and the AES-256-CTR packaging still absent [12]. `gitCheckpointService.ts` does its diffing through the local Git CLI with no cloud calls [13]. On the machine, process logs and `~/.zcode/v2/checkpoints/` showed the workspace going unscanned and unpackaged, with no new `.enc` archives [16]. Those 282 files are about four percent of the 6,973 published in the initial dump [1].
The post stops short of calling the binary clean. "matching version tags does not guarantee a 1:1 identical match between proprietary compiled binaries and public source code", the author wrote, and recommends keeping the ZCode directory read-only as the baseline defense [17][18].
Most of the new code in 3.14.3 is remote control. It adds IM bots for WeCom, Feishu, DingTalk and Telegram, plus workflow execution optimizations [14]. An agent that accepts instructions over four messaging platforms deserves the same traffic capture that found the snapshot path.
The vendor's own account is thin in the record. The post references the X statement and the third-party evaluation the company cited without reproducing either [19], and notes that the repository wiki was scrubbed down to a single external Wikipedia reference [10].
What to watch
- Whether Zhipu states how long snapshot uploads ran, how many workspaces were collected, and whether the OSS objects and the cloud-held private key are deleted.
- A byte-level or reproducible-build comparison tying the shipped 3.14.3 binary to commit 328c1a0.
- Whether the new WeCom, Feishu, DingTalk and Telegram control channels in 3.14.3 get the same traffic review as the snapshot path.