git status ejecutó su código
El 2 de septiembre de 2026, Manifold Security divulgó GitSpawn: ocho fallos en siete agentes de codificación de línea de comandos donde el propio .git/config de un repositorio ejecuta un comando en la máquina del desarrollador. El agente lanza git status para saber en qué rama está, git actualiza su índice, y el comando elegido por el repositorio se ejecuta con los privilegios del usuario que ha iniciado sesión, fuera del sandbox, antes del aviso de confianza y, en una de las herramientas, antes incluso del login. Sin prompt, sin llamada a herramienta, sin turno del modelo. Bromure Agentic Coding no parchea ese camino. Cambia la máquina a la que ese camino lleva.
No escribiste nada y no aprobaste nada. El agente no había terminado de arrancar y, en una de estas herramientas, ni siquiera habías iniciado sesión. Una carpeta que alguien te envió ejecutó un comando en tu nombre, y fue git quien lo ejecutó.
Un colaborador externo termina un trabajo y te envía un zip del directorio del
proyecto en una carpeta compartida. Lo descomprimes, entras con cd y arrancas
tu agente de codificación para orientarte. El agente empieza preguntándole a git
qué rama es esta y qué está modificado. Ese es todo el exploit.
El 2 de septiembre de 2026, The Hacker News informó de una divulgación de Manifold Security que cubre ocho fallos en siete agentes de codificación de línea de comandos, publicados bajo el nombre GitSpawn. Entre todas, las herramientas afectadas acumulan cerca de medio millón de estrellas en GitHub, y solo Claude Code ha superado los 77 millones de descargas npm al mes. Cuatro de los ocho seguían ejecutando comandos suministrados por el repositorio cuando Manifold volvió a probarlos el 1 de septiembre.
Un ajuste de rendimiento cuyo valor es un comando
core.fsmonitor es una opción de git pensada para quien tiene repositorios
enormes. En lugar de recorrer todo el árbol para averiguar qué ha cambiado, git
puede llamar a un programa auxiliar externo y preguntárselo. El valor del ajuste
es el comando. Git lo lee del .git/config del propio repositorio y lo
ejecuta cada vez que actualiza su índice, es decir, en git status, en
git diff, en la fontanería en la que se apoya cada herramienta.
Casi todos los agentes que examinó Manifold reúnen el contexto del proyecto
lanzando esos comandos al arrancar, y ninguno de ellos miraba antes el
.git/config. Así que el repositorio nombra el comando y git lo ejecuta. En
palabras de los investigadores, se ejecuta “con todos los privilegios del
usuario que ha iniciado sesión, fuera del sandbox”. OpenAI, en su propio aviso
para la variante de Codex, dijo que el auxiliar “se ejecuta fuera del sandbox de
comandos de Codex y sin un aviso de aprobación del usuario”.
Un git clone no arrastra nada de esto. El clon transfiere objetos y refs, y la
configuración local del repositorio de origen se queda en casa. Así que el
proyecto envenenado tiene que llegarte como archivos, con su directorio .git
intacto: un archivo zip, un disco compartido, una carpeta sincronizada, una
memoria USB. La lista de Manifold describe cómo consultores, clientes y colegas
se pasan trabajo, y es la única vía de entrega en la que no hay ninguna pull
request. La propia defensa de git contra repositorios hostiles,
safe.directory, comprueba si el repositorio pertenece a otra persona. Tú lo
descomprimiste, así que es tuyo, y la defensa no tiene nada que decir.
El momento de la ejecución deja la protección propia de cada agente un paso demasiado tarde. En Claude Code y Hermes Agent la carga se dispara antes del aviso de confianza del espacio de trabajo, el diálogo que existe justamente para preguntar si confías en este directorio. En Qwen Code se dispara antes de que el usuario se haya autenticado, y en Grok Build se dispara con la primera tecla.
Ocho hallazgos, siete agentes, cuatro todavía abiertos
La mitad está corregida. goose 1.44.0 lleva la corrección de
CVE-2026-72718, valorada con
CVSS 7.0. OpenAI publicó Codex CLI 0.131.0 y las builds de escritorio 26.519.x
para CVE-2026-19592. Cursor parcheó su variante. Manifold confirmó el camino
core.fsmonitor de Claude Code en 2.1.193 y Anthropic lo cerró en 2.1.196, sin
publicar un aviso: Manifold señala que ninguno de los dos hallazgos sobre Claude
Code aparece en los registros de avisos de npm.
La otra mitad no se ha movido. Hermes Agent tiene un CVE (CVE-2026-71963) y un
aviso privado todavía sin triar después de seis intentos de contacto. Los
mantenedores de Qwen Code aceptaron el informe el 7 de julio y 0.22.3 sigue
ejecutando el comando. Grok Build lo sigue ejecutando. Y Claude Code tiene un
segundo camino, a través de su comando ultrareview, que abusa de una clave
de configuración de git distinta y seguía vivo en 2.1.252. Manifold se guardó el
nombre de esa clave en lugar de repartir una plantilla de ataque reutilizable.
Anthropic parcheó el primer camino en tres días. La clase de fallo lo rodeó por otra clave, en el mismo archivo, en el mismo producto.
Esta es la superficie de ejecución de git, heredada por toda herramienta que
delega en git, y git tiene más de un ajuste cuyo valor es un comando que
ejecutará por ti. Los paginadores, los editores, los comandos SSH, las rutas de
hooks, los drivers de diff y de filtro, y los alias que empiezan con un escape
de shell aceptan todos valores de comando. Ahora cada fabricante tiene que
averiguar, clave por clave, cuáles de ellas puede alcanzar un repositorio desde
su ruta de arranque, frente a un esquema de configuración que gana claves con el
tiempo. La corrección recomendada por Manifold, sanear la configuración de git
durante las operaciones de contexto en segundo plano y desactivar
core.fsmonitor, es una lista de bloqueo mantenida frente a un espacio de
nombres. Los investigadores encontraron el patrón en más agentes de los que
nombra el informe.
Los controles que habrían atrapado esto están aguas abajo
Alinea lo que un equipo cuidadoso tiene hoy sobre un agente de codificación: avisos de permiso en el uso de herramientas, confianza de espacio de trabajo, hooks que inspeccionan un comando antes de que se ejecute, los endpoints de transcripción que envían una sesión a un backend de cumplimiento, y OpenTelemetry para decisiones de permiso y saltos.
Todos ellos se anclan al bucle propio del agente, es decir, a una llamada a
herramienta que el agente decidió hacer o a un turno que el modelo tomó.
GitSpawn no produce ninguno de los dos. El proceso que ejecuta la carga es
git, invocado por el agente para su propia limpieza, y el comando viene de un
archivo que el agente nunca leyó. No hay llamada a herramienta que aprobar ni
hook que disparar. Un equipo que ve aterrizar transcripciones de agente en su
SIEM ve una sesión que arranca con normalidad y no muestra nada, el mismo punto
ciego del que escribimos
cuando Anthropic lanzó su Compliance API:
un registro anclado a lo que llegó al modelo no puede ver lo que se ejecutó
antes de que se consultara al modelo.
El comando se va a ejecutar. La pregunta que vale la pena responder es qué encuentra.
Déjalo correr y mira qué encuentra
Bromure Agentic Coding da a cada espacio de trabajo su propia VM Ubuntu bajo el hipervisor de Apple. El agente, su git, su gestor de paquetes y todo lo que esos tres arranquen viven en el invitado. Suelta el zip del colaborador en un espacio de trabajo, deja que el auxiliar se dispare y concédele todo al atacante: antes de la confianza, antes de la autenticación, root en el invitado si quieres.
Leer las claves SSH. No hay ninguna que leer. Las claves privadas de un
espacio de trabajo se quedan en tu Mac; la VM recibe un SSH_AUTH_SOCK
puenteado por vsock hasta un agente del lado del anfitrión. Ese protocolo tiene
una petición que significa “firma este desafío” y ninguna que signifique
“dame la clave”.
Barrer el entorno en busca de credenciales. Están todas ahí, con la forma
que esperan los validadores, y todas son señuelos. ANTHROPIC_API_KEY guarda un
sk-ant-api03-brm-… falso, y lo mismo ocurre con ~/.git-credentials,
~/.aws/config, ~/.kube/config y ~/.docker/config.json. Tus valores reales
viven cifrados en tu Mac, y el proxy los sustituye en el cable después de que la
petición haya salido de la VM, solo cuando va dirigida al anfitrión para el que
se acuñó esa credencial. Ningún interruptor apaga esto. Así es como funcionan
las credenciales en la aplicación.
Descargar la segunda etapa. El auxiliar es un cargador, unos cientos de
bytes cuyo trabajo es traer la carga real. Esa descarga se topa con el firewall
de salida del espacio de trabajo. Pon Tráfico sin coincidencia en Deny y la
VM llega a los hosts que has listado y a nada más, aplicado en dos sitios: el
conmutador virtual filtra por IP de destino y por nombre de host husmeado en el
DNS, en todos los protocolos, y el proxy vuelve a filtrar por nombre de servidor
TLS y, para las reglas web, por método HTTP. Un cargador que en su lugar
recurra a un registro de paquetes se encuentra con el pipeline de cadena de
suministro, donde la barrera de edad rechaza versiones más jóvenes que el corte.
Una carga publicada ayer no supera ese listón.
Exfiltrar lo que sí encontró. Ahora algo tiene que cruzar un cable que posee tu Mac. El proxy escanea cada petición saliente contra los señuelos acuñados para el espacio de trabajo, cabeceras y cuerpo, con un autómata de Aho-Corasick. Un señuelo dirigido a un host fuera del ámbito para el que se acuñó es la firma de una máquina que está mandando fuera algo que no debería conocer. El proxy bloquea con un HTTP 451 antes de que un solo byte llegue al destino, pausa la VM y levanta una alerta nombrando la credencial y ambos hosts. Bromure marca entonces el espacio de trabajo como comprometido, y no volverá a arrancar hasta que borres su disco y su home.
Dejar persistencia. Un .bashrc modificado en el invitado dura lo que dejes
durar a la VM. Borrar home reinicia /home/ubuntu, Restablecer disco
vuelve a clonar el disco de sistema desde la imagen base firmada, y
bromure-cli vm run --rm te da un espacio de trabajo que se borra solo cuando
la VM se detiene.
La interceptación no tiene variable de entorno que desactivar
Un proxy al que el invitado se adhiere es un proxy que el invitado puede
rechazar. El conmutador virtual de Bromure desvía él mismo los flujos del
puerto 80 y del puerto 443 de la VM hacia el proxy del anfitrión: no hay
HTTPS_PROXY que desactivar, nada en el invitado que lo apague, y el HTTP
plano se inspecciona igual que el HTTPS. El proceso que hace la petición aquí
nunca leyó la configuración del agente y no es el agente. Es un binario
auxiliar que lanzó git, y viaja por el mismo cable que todo lo demás.
La fila existe aunque no exista ninguna llamada a herramienta
El proxy del anfitrión escribe un registro de metadatos por cada petición que
sale de la VM, sea cual sea el proceso que la hizo: hora, host, puerto,
método, ruta, estado, latencia y bytes medidos antes del intercambio de
credencial. Los veredictos del firewall, las decisiones de cadena de
suministro y la intermediación de credenciales aterrizan en la Línea de
tiempo de seguridad (Ventana → Línea de tiempo de seguridad…), y en un Mac
inscrito van al flujo de eventos de la organización como egress.firewall,
supply_chain.fetch y credential.exfiltration. Una transcripción de este
ataque del lado del agente está en blanco mientras la del cable lleva la
petición.
El invitado puede alcanzar una sola cosa en tu Mac. Una carpeta compartida es
una ventana viva, de lectura y escritura, a tu sistema de archivos real, y el
borrado por compromiso la deja intacta por diseño. Comparte el directorio del
proyecto en lugar de tu directorio home, y el find del auxiliar buscando
*.pem recorre un home Linux lleno de checkouts y cachés de paquetes en lugar
de tus inicios de sesión respaldados por el llavero.
La frontera que no es un paso de la secuencia
Lee juntos los cuatro detalles temporales de GitSpawn — antes del aviso de
confianza, antes de la autenticación, antes de la primera tecla, antes de
cualquier turno del modelo — y dicen una sola cosa. Cada protección es un paso
de una secuencia de arranque, y cada nueva función añade un paso por delante de
ella. Cursor lo aprendió en 2025 con un mcp.json suministrado por el
repositorio, y otra vez este julio con un comando de preparación de worktree que
se ejecutaba antes de su propio aviso de
confianza. Ahora le toca a git, en siete
productos a la vez, a través de una clave de configuración que lleva años en
git.
Un hipervisor no es un paso de esa secuencia. No lee el .git/config. Ninguna
refactorización lo reordena y ningún camino de código se exime de él, porque no
se ejecuta en el mismo programa que el aviso. La VM estaba corriendo antes de
que el zip terminara de descargarse, y sus dos garantías — aquí dentro no hay
secretos reales y no hay ruta sin mediar hacia fuera — se sostienen igual en
2.1.193 y en 2.1.196.
Revisa tu .git/config antes de abrir una carpeta que alguien te haya enviado.
Manifold tiene razón al decirlo. También lo harás durante dos semanas y luego lo
saltarás en el tercer zip de una tarde ajetreada, que es la vida útil de la
mayoría de las instrucciones que terminan en “antes de abrirlo”.
Instala Bromure Agentic Coding, dale a la carpeta
desconocida su propia máquina, y deja que la config ejecute lo que quiera en una
habitación donde ejecutarse es todo lo que va a poder hacer.