Plugin4Shell: cuatro agentes de código con IA confiaban en un pin que nunca verificaban

Fijar un plugin a un commit específico por su hash SHA es una de las principales garantías de integridad en una cadena de suministro de software. Una vez revisado y aprobado ese código, el pin debería asegurar que eso, y no otra cosa, sea lo que se ejecute.
El problema es que "pineado" y "validado" no son lo mismo. Y una investigación reciente lo demostró en cuatro de los agentes de código con IA más utilizados del mercado.
Qué encontró AIR Security
Investigadores de AIR Security identificaron una falla en el mecanismo de pin por SHA de los plugins: el agente verifica que el commit indicado por el marketplace quedó fijado, pero nunca confirma que el checkout realmente haya llegado a ese commit.
Un atacante que controla el repositorio de un plugin legítimo puede aprovechar esa brecha para hacer que el checkout resuelva hacia código malicioso mientras el pin sigue pareciendo respetado. El resultado: ejecución remota de código zero-click en Claude Code, Codex, GitHub Copilot y Gemini CLI.
La mecánica varía según el agente. En Claude Code, Codex y GitHub Copilot, la exposición viene de una rama nombrada igual que el hash de commit fijado de 40 caracteres. Como Git puede resolver el nombre de la rama antes que el objeto de commit, el atacante crea una rama con ese nombre exacto, la marca como rama por defecto y consigue que el agente reporte una instalación limpia en el hash esperado mientras, en realidad, ejecuta otro código.
Esta variante depende también del host Git utilizado. GitHub, por ejemplo, restringe la creación de ramas con nombres de 40 caracteres hexadecimales, mientras que otros hosts o servidores Git pueden permitirlas.
Gemini CLI presenta una variante diferente, relacionada con una ambigüedad en la resolución de FETCH_HEAD.
Además, en los agentes donde los plugins pineados podían actualizarse automáticamente, el ataque podía ejecutarse sin una nueva interacción del usuario una vez preparadas las condiciones necesarias. De ahí la clasificación como zero-click.
La respuesta de cada fabricante
AIR Security divulgó Plugin4Shell públicamente el 17 de septiembre de 2026, después de haber encontrado la falla en mayo de ese año, desarrollar exploits de prueba de concepto contra los cuatro agentes y notificar posteriormente a cada fabricante.
Al momento de la divulgación:
- Anthropic había parcheado Claude Code en la versión 2.1.179.
- OpenAI había corregido el problema en Codex 0.146.0.
- Microsoft no había publicado un fix para GitHub Copilot. Sin embargo, la explotación mediante ramas de 40 caracteres está restringida en repositorios alojados directamente en GitHub, aunque Copilot puede utilizar plugins provenientes de otros hosts.
- Google no planeaba corregir la versión afectada de Gemini CLI y dirigía a los usuarios hacia Antigravity.
Es decir, al momento de hacerse pública la investigación, solo dos de los cuatro agentes contaban con un parche disponible.
Por qué importa más allá del parche
Lo que hace interesante este caso no es solo la lista de marcas involucradas.
Es que incluso una organización que siguiera el modelo de seguridad esperado podía quedar expuesta bajo determinadas condiciones. La víctima podía estar utilizando un plugin revisado y pineado exactamente como indicaba el mecanismo de seguridad, pero si el repositorio terminaba bajo control de un atacante, ese pin no necesariamente garantizaba que el código ejecutado fuera el que había sido aprobado.
Hacer las cosas bien no siempre era suficiente.
Plugin4Shell expone una diferencia sencilla, pero importante: comprobar que existe un control no es lo mismo que comprobar que ese control funciona.
El marketplace podía revisar el código. Podía registrar un SHA. Podía exigir que el plugin quedara pineado. Todo eso podía estar correctamente configurado y, aun así, el código que terminaba ejecutándose podía ser otro.
El problema no estaba en la ausencia del control. Estaba en asumir que el control producía el resultado esperado sin validarlo.
Y esa diferencia importa mucho más allá de Plugin4Shell.
Una configuración puede ser correcta. Una política puede estar activa. Un control puede aparecer como implementado. Pero ninguna de esas cosas demuestra, por sí sola, qué sucede cuando alguien intenta romperlo.
Encontrar un mecanismo de seguridad no es lo mismo que validar que funciona bajo ataque real.
¿Cuántos de tus controles de seguridad están configurados correctamente, pero nunca fueron validados bajo condiciones reales de ataque?
En Strike creemos que la seguridad no termina cuando un control está correctamente configurado. Empieza cuando puedes comprobar que funciona como esperas frente a un ataque real.
Porque "configurado", "pineado" o "aprobado" describen una intención. Validado describe un resultado.



