Incidente de instantáneas de Git de ZCode: qué pueden ver, subir y recordar los agentes de programación con IA

Eva Wong es la Redactora técnica y manitas residente en ZimaSpace. Una geek de toda la vida con pasión por los homelabs y el software de código abierto, se especializa en traducir conceptos técnicos complejos en guías accesibles y prácticas. Eva cree que el autoalojamiento debe ser divertido, no intimidante. A través de sus tutoriales, empodera a la comunidad para desmitificar las configuraciones de hardware, desde construir su primer NAS hasta dominar los contenedores Docker.

El incidente de carga del repositorio de ZCode es más importante que una sola herramienta de programación. Expone una cuestión de seguridad que los desarrolladores deben responder cada vez más antes de dar a un agente de IA acceso a un proyecto: ¿el “acceso al repositorio” significa el archivo actual, el árbol de trabajo o años de historial de Git?

Esa distinción es importante porque .git puede contener información que ya no es visible en la base de código actual, incluidos secretos eliminados, versiones antiguas del código fuente, reflogs, recursos de LFS y el historial de ramas locales. ZCode afirma que el comportamiento de carga afectado se ha corregido, pero el incidente deja una lección duradera: los agentes de programación de IA necesitan límites de datos explícitos, no solo permiso para “acceder al repositorio”.

¿Qué ocurrió realmente con ZCode?

El 18 de septiembre de 2026, el desarrollador ferstar publicó una investigación de ingeniería inversa de ZCode 3.12.3 tras observar archivos inesperadamente grandes en el directorio de datos locales de la aplicación.

Según la investigación original, el cliente creaba instantáneas cifradas del espacio de trabajo que podían incluir archivos de código fuente, además de .git, objetos de Git LFS, reflogs y metadatos del repositorio. El cliente también contenía una canalización para obtener credenciales de carga y enviar archivos cifrados a Alibaba Cloud OSS.

Posteriormente, ZCode reconoció las cargas de datos de repositorios asociadas con la indexación de bases de código y Repo Wiki, se disculpó, afirmó que el comportamiento se había corregido y anunció planes para realizar revisiones de código abierto y de terceros. La cobertura contemporánea reprodujo los puntos principales de la respuesta de ZCode.

Afirmación Pruebas
Las versiones antiguas de ZCode creaban instantáneas amplias de los repositorios Respaldado por la ingeniería inversa y las pruebas de instantáneas locales
Existía una canalización de carga Respaldado por el comportamiento del cliente sometido a ingeniería inversa
Un repositorio pequeño llegó correctamente al servicio Verificado mediante la prueba de seguimiento del investigador
El repositorio comercial de 313 MB se cargó correctamente No: esa carga falló
El ZCode actual sigue utilizando la misma canalización Sin pruebas; el investigador informa que se eliminó la ruta antigua

Esta es la primera laguna informativa importante que hay que cerrar: el incidente fue real, pero algunos resúmenes virales exageraron lo que se transfirió correctamente.

¿Realmente se cargó el repositorio privado de 313 MB?

No.

La instantánea del proyecto comercial contenía aproximadamente 42.000 archivos y produjo un archivo cifrado de unos 313 MB. Según la actualización del investigador del 19 de septiembre, permaneció en un pendiente estado tras 564 intentos fallidos porque superó el límite de carga. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))

Un repositorio público más pequeño e independiente sí llegó correctamente al servicio. Contenía 538 archivos y produjo una carga útil cifrada mucho más pequeña.

Repositorio Resultado observado
Repositorio comercial de 313 MB Empaquetado localmente, se intentó repetidamente y la carga falló
Repositorio público pequeño Aceptado correctamente por el servicio remoto

Por lo tanto, la conclusión correcta no es “se subió cada repositorio de ZCode”. Es que el cliente antiguo contenía un mecanismo funcional de carga de repositorios cuyo éxito real dependía de la instantánea.

Por qué el directorio `.git` es la parte más importante de este incidente

En la gran instantánea del investigador, la mayor parte de la carga útil no era código fuente actual.

Contenido de la instantánea Proporción aproximada
.git/lfs/ 56.8%
.git/objects/ 29.6%
.git/logs/ 0.2%
Código fuente y documentación actuales 13.4%

Eso significa que aproximadamente el 86.6% de la instantánea procedía de .git. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))

Esto cambia por completo la interpretación de seguridad.

Un agente de IA que lea el árbol de código fuente actual puede ver lo que el desarrollador decide conservar hoy. Acceder al historial de Git puede revelar lo que el desarrollador creía haber eliminado.

