Quien controle el repositorio de un plugin solo tiene que crear una rama por defecto con el nombre adecuado, el hash del commit fijado o, en Gemini CLI, FETCH_HEAD. Con eso, Claude Code, OpenAI Codex, GitHub Copilot y Gemini CLI instalan un plugin distinto del revisado. Air Security lo ha bautizado Plugin4Shell y lo publicó el 17 de septiembre de 2026 en un informe firmado por Or Nevo, Dor Granat y Niv Hoffman.
Los cuatro agentes fijan cada plugin a un commit determinado. Los cuatro, según ese informe, daban por bueno el checkout, la orden de git que extrae ese commit al directorio de trabajo, sin comprobar después que el directorio contuviera ese commit.
Anthropic (Claude Code 2.1.179) y OpenAI (Codex 0.146.0) corrigieron el fallo tras la notificación coordinada de junio. Copilot sigue sin parche y Gemini CLI, según comunicó Google a Air, no lo tendrá. No hay CVE asignado, ningún fabricante ha publicado aviso de seguridad y no hay indicios de uso en ataques reales, según comprobó The Hacker News el 18 de septiembre.
¿Qué es Plugin4Shell y a quién afecta?
Los agentes de programación se extienden con plugins: paquetes de instrucciones, herramientas y ganchos de ejecución que se publican en catálogos, los llamados marketplaces, y que el agente descarga de un repositorio git. Para que una revisión valga algo, el catálogo registra el hash del commit revisado, el identificador de 40 caracteres hexadecimales de esa instantánea del código, y el agente instala exactamente ese commit. Es la misma idea que fijar una dependencia por hash en un fichero de bloqueo (lockfile): si el repositorio cambia mañana, la instalación no.
Plugin4Shell rompe esa idea dentro del agente. No hace falta comprometer el catálogo ni convencer a nadie de que instale algo nuevo. La víctima solo necesita tener instalado un plugin legítimo, fijado a un commit revisado, cuyo repositorio pase a estar bajo control de un atacante. Air describe dos maneras de conseguir ese control: publicar un plugin benigno, esperar a que se adopte y volverlo malicioso después, o apropiarse del repositorio de un plugin ajeno en el que el catálogo ya confía. Como resume Help Net Security, el fallo atrapa a quien ya había hecho todo bien: revisar el plugin y fijarlo.
La segunda vía encaja con lo que la misma empresa contó en agosto sobre MCPJacking: encontró 155 entradas del registro oficial de servidores MCP que apuntaban a dominios caducados, registró alguno de esos dominios y publicó detrás su servidor, que los agentes aceptaron como el original. Un repositorio de plugin es un activo que se hereda, se abandona y se compra igual que un paquete de npm.
Una rama con nombre de hash engaña al checkout
El fallo combina dos comportamientos de git (prefiere una rama a un hash del mismo nombre, y admite ramas con esa forma) con una decisión de producto: el agente no verifica el commit que ha quedado en disco. Lo que sigue resume el análisis técnico de Air, que The Hacker News reprodujo en una prueba local.
Claude Code, Codex y Copilot
Los tres clonan el repositorio del plugin y después ejecutan git checkout con el hash fijado. El atacante que controla el repositorio crea una rama cuyo nombre es el hash completo del commit fijado y la convierte en rama por defecto. Al clonar, esa rama se crea también en local. Cuando el agente pide el checkout del hash, git encuentra una rama con ese nombre exacto, la prefiere al identificador del objeto e imprime como mucho un aviso de nombre ambiguo. El commit revisado puede seguir intacto en el repositorio; en disco queda lo que apunta la rama.
La corrección pública de OpenAI describe el mismo comportamiento: git puede interpretar un hash solicitado como nombre de rama y materializar un commit distinto del fijado.
La comprobación de nombres de git acepta cadenas de 40 caracteres hexadecimales. Algunos servidores las prohíben: GitHub rechaza ramas y etiquetas que parezcan un hash, según confirmó un portavoz a The Register. Bitbucket y los servidores git autoalojados las aceptan, según Air, y ambos figuran, siempre según Air, entre los servidores que la documentación de Claude Code admite para un catálogo.
Gemini CLI
Gemini CLI no hace checkout del hash directamente. Clona con profundidad uno, trae el commit fijado con git fetch y luego hace checkout de FETCH_HEAD, el nombre con el que git recuerda lo último que trajo. Si la rama por defecto del repositorio se llama precisamente FETCH_HEAD, el checkout resuelve al nombre de la rama y descarta el commit que acababa de traer. Como FETCH_HEAD no tiene forma de hash, The Hacker News advierte de que la regla de nombres de GitHub no bloquea con claridad esta variante.
La actualización automática elimina la interacción del usuario
El problema se limitaría al momento de la instalación si el agente descargara el plugin una sola vez. Claude Code y Codex actualizan los plugins instalados en segundo plano, según el informe, y ahí está la parte sin interacción: cuando el catálogo cambia el commit fijado, esos dos agentes repiten el checkout y el código sustituido llega a plugins que ya estaban instalados y en uso.
El atacante no necesita colar nada malicioso por la revisión del catálogo: publica una versión benigna, consigue que el catálogo la fije y solo entonces crea la rama con nombre de hash; los agentes que actualicen a partir de ese momento reciben el código malicioso.
Hay un matiz que Air no destaca y que el medio citado sí señala tras leer la documentación de Anthropic y de GitHub: la actualización automática está activada por defecto solo para los catálogos oficiales de cada agente, alojados en GitHub, y está desactivada o es opcional para los externos. El mismo medio comprobó el 18 de septiembre que todos los plugins del catálogo comunitario de Anthropic y de los catálogos por defecto de Claude Code y Copilot apuntan a repositorios de GitHub.
Quien instale solo desde esos catálogos no está expuesto a la variante de la rama con nombre de hash. La exposición está en los catálogos internos o de terceros alojados fuera de GitHub, justo los que una empresa monta para controlar lo que instalan sus desarrolladores.
La comprobación que faltaba cabe en una línea: tras el checkout, resolver el commit que hay en el directorio de trabajo y abortar si no coincide con el fijado. Tiene que mirar el HEAD resuelto, porque la variante de Gemini pide una referencia, FETCH_HEAD, que no es la que acaba en disco. Y tiene que ejecutarse en el cliente, porque es el cliente quien resuelve el hash.
¿Qué ha cambiado respecto a hace un año?
La investigación en seguridad de agentes se había centrado hasta ahora en el modelo y en el propio agente, según el planteamiento de Air. En este blog lo hemos visto con los registros de observabilidad envenenados que se convierten en órdenes. Plugin4Shell apunta a la capa de distribución que hay debajo, los catálogos desde los que los plugins llegan a las máquinas de los desarrolladores.
Esa capa tiene alcance suficiente para interesar a un atacante. Air cita su investigación anterior. Un skill de prueba (la extensión de agente más ligera que un plugin) que la empresa publicó llegó a más de 26.000 agentes tras cambiar un enlace externo una vez pasada la revisión. Y 925 skills ya en uso pudieron secuestrarse apropiándose de los repositorios de sus mantenedores. Son cifras de un único proveedor con producto en este mercado, aunque la primera tuvo cobertura independiente en junio.
El objetivo coincide con el de los incidentes de npm de este año: el gusano Mini Shai-Hulud, que planta ganchos de ejecución en Claude Code y VS Code, o el paquete jscrambler comprometido, que robaba las credenciales de las herramientas de IA, iban a por lo mismo que un plugin sustituido. La respuesta del sector a los secuestros de repositorio fue fijar por hash. Cuatro implementaciones con la misma omisión apuntan, en nuestra lectura, a un control mal especificado: la norma decía «fija el commit», no «comprueba que has llegado».
El catálogo no puede arreglarlo
El hash se resuelve en el cliente, así que ningún catálogo puede cumplir por sí mismo lo que promete. Puede limitar el daño rechazando servidores git que admitan ramas con nombre de hash, lo que con lo publicado deja poco más que GitHub, pero eso excluye servidores que los agentes admiten oficialmente y no hace nada contra la variante de Gemini. La revisión de código del catálogo tampoco ayuda: el commit revisado sigue intacto y el agente no llega a él.
El segundo problema es el privilegio con el que se ejecuta el plugin. Un agente de programación trabaja con las credenciales de git del desarrollador, sus tokens de nube, sus claves de API y el acceso a cuanto repositorio pueda clonar. En nuestra experiencia esas credenciales pertenecen a menudo a identidades no humanas: cuentas de servicio y tokens con más permisos que el desarrollador, sin caducidad y sin inventario. Un plugin sustituido las hereda en el momento de la actualización sin pasar por el correo ni por el navegador.
¿Qué agentes tienen parche y cuáles no?
La cronología de Air, completada con lo publicado por la prensa, deja a cada fabricante en una fase distinta:
- Mayo de 2026: Air encuentra el fallo y construye pruebas de concepto contra los cuatro agentes.
- Junio: notificación coordinada a los cuatro. El 17 de junio Anthropic confirma a Air la corrección en Claude Code 2.1.179; las notas de esa versión no la mencionan, así que la constancia es la de Air.
- 4 de agosto: Google comunica a Air que no habrá parche porque Gemini CLI está en fase de retirada.
- 12 de agosto: Air verifica la corrección en Codex 0.146.0, cuya solicitud de cambio pública describe el fallo.
- 17 de septiembre: publicación. Microsoft no ha publicado corrección para Copilot; al cierre del artículo de The Register no había respondido al medio y, según Air, tampoco ha contestado a la notificación de junio.
Sobre Copilot hay una discrepancia sin resolver. GitHub, que pertenece a Microsoft, sí respondió a The Register y sostiene que el ataque no funciona contra repositorios alojados en GitHub por su filtro de nombres. Air replica que Copilot admite catálogos en otros servidores y sigue expuesto en ellos.
Sobre Gemini CLI hay dos posiciones de Google en tensión. En su anuncio de mayo retiraba la herramienta en favor de Antigravity CLI, cortaba el servicio a las cuentas de particulares el 18 de junio y prometía a los clientes de empresa soporte continuado y actualizaciones. En agosto, según Air, comunicó que no habrá parche. No consta una aclaración pública sobre si esas actualizaciones de empresa incluirán este fallo.
Qué controles siguen valiendo
Los que tratan a los agentes como lo que son: software externo con acceso privilegiado. Eso los mete en el programa de gestión de riesgo de terceros, con la misma disciplina que cualquier otra pieza de la cadena de suministro de software.
- El primer control es un inventario de agentes y versiones en las máquinas de los desarrolladores. Claude Code por debajo de 2.1.179, Codex por debajo de 0.146.0 y Copilot, sin versión corregida, son vulnerables con catálogos fuera de GitHub; Gemini CLI lo es en cualquier servidor, porque su variante no depende del nombre del hash.
- Una política de catálogos permitidos viene después. Un catálogo interno alojado en GitHub, o en un servidor que rechace nombres de rama con forma de hash, limita el primer mecanismo; hay que dar por hecho que no cierra el segundo. Si el catálogo interno vive en Bitbucket o en un git autoalojado, es el caso que más importa.
- La actualización automática de plugins debería estar desactivada en las máquinas gestionadas, donde exista, con actualización manual tras revisar el cambio de commit. Molesta al desarrollador, pero la actualización en segundo plano es el paso que elimina la intervención del usuario.
- Las credenciales con las que se ejecuta el agente tienen que estar acotadas: tokens de git de corta vida, ninguna credencial de nube en la sesión del agente y un contenedor o máquina virtual para los proyectos que instalan plugins de terceros. Medir ese privilegio es por donde debería empezar una auditoría de seguridad de agentes de IA y MCP.
- El EDR (detección y respuesta en el puesto) debe vigilar los procesos del agente: clonaciones de git que este inicie hacia dominios distintos del que aloja el catálogo aprobado, procesos hijos inesperados tras una actualización de plugin y escrituras fuera del directorio del plugin. Un equipo de caza de amenazas puede convertirlas en tres consultas.
- Quien mantiene un catálogo interno tiene una comprobación periódica pendiente, listar las ramas de cada repositorio de plugin y alertar si alguna tiene 40 caracteres hexadecimales o se llama FETCH_HEAD, y un cambio permanente en su instalador: comparar el commit resuelto tras el checkout con el fijado.
Revisar y fijar no basta si el instalador no verifica el resultado. Y la seguridad de MCP y agentes en producción tiene que cubrir la capa de distribución de plugins, además del servidor y el modelo.
Lo que todavía no se sabe
No consta un identificador CVE que permita seguir el caso en las bases de datos de vulnerabilidades habituales. Tampoco hay una lista pública de catálogos afectados, porque el fallo no está en ningún catálogo. La discrepancia entre GitHub y Air sobre Copilot sigue abierta, Microsoft no se ha pronunciado y ninguna fuente dice si actualizar el agente retira un plugin ya sustituido o solo impide las sustituciones futuras. Un buen punto de partida es contar cuántos instaladores internos de la organización fijan un hash y cuántos verifican el commit que instalan.
Las configuraciones y comprobaciones descritas son un punto de partida y deben validarse en un entorno de pruebas antes de aplicarse en producción. Los datos sobre el fallo, sus variantes y el estado de las correcciones proceden de Air Security, de las comprobaciones de The Hacker News y The Register y de los anuncios públicos de Google y OpenAI. Reflejan la información disponible a 21 de septiembre de 2026. La mención de los productos afectados no implica valoración sobre su seguridad general, y el estado de los parches puede cambiar.
Preguntas frecuentes
¿Plugin4Shell tiene número CVE o está en el catálogo KEV de CISA?
▾
A 21 de septiembre de 2026 no consta un identificador CVE ni una entrada en KEV, y The Hacker News no encontró aviso de seguridad de ningún fabricante ni indicios de uso en ataques reales. Eso complica el seguimiento con las herramientas habituales de gestión de vulnerabilidades, que ordenan por CVE: el rastreo se hace por versión de agente instalada en cada máquina.
¿Basta con actualizar el agente para estar protegido?
▾
Actualizar Claude Code a 2.1.179 o posterior y Codex a 0.146.0 o posterior corrige el fallo, según Air, pero ninguna fuente dice si la actualización retira un plugin ya sustituido o solo impide sustituciones futuras. Por prudencia, después de actualizar se revisan los plugins instalados y se reinstalan desde el commit fijado. Para Copilot y Gemini CLI no hay versión corregida y solo quedan las mitigaciones: restringir catálogos, desactivar la actualización automática donde exista y acotar credenciales.
Si mis plugins están alojados en GitHub, ¿estoy protegido?
▾
En gran parte. GitHub rechaza nombres de rama y de etiqueta con forma de hash, lo que bloquea el mecanismo que afecta a Claude Code, Codex y Copilot en repositorios alojados allí; los catálogos por defecto de esos agentes apuntan a GitHub, según comprobó The Hacker News. No cubre la variante de Gemini CLI, que se apoya en una rama llamada FETCH_HEAD, ni protege a los catálogos internos o de terceros alojados en Bitbucket o en servidores git propios.
¿Cómo puedo saber si un plugin ya instalado ha sido sustituido?
▾
Comparando el commit real del directorio del plugin con el hash que fija el catálogo: si no coinciden, el plugin no es el revisado. Hay que consultar además las ramas del repositorio remoto y buscar alguna cuyo nombre tenga 40 caracteres hexadecimales o sea FETCH_HEAD, y revisar la fecha de la última actualización automática. Una discrepancia se trata como incidente: aislar el equipo y rotar las credenciales a las que el agente tenía acceso.
¿En qué se diferencia de un ataque a npm o PyPI?
▾
En npm o PyPI la versión maliciosa es una versión nueva que el registro sirve, y un lockfile con hash la detecta. En Plugin4Shell el identificador fijado sigue siendo el mismo y es git, en el cliente, quien lo resuelve hacia otro código. El lockfile del catálogo sigue pareciendo correcto, y la defensa que cierra el fallo es que el instalador verifique el commit resultante, no el solicitado.
¿Puede un catálogo corregir Plugin4Shell por su cuenta?
▾
No del todo. Solo el agente puede comprobar dónde ha acabado el checkout, así que la corrección completa tiene que venir de cada fabricante. Lo que un catálogo puede hacer es restringir los servidores permitidos, y esa restricción no alcanza a la variante de Gemini CLI.
¿Por qué importa a un CISO un fallo en herramientas de desarrollo?
▾
Porque un plugin sustituido corre con la identidad del desarrollador y hereda sus credenciales en el momento de la actualización, desde una herramienta que suele quedar fuera del inventario de software de terceros y de los controles de correo y navegador. El riesgo se gobierna igual que el de cualquier proveedor con acceso privilegiado.
¿Qué pasa con las instalaciones de Gemini CLI en empresas?
▾
Siguen funcionando con licencia de empresa o clave de API. Google prometió en mayo soporte y actualizaciones a esos clientes, pero según Air comunicó en agosto que este fallo no se corregirá, y no hay aclaración pública. Las opciones realistas son migrar a Antigravity, que según Air no tiene anclaje de plugins por commit que burlar, o acotar los permisos del agente y restringir sus catálogos mientras tanto.