- Un equipo de investigación de seguridad logró ejecución remota de código (RCE) en los servidores de producción de CodeRabbit y filtración de tokens de API y secretos
- Mediante un PR que aprovechaba Rubocop, fue posible extraer variables de entorno, además de acceder a PostgreSQL y obtener lectura/escritura sobre 1 millón de repositorios
- La filtración de la clave privada de la GitHub App permitió inyectar código malicioso y modificar código fuente en un gran volumen de repositorios, públicos y privados, haciendo posible un impacto real
- CodeRabbit respondió de inmediato en cuestión de horas tras el reporte de la vulnerabilidad y reforzó sus medidas de seguridad
- Se subraya la necesidad de prevenir incidentes de seguridad al ejecutar herramientas externas mediante aislamiento en sandbox, privilegio mínimo y bloqueo de red
Introducción
- En enero de 2025, el equipo de investigación de Kudelski Security reveló una vulnerabilidad crítica en CodeRabbit
- En CodeRabbit, una herramienta ampliamente usada para automatizar revisiones de PR, se confirmó un problema grave: remote code execution (RCE), filtración de variables de entorno e información sensible, y obtención de permisos de lectura/escritura sobre más de 1 millón de repositorios
- Este artículo contiene un análisis detallado de la vulnerabilidad divulgada en Black Hat USA, y tiene alto valor como caso real de fallas en herramientas de revisión basadas en código y sistemas integrados
- La vulnerabilidad reportada fue parcheada rápidamente justo después de ser informada
Resumen de CodeRabbit
- CodeRabbit es la app de revisión de código con IA más instalada en GitHub Marketplace y GitLab Marketplace
- Revisa 1 millón de repositorios y 5 millones de pull requests en ambas plataformas
- Cada vez que un usuario crea o actualiza un PR, el motor de IA analiza el código y genera automáticamente comentarios y sugerencias
- Ofrece grandes beneficios para la productividad de desarrollo, como resúmenes de código, detección de vulnerabilidades de seguridad, sugerencias de mejora y generación de diagramas
Uso de CodeRabbit y estructura de permisos
- El plan Pro ofrece funciones de integración con herramientas de linter y SAST (análisis estático)
- Al autenticar una cuenta de GitHub e instalar la app, se le otorgan permisos de lectura y escritura sobre los repositorios seleccionados
- Si esta gestión de permisos fuera abusada, podría tener un impacto directo sobre el código de todos los repositorios donde está instalada
Ejecución de herramientas externas y hallazgo del exploit
- Cuando CodeRabbit detecta cambios de código dentro de un PR, ejecuta automáticamente múltiples herramientas externas de análisis estático (por ejemplo, Rubocop)
- Rubocop está diseñado para usar el archivo de configuración
.rubocop.yml, que puede cargar archivos externos de extensión Ruby (comoext.rb)- Un atacante puede insertar código malicioso en
.rubocop.ymlyext.rb, enviar un PR y hacer que CodeRabbit ejecute ese código en su servidor remoto
- Un atacante puede insertar código malicioso en
- El código ejecutado con esta técnica envió todas las variables de entorno del servidor al servidor del atacante
Análisis del contenido filtrado en variables de entorno
- Las variables de entorno filtradas incluían API keys, tokens y contraseñas de diversos servicios, entre ellos:
- claves de API de Anthropic/OpenAI, salt/password de cifrado, clave privada de GitHub App, credenciales de PostgreSQL, etc.
- Mediante RCE, el potencial de daño secundario era alto y de gran alcance: acceso a bases de datos, modificación de código y filtración de información interna del servicio
- Era posible continuar con más exploración maliciosa sobre el servidor real, pero por consideraciones operativas del servicio se verificó solo lo mínimo y luego se detuvo
Obtención de permisos de lectura/escritura sobre 1 millón de repositorios
- Usando GITHUB_APP_PEM_FILE (clave privada) incluida en las variables de entorno, era posible autenticarse ante la GitHub API
- Sobre todos los repositorios a los que CodeRabbit tenía acceso (incluyendo públicos y privados), se podían ejercer permisos muy potentes, como:
- leer/escribir código fuente, reemplazar archivos de release (ataque a la cadena de suministro), alterar historial de git, etc.
- Se publicó un código de reproducción (PoC) que demostró la viabilidad real de explotación
Resumen del PoC
- Usando librerías como PyGitHub y la clave privada filtrada, el App ID y otros datos, se pueden emitir tokens de acceso para repositorios arbitrarios
- Con esos tokens, es posible automatizar la clonación de repositorios privados, modificación de archivos, nuevos commits y manipulación de archivos de release
Posible compromiso de repositorios internos/privados de CodeRabbit
- Como la propia organización de CodeRabbit también tenía instalada la app en su servicio, también era posible acceder y clonar los repositorios internos del código fuente de CodeRabbit
- Con solo conocer el nombre de la organización, se podía consultar el installation ID y acceder de inmediato a la lista de repositorios correspondientes
Resumen del impacto
- Acceso no autorizado a repositorios privados y filtración de datos personales
- Amenaza de ataques a la cadena de suministro, como manipulación de código fuente e inserción de malware/backdoors
- Posibilidad de encadenarlo con vulnerabilidades adicionales, como las de GitHub Actions
- RCE directo con potencial de causar destrucción de datos, caída del servicio y daños en cascada sobre otros servicios
Contexto y límites del juicio de la IA
- Incluso durante el ataque, el propio PR fue revisado normalmente por CodeRabbit, y aunque dejó un comentario de advertencia sobre la vulnerabilidad, en la práctica no logró identificar la sintaxis maliciosa como amenaza
- Esto muestra que una herramienta de revisión de código con IA no necesariamente comprende el contexto real de una situación de riesgo
Respuesta y recomendaciones
- CodeRabbit deshabilitó Rubocop, rotó secretos y realizó una auditoría del sistema en cuestión de horas tras el reporte
- El problema ocurrió en una herramienta (Rubocop) a la que no se le aplicaba sandbox; después de las medidas, se mejoró para que todas las herramientas externas se ejecuten en entornos aislados
- Para reforzar la seguridad, se subraya la necesidad de un diseño defensivo en el entorno de ejecución de herramientas externas: minimizar variables de entorno, restringir IPs de acceso de red, bloquear acceso a internet, etc.
Divulgación responsable y conclusión
- En enero de 2025, tras el reporte, se llevaron a cabo una respuesta y medidas rápidas
- Se quedó solo en un PoC, pero quedó demostrado que un atacante malicioso podría abusarlo fácilmente para seleccionar repositorios de alto valor, desplegar ransomware a gran escala o realizar ataques destructivos a la cadena de suministro
- Se reafirma la importancia de implementar sandbox y el principio de mínimo privilegio al integrar herramientas externas de análisis y servicios de automatización basados en IA
1 comentarios
Opiniones en Hacker News
Oh wow, esta es una vulnerabilidad realmente grave. Qué bueno que ya la corrigieron esta vez, pero el solo hecho de que algo así existiera desde el principio ya es un problema. La regla más básica al crear un sistema que analiza código de usuarios en una plataforma en la nube es que el analizador debe ejecutarse siempre en un entorno aislado. Se puede inyectar código directamente mediante plugins, y los linter/analizadores/compiladores son software complejo con una gran superficie de ataque. Nunca se debe asumir que es seguro ejecutar estas herramientas sobre repositorios arbitrarios en un entorno compartido. Yo también operé una plataforma de análisis de código, y aun cuando corríamos analizadores desarrollados por nosotros mismos sobre repositorios de clientes, los diseñamos para ejecutarse en un entorno sandbox. Ni siquiera incluíamos variables de entorno ni permisos para solicitudes de red, pero el análisis se ejecutaba solo dentro del sandbox. Es la única forma de hacer análisis de código de manera segura
https://github.com/getgrit/gritql
Cancelé mi suscripción de pago a Coderabbit. Siempre me preocupa cuando una empresa solo termina reconociendo un problema después de que se vuelve viral en HN. No hay ninguna mención de esta vulnerabilidad en el blog oficial, y hoy tampoco hay una publicación nueva. Creo que cualquiera puede cometer errores, pero no ser transparentes cuando pasa algo así daña la imagen de la empresa
Es realmente extraño eso de que “mientras el exploit se estaba ejecutando, CodeRabbit dejaba directamente un comentario de advertencia de riesgo en el PR, cuando en realidad el hackeo estaba ocurriendo al ejecutar ese mismo PR”. Se siente surrealista vivir en un mundo donde la IA está diciendo que la están hackeando. Además, aunque el equipo de CodeRabbit respondió rápido, me preocupa más que “otros proveedores ni siquiera respondieron a los contactos de investigación y siguen siendo vulnerables”. Aplausos para el equipo de CodeRabbit, pero todos deberían moverse con mucho cuidado
En parte de la declaración oficial del CEO dicen que “el problema ocurrió porque Rubocop se ejecutó fuera del entorno sandbox”, pero sinceramente suena dudoso. ¿Por qué una sola tarea específica funcionaba de forma completamente distinta, y justo era la que terminó comprometida?
Fue un artículo realmente interesante, pero en realidad tampoco sorprende. Los usuarios agregan montones de apps con permisos amplios sin pensarlo mucho, y el sistema de permisos de github también tiene problemas, así que algo así era casi inevitable. Mucha gente concede de forma excesiva permisos de escritura en repositorios de github apps, e incluso permisos de nube. Aunque haya protección de ramas, a través de pull request todavía se puede obtener acceso privilegiado en github actions. Para configurarlo bien hay que modificar el audience de github oidc, y además está mal documentado. Incluso si le pides al proveedor de la app que haga una versión separada con menos permisos y algunas funciones desactivadas, a la mayoría no le importa y ni siquiera entiende el problema de seguridad. github debería permitir granular mejor los permisos de acceso de las apps, y en general los permisos deberían ser mucho más granulares
Es realmente impactante. Todavía ni termino de leer el artículo, pero ya estoy abrumado por todo lo que implica. La parte donde dicen que un atacante pudo haber inyectado malware en archivos de distribución de herramientas/bibliotecas/software open source a escala de 100 mil a 1 millón hace pensar que el mundo pudo haber colapsado. Cuesta incluso imaginar cuántos problemas parecidos seguirán existiendo
Creo que este tipo de fallas de seguridad tan graves debería clasificarse como “brecha” o “incidente”, y su divulgación debería ser obligatoria a través de la prensa. Estamos hablando de una herramienta con acceso a unos 7,000 clientes y 1 millón de repositorios, comprometida por un exploit simple que probablemente hasta un niño de 11 años podría hacer. Si era así de fácil de hackear, es muy probable que bots, black hats o APTs ya hayan entrado y se hayan instalado de forma silenciosa. Si ya estaban dentro antes de que el white hat lo revelara, entonces el parche solo detiene a nuevos atacantes, pero quizá no elimine a quienes ya están infiltrados. Sé que la seguridad es difícil, pero de verdad hay que ponerse las pilas
Uno de los problemas es que varios analizadores de código, bundlers y compiladores (por ejemplo, el compilador de Rust) pueden ejecutar código arbitrario sin ninguna advertencia. Por ejemplo, un atacante podría enviarme un repositorio diciendo que es una prueba técnica de contratación, y si yo corro “npm install” o un comando de compilación de Rust, mi computadora podría quedar comprometida de inmediato. O si hackean la PC de un compañero de trabajo y entra malware al repositorio, al final hasta una multinacional completa podría terminar comprometida por atacantes extranjeros. Quienes construyeron esta estructura fueron npm y el compilador de Rust. Estas herramientas deberían pedir confirmación explícita cada vez que ejecutan comandos externos (se podría guardar en caché una lista blanca para no preguntar siempre). Linux también debería ofrecer un sandbox seguro y fácil de usar para desarrolladores, pero hoy en día hay que construirlo manualmente. Además, hay tareas como instalar paquetes JS donde en algunos casos no hace falta ejecutar código externo. Y meter secretos y configuración en variables de entorno es una muy mala práctica. Parece que quien inventó la “12-factor app” no sabe que existen los flags de línea de comandos y los archivos de configuración
pspara ver toda la informaciónQue la llave de permisos (private key) para “poder convertirse en una github app a voluntad” estuviera guardada en una variable de entorno es una práctica realmente pésima. Cualquiera puede ser hackeado, pero esto es lo más básico de la gestión de secretos. La documentación oficial de github dice claramente que no se debe poner una private key en una variable de entorno. Es de lo más elemental
https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps#storing-private-keys
En el momento en que leí que el archivo de configuración de Rubocop permitía especificar la ruta de archivos Ruby extendidos, pensé “no me digas que ejecutaban extensiones de usuario directamente en producción...”, y efectivamente así era. Claro que tapar solo ese hueco no significa que el sistema sea realmente seguro. Dudo mucho que la mayoría de los linter hayan sido auditados o fuzzed contra entradas maliciosas; esto era básicamente dejar la puerta abierta con un letrero de neón diciendo “¡por favor, háckeenme!”