Hay un archivo de 313 MB en tu disco. Lo escribió un programa que instalaste tú, con datos tuyos, en tu carpeta personal. Y no lo puedes abrir: la mitad de la llave que lo cierra nunca bajó a tu máquina.
El cifrado no te protegió a ti.
Te separó de lo tuyo.
Setecientos megas sin explicación
El 18 de septiembre de 2026, un desarrollador que firma ferstar —una persona con un blog, no una firma de seguridad— notó que una carpeta crecía sin motivo. Lo escribió así: "~/.zcode was taking up over 700MB."
ZCode es el cliente de escritorio de código con IA de Z.ai —Zhipu—, construido sobre GLM-5.3 y empaquetado en Electron: su app.asar se desarma en una tarde.
Dentro de la carpeta había un archivo cifrado de 313 MB atascado en pendientes, con el nombre de un proyecto comercial del autor y un contador: "failureCount": 564. El repositorio no era un juguete: "The repository totaled 10GB; minus dependencies, the remaining 345MB was almost entirely core intellectual property."
Es la misma escena de cli.js.map: alguien mirando un archivo que pesaba demasiado. Allá el fabricante se filtró solo; acá se lleva lo tuyo.
El blog de ferstar avisa que sus artículos los redacta una IA, y en Hacker News hubo quien pidió pruebas más allá de un sitio escrito por Claude. No sobrevivió a las réplicas.
El atajo
UpXuu reconstruyó la cadena de funciones desde el paquete descompilado, y el primer eslabón dice lo esencial: sendPrompt → captureBeforePrompt → … → uploadObject. Arranca cuando preguntas: una sola sesión activa llegó a 62 eventos de captura.
En cada consulta, sin condición, el cliente pide credenciales a zcode.z.ai; si el servidor las entrega, recolecta. La respuesta trae la Object Key y la clave pública RSA de ese envío. Después el bulto va directo a Alibaba Cloud, sin tocar los servidores de negocio de Zhipu.
Y la pieza que nadie escribe por accidente: "只要命中根 .git 或内部目录,直接返回 include: true,后续的敏感文件名、文件大小、二进制检查全部跳过". El filtro descarta los archivos comunes de más de 1 MiB; si la ruta cae dentro de .git, se incluye y se saltan todas las revisiones.
Por eso el 86,6%.
De los 345 MB, el código y la documentación —lo único que un asistente necesita para asistirte— son 46,2 MB. El 13,4%.
No se lleva solo tu código. Se lleva tu historia: los objetos de todos tus commits, el caché de LFS, los reflogs, las ramas que nunca empujaste a ningún remoto. Quien limpia su historial borra la credencial del árbol actual, no del objeto viejo. Y el objeto viejo viaja.
El cliente intentó subir esos 313 MB y falló 564 veces; nadie dice por qué. Lo que sí salió, medido: "A separate, tiny public-repo workspace did: 538 files, about 15KB after compression and encryption, status accepted by the server."
Quince kilobytes, con acuse. La tubería funcionaba.
Los dos interruptores
La interfaz ofrecía dos. Ninguno interrumpía nada.
«Optimize Experience»: "Only controls whether data is authorized for model training. Snapshot capture and upload still run". «Repo Snapshot Indexing»: "Only controls whether the server indexes uploaded snapshots. Local packaging and upload continue uninterrupted".
Uno decide si te entrenan con eso. El otro, si el servidor ordena lo que ya recibió. ¿Cuál decía algo sobre no mandarlo?
ferstar no lo dedujo: lo probó. "Disabling 'Optimize Experience' and 'Repo Snapshot Indexing' still packaged and attempted direct OSS uploads".
El mismo día, 冯若航 (Vonng) repitió el análisis forense en su macOS, con «仓库快照索引» apagado todo el tiempo, y encontró cuatro instantáneas: en una, .git era el 93,9%. En el estado de otra estaba escrito lastAcceptedManifestHash, el campo que el cliente solo escribe cuando la subida devuelve OK. Él lo presenta como inferencia.
No es que el interruptor controlara otra cosa. Estaba apagado y pasó igual.
"Bottom line: as long as you are logged in, this background pipeline is permanently active, and no UI setting can turn it off."
La política de privacidad dice que ZCode recoge texto, archivos y código "submitted during conversations". Enviados. Un acto del usuario. Y sobre lo otro: "there is not a single mention of silently packaging and uploading entire workspaces and full Git histories."
Quien queda PAILA no es el que ignoró la advertencia. Es el que leyó la política, encontró los dos interruptores y los apagó.
Julio, otra empresa, el mismo guion
Nada de esto era inédito. En julio de 2026, cereblab interceptó el tráfico de Grok Build CLI y encontró que el cliente de xAI subía "a complete v2 git bundle". xAI lo apagó con dos banderas del servidor, sin aviso de seguridad y sin registro de cambios. Después publicó el código completo bajo Apache 2.0, y el resultado quedó documentado: "the exfiltration code is still present. It's disabled by the server-side disable_codebase_upload flag, not removed."
En abril escribimos sobre el jardín cerrado y la lección fue usar clientes abiertos. En Hacker News la frase vuelve con otro filo —"Never use a Harness if it is not opensourced."—, y Grok ya demostró que no alcanza. El código estaba abierto. La bandera estaba en el servidor.
Que es donde estaba acá. Z.ai dijo el 18 que ya estaba arreglado; ZCode 3.14.0 salió el 19, un día después. Si el arreglo llegó antes que el cliente nuevo, no estaba en el cliente.
Sobre la versión afectada, después de la disculpa, UpXuu registró que la tubería seguía entera —captureBeforePrompt, RepoWikiGenerator, el cifrado de sobre—, "理论上可经服务端配置重新启用": reactivable en teoría por configuración del servidor. Un equipo tercero corrió esa versión con marcas canario y no reprodujo nada. Las dos cosas son ciertas, y juntas dicen una: no lo desarmaron, lo apagaron desde afuera.
El sobre
El contenido se cierra con una clave simétrica efímera, AES-256-CTR, envuelta con RSA-OAEP-SHA256 usando la clave pública que manda el servidor. Y entonces: "the corresponding private key never touches your machine."
"Only Zhipu's backend holds the key to unlock it."
Tu archivo. Tu disco. Tu proyecto comercial adentro. Y del otro lado del sobre, nadie que se apellide como tú. Una llave que solo sirve de un lado tiene un solo propósito, y lo escribió ferstar: asegurarse de que el servidor pueda leer tu código cuando quiera.
La respuesta oficial llegó el mismo 18 de septiembre —según ferstar, a las 17:44— por el grupo de chat oficial de usuarios. Esta redacción no encontró el comunicado en ningún canal propio en inglés. El problema, dijo Z.ai, venía del «indexado de la base de código», que existe "to support session checkpoint recovery, historical version rollback, and Repo Wiki." Admitió que venía activado por defecto, prometió abrir el código, compensó con una recarga extra de la cuota semanal y garantizó que el dato "会立即销毁,不会保存": se destruye al instante.
ferstar puso el dedo en la juntura: "The claimed 'checkpoint restore' contradicts 'destroyed immediately' — what exactly was retained in the cloud?" Si se destruye al instante, ¿qué restaura la restauración?
全天候科技 agregó otra: la documentación oficial de Repo Wiki dice que generar la wiki no lee el historial del proyecto. ¿Por qué, entonces, el 86,6% del paquete era historial?
El único rastro del caso en el registro de cambios encabeza los catorce «Bug Fixes» de la 3.14.0: "Fixed an issue with abnormal uploads in the repository wiki". En la misma lista, las fallas de inicio de sesión y el ancho del menú de modelos. Ni una palabra sobre .git, ni sobre instantáneas, ni sobre los interruptores. Encabezar la lista no lo explica: lo normaliza.
Atribución
Perpetrador: Z.ai / Zhipu. Lo admitió la empresa: venía activado por defecto. La disculpa salió por un grupo de chat. La compensación, una recarga de cuota.
Cómplices: dos interruptores que no interrumpían, y una política construida alrededor del verbo submitted —enviado, voluntario— para un producto que empaquetaba solo. Y el consenso de la categoría: que un agente lea todo el espacio de trabajo es normal, y nadie desarma el .asar para ver qué hace con esa lectura.
Falla sistémica: el plano de control vive en el servidor. Por eso un cliente se «arregla» el mismo día sin publicar una versión, y se puede volver a encender igual de rápido. El 8 de septiembre, la NSA, CISA y el FBI habían nombrado a Z.AI entre seis empresas chinas que destilan modelos estadounidenses. Ninguna fuente lo conecta con esto.
Falta lo que no hay: ninguna víctima con daño demostrado, ninguna credencial robada, ningún repositorio filtrado. Hay capacidad demostrada, artefactos en discos ajenos —en V2EX varios encontraron sus instantáneas y varios no— y al menos un envío que el cliente registró como aceptado: a quien tuviera sesión iniciada y un repositorio que cupiera.
Dos días después de la divulgación, 太原澄明科技 le mandó a Zhipu una carta legal por código fuente, contraseñas de bases de datos y credenciales de nube, exigiendo borrado comprobable de servidores, cachés y copias de respaldo. ferstar había preguntado cómo se prueba un borrado desde afuera; alguien mandó la pregunta con abogado.
Z.ai prometió abrir el código. ferstar ya preguntó lo único que importa: si publicarán el proceso de subida que fue cazado, o solo el último commit ya limpio.
Lo que nadie va a poder leer es lo que ya está del otro lado. Sigue ahí, en un sobre impecable, cerrado con una llave que funciona en una sola dirección. ¿En qué momento aceptamos que «cifrado» dijera de quién es la información, y no quién puede leerla?