Entre las posibles exposiciones históricas se incluyen:

  • archivos de código fuente eliminados
  • claves de API o tokens antiguos
  • endpoints internos anteriores
  • funciones abandonadas
  • configuración histórica
  • actividad de ramas locales
  • estados exclusivos del reflog
  • activos LFS históricos de gran tamaño

La documentación del reflog de Git explica que los reflogs registran valores anteriores de referencias locales. Esos registros pueden existir localmente incluso cuando el historial correspondiente nunca se ha enviado a un repositorio remoto.

Esto nos proporciona una regla de seguridad útil:

“Leer mi proyecto” y “leer mi historial de Git” deberían ser permisos independientes.

Por qué los secretos eliminados aún pueden existir después de quitarlos del código

Eliminar una credencial del archivo más reciente no necesariamente la elimina de Git.

Un desarrollador puede confirmar accidentalmente una clave de API, eliminarla en la siguiente confirmación y ver un archivo actual completamente limpio. El blob anterior aún puede seguir siendo accesible a través del historial del repositorio.

La guía de GitHub sobre la eliminación de datos confidenciales recomienda explícitamente revocar o rotar las credenciales expuestas antes de reescribir el historial.

Ese orden es importante:

  1. Invalida la credencial.
  2. Elimina el historial confidencial cuando corresponda.
  3. Evita que el secreto vuelva a confirmarse.

Para los agentes de programación con IA, esto significa que una función consciente del historial puede acceder a datos que una vista normal del editor ya no muestra.

También explica por qué un agente de solo lectura no supone automáticamente un riesgo bajo. El acceso de solo lectura aún puede filtrar información valiosa si el alcance de su sistema de archivos es demasiado amplio o si el contenido recuperado se envía a un modelo remoto.

El contexto del modelo, la telemetría, el entrenamiento y las cargas del repositorio no son lo mismo

Otra lección importante es que un único interruptor de «privacidad» no puede representar todos los tipos de flujo de datos que puede tener una herramienta de programación con IA.

Flujo de datos Propósito habitual
Contexto de inferencia Enviar el código necesario para responder a la tarea actual
Telemetría Medir fallos, fiabilidad y uso
Datos de entrenamiento del modelo Mejorar futuros modelos o el comportamiento del producto
Índice del repositorio Buscar y comprender un proyecto de manera más eficiente
Instantánea en la nube Conservar un estado más amplio del espacio de trabajo
Sincronización / copia de seguridad Restaurar datos entre sesiones o dispositivos

La versión afectada de ZCode es importante porque el investigador informó de que desactivar su opción de optimización/entrenamiento no desactivaba la canalización independiente de instantáneas. El informe también afirmó que, en esa versión, el interruptor de indexación de instantáneas del repositorio no impedía los intentos de empaquetado y carga. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))

Esto conduce a una regla que se aplica mucho más allá de ZCode:

«No entrenar con mis datos» no significa «no transmitir mis datos».

Un modelo en la nube sigue necesitando contexto para la inferencia. La telemetría puede viajar a través de otro endpoint. La sincronización puede conservar otra copia. La indexación del repositorio puede tener su propia ruta de datos.

La misma distinción aparece cuando un agente de IA local utiliza herramientas en la nube: la privacidad depende de los datos exactos que cruzan el límite, no simplemente de dónde se ejecuta el proceso principal del agente.

El cifrado no responde a la pregunta de privacidad más importante

La instantánea de ZCode afectada se cifró antes de subirse.

El informe de ingeniería inversa describe un cifrado AES-256-CTR para el archivo y un envoltorio RSA-OAEP-SHA256 para la clave simétrica. El servicio proporcionó la clave pública RSA, mientras que la clave privada correspondiente no se almacenó localmente. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))

Eso protege los datos de manera diferente al cifrado de extremo a extremo controlado por el usuario.

Protección Qué significa
TLS / cifrado de transporte Protege los datos mientras atraviesan la red
Cifrado en reposo en la nube Protege los bytes almacenados frente a algunas amenazas de la infraestructura
Clave controlada por el proveedor El servicio puede conservar la capacidad técnica de descifrar
Clave de extremo a extremo controlada por el usuario El servicio no posee la clave de descifrado necesaria

Por lo tanto, decir que «el repositorio estaba cifrado» es incompleto.

La pregunta más importante es:

¿quién puede descifrarlo?

This same principle applies to private RAG, cloud backup, AI memory, and any system that claims data is protected because it is encrypted.

Este mismo principio se aplica a RAG privado, copias de seguridad en la nube, memoria de IA y cualquier sistema que afirme que los datos están protegidos porque están cifrados.

¿Cuánto acceso al repositorio necesita realmente un agente de programación?

