Si tu equipo se enfrenta a gem install o instalar el paquete, tanto si utilizas portátiles como CI, esta entrada es para ti. Es el tipo de cosa que nunca te esperarías. Una gema puede ejecutar código en tu equipo sin necesidad de un script de instalación. A continuación te explicamos cómo detectar cuatro gemas que extraen datos y que hemos encontrado en RubyGems, cómo desactivar este comportamiento con nuevos ajustes y cómo ver qué alertas detecta Aikido en tu feed.
TL;DR
- Al instalar una gema de Ruby, el código de dicha gema puede ejecutarse antes de que tu aplicación la cargue. Los scripts de compilación de las extensiones nativas se ejecutan durante la instalación. Los complementos de RubyGems se ejecutan al final de
gem instally de nuevo en cada gema posteriorcomando, inclusolista de gemasogem -v. - Npm ya ha resuelto este problema. A partir de la versión 12, npm permite activar o desactivar los scripts de instalación, incluidas las compilaciones nativas. RubyGems sigue ejecutando compilaciones de extensiones y complementos de forma predeterminada.
- Las versiones estables de RubyGems y Bundler 4.0.x no ofrecen ninguna opción para desactivar ninguno de estos comportamientos. Las versiones preliminares de la 4.1 incluyen opciones para desactivarlas, pero están desactivadas por defecto, por lo que tendrás que activarlas tú mismo.
- Las nuevas reglas de detección de Aikido han identificado cuatro gemas en RubyGems, publicadas entre 2013 y 2015, que envían el nombre de usuario del instalador, una captura de pantalla de macOS o una señal de localización a un servidor remoto. A fecha de 4 de noviembre de 2026, las gemas detectadas siguen pudiendo instalarse.
- Para bloquear las gemas maliciosas conocidas antes de que lleguen al equipo de un desarrollador, utiliza Aikido Device Protection. Comprueba
gem installyinstalar el paqueteen Ruby 3 y versiones posteriores con Aikido Intel, y bloquea el malware conocido antes de que llegue al sistema de archivos. - Si eres cliente de Aikido, Aikido te avisará de estas amenazas como un problema de malware en tu feed.
- En octubre informamos al equipo de seguridad de RubyGems sobre la extensión, las rutas de ejecución de los complementos y las cuatro gemas que extraen datos que habíamos encontrado. Nos hicieron algunas preguntas sobre los indicadores de exclusión voluntaria y no han hecho más comentarios al respecto.
Configuración de exclusión voluntaria
(Las opciones y ajustes de desactivación solo se aplican a la versión 4.1.0.beta3):
- Actualiza RubyGems y Bundler a la versión 4.1.0.beta3.
- Para
gem install, pasar--no-build-extension --no-install-plugin. - Para Bundler, ejecuta «bundle config set»
--global no_build_extension trueybundle config set --global no_install_plugin true. - En CI, configura
BUNDLE_NO_BUILD_EXTENSION=trueyBUNDLE_NO_INSTALL_PLUGIN=truee.
Qué hacer si ejecutas gemas de Ruby
Si utilizas gemas de Ruby, sigue estos pasos para asegurarte de que tu sistema está protegido. De lo contrario, puedes saltarte esta sección para obtener más información sobre cómo funcionan estas funciones.
1. Comprueba si hay cuatro gemas maliciosas. En cada proyecto, busca todos los archivos de bloqueo del directorio actual:
grep -rE '^ +(xmastree|ancient-city-ruby|hacky|et_phone_home) \(' --include=Gemfile.lock .Para comprobar las gemas instaladas sin ejecutar un comando «gem» (lo que cargaría los complementos), ejecuta:
ruby -e 'Gem.path.each { |p| puts Dir.glob("#{p}/gems/*") }' | grep -E '/(xmastree|ancient-city-ruby|hacky|et_phone_home)-[0-9]'Si utilizas rbenv u otro gestor de versiones de Ruby, repite este proceso para cada versión de Ruby. Las versiones afectadas figuran en la tabla del IOC al final de esta entrada.
2. Qué hacer si has instalado una de estas gemas. La carga útil se ejecuta desde un Rakefile (extensión nativa) durante la instalación, por lo que bastaba con instalar la gema para que se ejecutara.
- Detén todos los procesos que haya iniciado la gema.
- Desinstala la gema. Sustituye
NOMBRE_DE_LA_GEMAjunto con el nombre de la gema afectada:gem desinstalar NOMBRE_DEL_GEM --todo --ejecutables - Elimina la gema de las dependencias de tu proyecto. Elimínala de tu Gemfile y, a continuación, ejecuta
instalar el paquetepara regenerar elGemfile.lock. - Evalúa la posible exposición. Revisa las acciones de la gema en la sección IOC para determinar qué datos pueden haberse filtrado y toma las medidas oportunas.
3. Revisa qué complementos de RubyGems tienes instalados y desinstala los que no necesites. Ejecuta el comando que aparece a continuación y revisa cada directorio que muestre. RubyGems carga los complementos desde todas las rutas de gemas, no solo desde la predeterminada.
ruby -e 'Gem.path.each { |p| puts Gem.plugindir(p) }'4. Desactiva la compilación de extensiones y la instalación de complementos siempre que sea posible. Para ello se necesitan RubyGems y Bundler 4.1.0.beta3. Instálalos con gem update --system 4.1.0.beta3, que también actualiza Bundler. (gem update --system --pre no lo instala.)
- Para
gem install, pasar--no-build-extension --no-install-plugin. - Para Bundler, ejecuta
bundle config set --global no_build_extension trueybundle config set --global no_install_plugin true. - En CI, configura
BUNDLE_NO_BUILD_EXTENSION=trueyBUNDLE_NO_INSTALL_PLUGIN=true. Desactiva las compilaciones de extensiones únicamente en una tarea de integración continua (CI) en la que no se cargue la aplicación, como un paso de instalación de dependencias o de auditoría, a menos que todas las gemas de tu paquete cuenten con una compilación precompilada. De lo contrario, tu aplicación y tus pruebas no podrán cargar las gemas cuyas extensiones se hayan omitido.
Estas configuraciones solo impiden que el código se ejecute durante la instalación. El código de una gem maliciosa sigue ejecutándose cuando tu aplicación o tus pruebas la cargan, por lo que protegen únicamente los pasos de instalación, no todo aquello que requiera el paquete.
5. Es de esperar que las gems cuyas extensiones se hayan omitido dejen de cargarse. RubyGems no cargará una gem cuyas extensiones declaradas no se hayan compilado, incluso si su código nativo es opcional, y muestra el mensaje Ignoring <gem> because its extensions are not built. Bundler considera que la gema no está presente, por lo que bundle exec da error con Could not find <gem> in locally installed gems, y cada instalar el paquete lo vuelve a instalar.
Las compilaciones precompiladas para plataformas no declaran las extensiones, por lo que siguen cargándose. Una vez que hayas revisado una gema, vuelve a añadirle la extensión:
gem install: ejecutargem pristine <gem> --extensions. Esto también instala el complemento de la gem, si lo tiene, y dicho complemento se ejecuta a continuación. Para instalar solo el complemento, ejecutagem pristine <gem> --only-plugins.- Bundler: sin definir
no_build_extensiony ejecutainstalar el paqueteotra vez. Sigueno_install_pluginConfigúralo si quieres que los complementos permanezcan desactivados. Esto recompila todas las gemas del paquete cuyas extensiones se hayan omitido. La propia advertencia de Bundler indica que hay que ejecutarbundle pristine <gem>, pero en la versión 4.1.0.beta3 da error con el mismoNo se ha encontradoerror, porque Bundler no detecta que la gema esté instalada.paquete sin abrirFunciona para una gema en la que solo se ha omitido su complemento, aunque también recompila la extensión.
6. Revisa las gemas nuevas o actualizadas recientemente antes de instalarlas. En un entorno limpio, ejecuta gem fetch y luego descomprimir gem. Leer extconf.rb, mkrf_conf.rb, cualquier archivo Rakefile o CMake que figure en la lista de extensiones en el gemspec, y cualquier lib/rubygems_plugin.rb.
Hemos probado estos comandos en Ruby 4.0.9 con RubyGems y Bundler 4.0.23 (la versión estable actual) y 4.1.0.beta3. Las opciones de exclusión, la configuración y los pasos de recuperación solo se aplican a la versión 4.1.0.beta3.
Dos formas en las que una gema ejecuta código en tu ordenador
Ruby ofrece dos formas de ejecutar el código de una gem sin necesidad de ningún tipo de script de instalación: las extensiones nativas y los complementos de RubyGems. Ambas permiten a un atacante ejecutar una carga maliciosa antes de que el desarrollador inicie la aplicación. Un script de compilación de extensiones malicioso podría robar credenciales durante la instalación. Un complemento de RubyGems malicioso podría hacer lo mismo al final de ese mismo gem install, y de nuevo cada vez que el desarrollador ejecute un comando «gem».
Método 1: Extensiones nativas
Una joya afirma extensiones en su gemspec (el manifiesto de la gema). Si uno de ellos es un extconf.rb script de compilación: RubyGems ejecuta ese archivo Ruby durante la instalación y, a continuación, ejecuta el Makefile que genera. Lo que sea que contenga ese archivo Ruby se ejecuta durante la instalación, del mismo modo que node-gyp ejecuta compilaciones nativas para los paquetes de npm.
RubyGems también se ejecuta mkrf_conf.rb como script de Ruby durante la instalación, si una gem lo incluye en extensiones, y a continuación ejecuta rastrillo en el mismo directorio. Además de estos scripts de Ruby, RubyGems admite compilaciones con `configure`, `Rakefile`, CMake y Cargo, cada uno de los cuales ejecuta el código a través de su propia herramienta de compilación.
Lo que un atacante aporta a una gema:
- Un archivo,
extconf.rbomkrf_conf.rb(por ejemplo,ext/foo/extconf.rb), que contenga el código Ruby que deseen - Una línea en el gemspec:
spec.extensions = ["ext/foo/extconf.rb"]
Por qué es fácil que se cuele: Muchas herramientas excelentes y legítimas, como bcrypt y bootsnap, utilizan extconf.rb. Tiene el mismo aspecto que cualquier otro archivo de compilación y no hay una sección separada de «scripts» que llame la atención del revisor.
Método 2: Complementos de RubyGems
Si una gema incluye un archivo llamado rubygems_plugin.rb, RubyGems lo instala como un complemento. Durante la instalación, RubyGems escribe un pequeño cargador para ese archivo en su directorio de complementos, y cada comando «gem» posterior carga lo que hay en ese directorio.
Lo que un atacante añade a una gema: un archivo con el nombre exacto de rubygems_plugin.rb en la raíz de una ruta «require» declarada, normalmente lib/rubygems_plugin.rb.
Cuándo se ejecuta:
- RubyGems carga un complemento recién instalado inmediatamente al finalizar
gem install(si no hay ninguna otra versión instalada). - Posteriormente, carga todos los complementos instalados cada vez que se ejecuta un comando «gem», incluidos los comandos de solo lectura como
lista de gemas,búsqueda de gemas, ygem -v, así como comandos relacionados con gemas que no guardan relación con el tema. - El complemento se ejecuta repetidamente con cada comando mientras la gema siga instalada.
Por qué es fácil que se cuele: es un archivo en lib/ con un nombre especial. No es necesaria una declaración independiente del complemento, por lo que un revisor que busque puntos de enganche de ejecución explícitos podría pasarlo por alto. RubyGems notifica las excepciones de carga de complementos como advertencias, por lo que el comando continúa ejecutándose aunque falle un complemento.
Gems que Bundler instala en proveedor/paquete o una personalización BUNDLE_PATH funcionan de forma un poco diferente. Un simple lista de gemas no carga sus complementos, pero bundle exec gem list sí.
npm ya ha pasado por esto
Npm aprendió por las malas que la seguridad durante la instalación debe abarcar algo más que los scripts del ciclo de vida. En la campaña «Miasma», los atacantes cambiaron el punto de activación de su ataque de package.json en binding.gyp, el archivo de compilación nativo de npm, que node-gyp Se ejecuta automáticamente al instalarlo. Comprueba que solo los archivos en seguimiento package.json Se pasó por alto la instalación de hooks. NPM 12 respondió haciendo que los scripts de instalación de dependencias fueran opcionales, incluidas las compilaciones de node-gyp.
Ruby tiene el mismo problema y no disponemos de una versión estable que lo solucione. Un archivo «extconf.rb» parece una configuración de compilación normal, y un «rubygems_plugin.rb» no requiere ninguna declaración, por lo que ninguno de los dos parece un script de instalación que deba revisarse. Los atacantes ya también tienen en el punto de mira a los desarrolladores de Ruby. En la campaña «SleeperGem», los atacantes publicaron versiones maliciosas de gemas desde lo que parecen ser cuentas de mantenedores inactivas que habían sido comprometidas.
Un ejemplo reciente muestra cómo se utiliza esta ruta de ejecución para distribuir malware. Tanto Oliver Smith, del equipo de investigación de Aikido, como Socket informaron sobre la versión 1.0.1 de strutil-core. Su archivo extconf.rb descargaba el entorno de ejecución Bun y ejecutaba una carga útil integrada para el robo de credenciales durante la instalación. El malware comparte componentes funcionalmente idénticos con descendientes de Shai-Hulud documentados anteriormente, aunque el código compartido no permite determinar quién estaba detrás de él. RubyGems retiró ambas versiones publicadas el 1 de noviembre. Este caso es independiente de nuestra revelación de octubre, pero ilustra la misma ruta de ejecución de extensiones nativas descrita anteriormente.
1 de cada 13 gemas populares ejecuta código al instalarse
El 26 de octubre de 2026, seleccionamos las aproximadamente 1.000 gemas más descargadas de bestgems.org y leímos sus especificaciones publicadas (gemspecs) para comprender hasta qué punto son habituales hoy en día las extensiones nativas y los archivos de complementos. Hay que tener en cuenta que el hecho de que las gemas utilicen o no estos mecanismos de instalación en la actualidad no es un indicador del riesgo, ya que los atacantes pueden utilizarlos en cualquier momento. Sin embargo, sí que muestra lo habituales que parecen estos pasos de compilación a ojos de un revisor.
- Extensiones nativas: 74 de 997 (aproximadamente 1 de cada 13) declaran pasos de compilación de extensiones, entre las que se incluyen bcrypt, bigdecimal, bootsnap, bson, debug y muchas gemas habituales relacionadas con bases de datos y análisis sintáctico.
- Archivos de complementos: se incluyen 2 de 997 (rdoc y yard)
rubygems_plugin.rb. Ambos se cargan en comandos gem posteriores cuando se instalan en el entorno activo.
Todavía se pueden instalar cuatro programas de prueba de concepto que envían datos a sus creadores
Al probar nuestras reglas de detección, encontramos cuatro joyas, publicadas entre 2013 y 2015, que ejecutan código durante la instalación: xmastree, ancient-city-ruby, hacky y et_phone_home. Estas envían el nombre de usuario del instalador, una captura de pantalla de macOS realizada de forma silenciosa o una simple señal a un servidor remoto.
Parecen pruebas de concepto o pruebas de investigación, pero se ejecutan al instalarse y envían datos fuera del equipo. Las versiones afectadas y los destinos figuran en la tabla de IOC al final de esta entrada.
Calendario de divulgación de nuestras conclusiones
- 27 de octubre de 2026: Informamos al equipo de seguridad de RubyGems sobre las rutas de ejecución de las extensiones y los complementos. Nos plantearon algunas preguntas sobre los indicadores de exclusión voluntaria y no han hecho más comentarios al respecto.
- 30 de octubre de 2026: Informamos al equipo de seguridad de RubyGems sobre los cuatro gem.
- 4 de noviembre de 2026: Las gemas mencionadas siguen estando disponibles en RubyGems.
Las RubyGems estables no tienen botón de apagado
Quizá pienses que basta con pasar las banderas --sin-extensión-de-compilación y --no-install-plugin a gem. Sin embargo, estas dos opciones solo están presentes en las versiones preliminares de la 4.1, e incluso en la 4.1.0.beta3 ambos comportamientos permanecen activados a menos que los desactives. En la versión estable 4.0.x, gem install las rechaza por considerarlas una opción inválida.
Cómo Aikido detecta esto
Si utilizas Aikido, revisa tu feed central y filtra los problemas relacionados con malware. Cuando aparece una gema maliciosa en uno de los archivos de bloqueo de tus repositorios, Aikido la marca como un problema de malware. Aikido vuelve a escanear cada noche, pero te recomendamos que inicies un nuevo escaneo manual de inmediato si crees que puedes estar afectado.
Para detener las gemas maliciosas conocidas antes de que lleguen al equipo de un desarrollador, utiliza Aikido Device Protection. Esta herramienta comprueba los comandos «gem install» y «bundle install» en Ruby 3 y versiones posteriores con Aikido Intel, y bloquea el malware conocido antes de que acceda al sistema de archivos. Puedes implementarla a través de tu herramienta de gestión de dispositivos móviles (MDM).