Los agentes de programación necesitan legítimamente más contexto que el autocompletado tradicional. Una refactorización de todo el repositorio puede requerir muchos archivos. Un agente de depuración puede necesitar pruebas, metadatos de dependencias, estado de Git y salida de compilación.

Pero «el agente puede necesitar un contexto amplio» no implica que «todas las funciones deban recibir cada byte del repositorio». Alcance de los datos
Valor predeterminado sensato Archivo actual
Permitir para tareas relevantes Archivos de código fuente referenciados
Permitir Árbol de código fuente completo
.gitignoreDepende de la tarea -archivos excluidos
Excluir .env Bloquear
.git / credenciales objetos
Referencias de registro Excluir de forma predeterminada
Caché de Git LFS Excluir salvo que sea necesario
Credenciales de SSH o de la nube Bloquear
Instantánea remota completa Consentimiento explícito

Esta es una versión centrada en el acceso a los datos del mismo principio utilizado en un límite de confianza de ejecución de herramientas: la capacidad del modelo para solicitar algo no debería otorgarle automáticamente autoridad para acceder o exportar todo lo que haya cerca.

En el caso de los agentes de programación, necesitamos dos límites independientes:

  • Límite de acciones: ¿qué puede modificar o ejecutar el agente?
  • Límite de datos: ¿qué puede leer o enviar el agente?

Un agente sin permiso de escritura aún puede causar una grave exposición de la privacidad si sus permisos de lectura y red no están restringidos.

¿Qué cambió ZCode después del incidente?

El incidente no debe describirse como si se supiera que el mismo comportamiento existe en las versiones actuales de ZCode.

En una inspección posterior de ZCode 3.14.0, el investigador informó que el componente auxiliar de carga anterior había sido eliminado y que el antiguo endpoint de credenciales devolvía 404. La ruta inspeccionada conservaba la funcionalidad de puntos de control locales sin el mecanismo anterior de carga remota. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))

La documentación actual de Repo Wiki también describe un límite de datos mucho más reducido.

Indica que el contexto de Wiki excluye:

  • .git
  • directorios de dependencias
  • salida de compilación
  • cachés
  • estado de ejecución local
  • compatible .gitignore exclusiones
  • archivos de configuración sospechosos que contengan información confidencial
  • destinos de enlaces simbólicos

La salida de Repo Wiki está documentada como datos locales de la aplicación, en lugar de contenido escrito de vuelta en el repositorio.

Esto difiere sustancialmente del comportamiento de instantáneas informado en la versión 3.12.3.

¿Es suficiente con que un agente de programación sea de código abierto para que sea privado?

No.

El código abierto puede facilitar la auditoría de un cliente, pero una aplicación de código abierto aún puede enviar código fuente a modelos en la nube, cargar datos de telemetría, sincronizar el estado o depender de almacenamiento controlado por el proveedor.

La lista de comprobación más útil es:

Pregunta Propiedad de seguridad
¿Qué puede leer el agente? Alcance de los datos locales
¿Qué puede salir de la máquina? Límite de salida
¿Por qué se transmite? Limitación de la finalidad
¿Durante cuánto tiempo se conserva? Persistencia
¿Quién controla las claves de cifrado? Autoridad de descifrado
¿Se puede desactivar el comportamiento? Control del usuario
¿Pueden verificarlo personas externas? Auditabilidad

Por eso una arquitectura de IA privada se define más por su flujo de datos que por el hecho de que su licencia de software sea de código abierto.

¿Cómo deberían auditar los desarrolladores un nuevo agente de programación con IA?

Los desarrolladores no necesitan aplicar ingeniería inversa a cada aplicación, pero un agente nuevo no debería recibir un repositorio comercial sensible como primer entorno de prueba.

  1. Lee la documentación sobre el tratamiento de datos. Separa la inferencia, la telemetría, el entrenamiento, la indexación, la sincronización y las copias de seguridad.
  2. Comprueba las reglas de exclusión. Busca específicamente .git, .env, archivos ignorados, dependencias, credenciales y enlaces simbólicos.
  3. Empieza con un repositorio desechable. Usa primero código no sensible.
  4. Inspecciona el almacenamiento local de la aplicación. Las cachés o instantáneas grandes e inesperadas pueden revelar un alcance de datos oculto.
  5. Observa el tráfico saliente. Los registros del cortafuegos, DNS, proxy o enrutador pueden identificar servicios remotos.
  6. Usa archivos señuelo inofensivos. Comprueba si archivos no relacionados entran en el contexto del modelo o de carga.
  7. Concede primero los permisos más limitados. Amplíalos solo cuando una tarea específica lo requiera.

Aquí también resulta útil el diseño de agentes con privilegios mínimos, siempre que «solo lectura» se combine con rutas limitadas y datos salientes controlados, en lugar de una visibilidad ilimitada del repositorio.

Qué debería hacer de forma diferente un agente de programación con prioridad local

La prioridad local no significa que todas las tareas deban ejecutarse sin conexión.

Significa que, de forma predeterminada, los datos locales permanecen dentro del límite de confianza local y que la transmisión externa es deliberada, no incidental.

Principio de prioridad local Comportamiento preferido
Indexación del repositorio Mantén localmente los símbolos, las inserciones y los metadatos siempre que sea práctico
Contexto del modelo remoto Envía solo el código relevante para la tarea
Historial de Git Exclúyelos, salvo que la tarea necesite explícitamente el historial
Secretos Filtra antes de construir el contexto
Carga remota Muestra el alcance y solicita consentimiento explícito
Consentimiento para el entrenamiento Sepáralo del permiso de inferencia
Repositorios sensibles Ofrece rutas de modelo e indexación completamente locales
Dependencia de la red Documenta qué deja de funcionar sin conexión

Este principio es más amplio que la programación. Un flujo de trabajo de IA verdaderamente local debe mantener localmente su ruta de datos crítica de principio a fin; instalar un modelo localmente no basta si las inserciones, la indexación, la autenticación o el procesamiento de archivos dependen silenciosamente de un servicio remoto.

En los sistemas híbridos, el patrón más sólido consiste en mantener los archivos privados detrás de un servicio local y exponer únicamente el contexto mínimo necesario a las herramientas remotas autorizadas. Es el mismo enfoque que se utiliza al diseñar un agente que utiliza servicios en la nube sin exponer todo el sistema de archivos local.

La lección más importante: el acceso al repositorio es un permiso de seguridad

La lección duradera de ZCode no es «no uses nunca agentes de programación en la nube». Es que el acceso al repositorio se ha convertido en un permiso de seguridad por derecho propio.

Un agente de programación moderno puede combinar:

  • lectura del proyecto completo
  • conocimiento de Git
  • ejecución de terminal
  • acceso al navegador
  • modelos remotos
  • tareas en segundo plano
  • memoria a largo plazo
  • edición autónoma de archivos

Eso significa que los desarrolladores deben revisar más aspectos que los comandos que un agente puede ejecutar.

También deben preguntarse:

  • ¿Qué archivos puede observar?
  • ¿Hasta qué punto del historial puede acceder?
  • ¿Qué parte de esos datos sale de la máquina?
  • ¿Qué servicio lo recibe?
  • ¿Durante cuánto tiempo se conserva?
  • ¿Quién puede descifrarlo?

Para los agentes de programación de IA, la privacidad ya no consiste simplemente en si el modelo entrena con tu código. Se trata de si el límite de datos del agente coincide con la tarea que realmente le pediste realizar.

Preguntas frecuentes sobre el incidente de carga del repositorio de ZCode

¿Cargó ZCode el repositorio privado completo de 313 MB del investigador?

No. El investigador informó de que la instantánea del proyecto comercial de gran tamaño se empaquetó y se puso repetidamente en cola para cargarse, pero la carga falló debido a su tamaño. Un repositorio público independiente y más pequeño fue aceptado correctamente por el servicio.

¿Puede `.git` contener secretos que ya no están en el código actual?

Sí. Los objetos de Git y los commits históricos pueden conservar versiones anteriores de los archivos después de que se haya eliminado contenido confidencial del árbol de trabajo. Los reflogs también pueden contener un historial local de referencias que quizá nunca se haya enviado a un repositorio remoto.

¿Desactivar el entrenamiento de IA impide que un agente de programación cargue código?

No necesariamente. El entrenamiento, la inferencia, la indexación del repositorio, la telemetría, la sincronización en la nube y las copias de seguridad son flujos de datos independientes. Desactivar el consentimiento para el entrenamiento del modelo no desactiva automáticamente las transferencias de datos requeridas por otra función en la nube.

¿Ha solucionado ZCode el problema de la instantánea del repositorio?

ZCode afirma que el problema se ha solucionado. El investigador original informó de que la antigua ruta de carga remota no estaba presente en la versión 3.14.0, mientras que la documentación actual de Repo Wiki excluye explícitamente .git, las dependencias, los artefactos de compilación, las cachés y varias categorías de archivos confidenciales del contexto del modelo Wiki.

¿Un agente de programación de IA de código abierto es privado automáticamente?

No. El código abierto mejora la auditabilidad, pero la privacidad sigue dependiendo de qué archivos lee la herramienta, qué datos salen del dispositivo, qué servicios en la nube los reciben, durante cuánto tiempo se conservan y quién controla las claves de cifrado.

Centro de Tecnología e IA

Más para leer

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.