Ataque a la cadena de suministro Miasma: código malicioso detectado en paquetes npm de @redhat-cloud-services
1 de junio de 2026
0 minutos de lecturaEl 1 de junio de 2026, investigadores identificaron código malicioso integrado en al menos 32 versiones de paquetes publicados bajo el espacio de nombres npm @redhat-cloud-services, un conjunto de componentes frontend y clientes de API que impulsan Red Hat Hybrid Cloud Console. Las versiones comprometidas incluyen un script preinstall que ejecuta una carga útil ofuscada en cuanto se instala un paquete, roba credenciales de desarrolladores y de la nube, e intenta propagarse a otros paquetes que la víctima pueda publicar. Los paquetes afectados promedian en conjunto alrededor de 80.000 descargas por semana, por lo que el alcance va mucho más allá de los propios pipelines de Red Hat.
La campaña se conoce como Miasma, y su carga útil es una versión ligeramente modificada derivada del gusano (Mini) Shai-Hulud, cuyo código abierto publicó TeamPCP a principios de este año. Si instalaste algún paquete @redhat-cloud-services o desarrollaste un proyecto que depende de uno, considéralo un incidente activo y asume que todos los secretos que estuvieron en contacto con las máquinas afectadas quedaron expuestos.
Resumen
Qué: Código malicioso (gusano autorreplicante + ladrón de credenciales) integrado en versiones publicadas de npm.
Espacio de nombres: @redhat-cloud-services (componentes frontend y clientes de API de Red Hat Hybrid Cloud Console).
Alcance: Al menos 32 versiones de paquetes en el espacio de nombres, con ~80.000 descargas semanales en conjunto. Publicadas en dos oleadas.
CVE: No se asignó ninguno. Se rastrea mediante avisos de Snyk. Snyk califica el aviso principal con 9.3 (Crítico, CVSS v4.0) y una madurez de explotación de Ataque activo.
Causa raíz: Una cuenta de GitHub de un empleado de Red Hat fue comprometida y se usó para publicar commits huérfanos maliciosos que solicitaron un token OIDC para publicar en npm y publicaron paquetes con procedencia SLSA válida.
Estado: La mayoría de las versiones maliciosas se retiraron de npm pocas horas después de la divulgación; algunas seguían disponibles mientras continuaba el análisis. La investigación sigue en curso.
Acción: Fija versiones seguras en lugar de las afectadas, vuelve a instalar con los scripts desactivados y rota todas las credenciales a las que se podía acceder desde una estación de trabajo o un runner de CI afectados.
Qué ocurrió
Los paquetes del espacio de nombres @redhat-cloud-services son dependencias de compilación de Hybrid Cloud Console: componentes React compartidos (@redhat-cloud-services/frontend-components, frontend-components-utilities, frontend-components-notifications), clientes de API generados (rbac-client, host-inventory-client, compliance-client y alrededor de dos docenas más) y herramientas de soporte. Varios de ellos reciben un volumen considerable de tráfico por sí solos. Como comprobación rápida del alcance informado, la API de descargas de npm indica que los paquetes más grandes, como @redhat-cloud-services/types, registran decenas de miles de descargas por semana:
Al sumar la última semana completa (del 25 al 31 de mayo de 2026) para los paquetes afectados, se obtienen aproximadamente 79.000 descargas, una cifra coherente con las ~80.000 mencionadas para este incidente. Las modificaciones no autorizadas se identificaron por primera vez el 1 de junio de 2026.
Las versiones maliciosas se publicaron en dos oleadas el 1 de junio. Para cuando se emitieron los avisos, npm ya había retirado la mayoría de las versiones maliciosas, aunque algunas seguían disponibles durante el análisis.
Detalles técnicos
El disparador durante la instalación
Cada versión comprometida agrega un hook que se ejecuta durante la instalación. npm ejecuta automáticamente los scripts preinstall durante npm install, antes de que se ejecute tu propio código, así que basta con resolver la dependencia para activar la carga útil:
El archivo index.js que invoca es un archivo JavaScript inusualmente grande y muy ofuscado. El autor recurrió a eval() y a la decodificación de cadenas basada en ROT para ocultar la lógica, una técnica que ya se había visto en variantes anteriores de Shai-Hulud. Una vez decodificada, la carga útil es un gusano y recolector de credenciales de varias etapas.
Qué hace la carga útil
El núcleo funcional coincide con el framework (Mini) Shai-Hulud, aunque las referencias a la mitología griega reemplazan los elementos estéticos originales inspirados en Dune (como el uso de spartan). Los repositorios recién creados por los atacantes llevan la descripción Miasma: The Spreading Blight, una señal útil para la búsqueda de indicadores.
Al ejecutarse, la carga útil:
Recopila secretos y credenciales del entorno local y del contexto de CI: variables de entorno, tokens de
~/.npmrc, claves SSH, tokens de GitHub y secretos de CI/CD.Enumera identidades en la nube. El cambio destacado en esta variante es la incorporación de dos nuevos recolectores para GCP y Azure, que enumeran todas las identidades que puede asumir el host infectado, no solo secretos estáticos. Las variantes anteriores se enfocaban en extraer credenciales; esta busca mapear y acceder al plano de control de la nube.
Se propaga por sí mismo. Consulta el registro para identificar otros paquetes que la identidad comprometida pueda publicar y los vuelve a publicar con la misma carga útil. Así, un solo mantenedor comprometido puede desencadenar un gusano.
Causa raíz: una cuenta comprometida, procedencia válida
Este es un detalle que vale la pena analizar con atención. El código malicioso no se introdujo mediante un paquete con nombre engañoso ni una dependencia transitiva envenenada. La evidencia indica que la cuenta de GitHub de un empleado de Red Hat fue comprometida y se usó para insertar commits huérfanos maliciosos directamente en dos repositorios RedHatInsights, sin pasar por la revisión de código.
Esos commits agregaron un workflow mínimo de GitHub Actions que:
Se activaba al hacer push a cualquier rama.
Solicitaba un token de identidad OIDC de GitHub mediante
id-token: write.Ejecutaba una carga útil ofuscada (
_index.js) que publicaba los paquetes en npm.
Como la publicación se ejecutó dentro del contexto de Actions de un repositorio legítimo, las versiones resultantes se distribuyeron con atestaciones de procedencia SLSA válidas. La procedencia era técnicamente correcta: el paquete sí fue compilado por el workflow de ese repositorio. Lo que no podía indicar era que el workflow no estaba autorizado. Esta es la misma brecha que TeamPCP aprovechó contra TanStack unas semanas antes, donde una procedencia falsificada pero válida permitió que paquetes maliciosos superaran una verificación superficial. También recuerda el robo de tokens en el runner observado en el compromiso de la acción de GitHub de Trivy. Verificar la procedencia es necesario, pero no basta por sí solo.
Análisis del impacto
Las cifras directas de descargas subestiman la exposición real. Estos paquetes son dependencias de compilación de una consola empresarial, así que la mayoría de las instalaciones ocurren en estaciones de trabajo de desarrolladores y runners de CI: precisamente los entornos con más credenciales de nube de larga duración, tokens de registros y PAT de GitHub. El comportamiento de gusano agrava el problema: un solo desarrollador que instale una versión afectada y tenga permisos para publicar otros paquetes puede iniciar la siguiente oleada.
Es posible que te hayas visto afectado si, desde la primera publicación maliciosa el 1 de junio de 2026, se ejecutó alguna de las siguientes acciones:
Un
npm install/npm cique resolvió una versión afectada de@redhat-cloud-servicesen una estación de trabajo o un runner de CI.Una compilación en un entorno de nube donde el runner tenía identidades de GCP, AWS o Azure, dado que ahora existen recolectores de identidades en la nube.
La explotación no requiere ninguna configuración especial de tu parte. El hook preinstall se ejecuta de forma predeterminada. El único requisito es haber instalado una versión afectada.
Detección
1. Busca versiones afectadas en tus archivos de bloqueo. Busca el espacio de nombres en package-lock.json / pnpm-lock.yaml / yarn.lock:
Compara las versiones resueltas con los avisos de Snyk que aparecen en la sección Referencias. El aviso principal de Snyk señala @redhat-cloud-services/frontend-components en las versiones <=7.7.2; los límites varían según el paquete, así que consulta cada aviso.
2. Analiza con Snyk. La base de datos de Snyk ya incluye avisos para las versiones maliciosas, así que una prueba estándar las detectará:
En las organizaciones, el descubrimiento de activos y la priorización basada en riesgos te ayudan a encontrar todos los proyectos y runners que descargaron una versión afectada, y luego a priorizar la corrección según el nivel real de exposición de credenciales de cada entorno, en lugar de perseguir cada instalación.
3. Busca indicios de compromiso. Aunque elimines el paquete, es posible que la carga útil ya se haya ejecutado. Busca lo siguiente:
Repositorios nuevos e inesperados en tu organización de GitHub, especialmente los que tengan la descripción
Miasma: The Spreading Blight.Workflows de GitHub Actions que no reconozcas, en particular los mínimos que solicitan
id-token: writey se activan al hacer push a cualquier rama.Tokens de acceso personal, claves de implementación o tokens de npm recién creados que no hayas generado.
Lecturas anómalas de metadatos de identidad de GCP y Azure desde runners de compilación.
Corrección
El orden importa. Como se sabe que esta familia de malware instala mecanismos de persistencia y, en algunas variantes, activadores destructivos, limpia el host antes de empezar a revocar los tokens que está vigilando.
1. Deja de instalar las versiones maliciosas. Fija o sobrescribe tus dependencias para usar versiones seguras conocidas, o elimina temporalmente los paquetes afectados. Luego, verifica que tu archivo de bloqueo ya no resuelva una versión señalada.
2. Vuelve a instalar con los scripts desactivados. Cuando vuelvas a compilar un árbol de dependencias potencialmente afectado, bloquea los scripts de instalación para evitar que se active otra vez una versión maliciosa que siga presente:
Puedes establecerlo como opción predeterminada para un entorno:
(Vuelve a habilitar los scripts de forma selectiva para los paquetes que realmente necesiten pasos de compilación.)
3. Elimina la persistencia. Audita y limpia todos los hooks instalados por los atacantes antes de tocar las credenciales: configuración de editores y agentes, como .claude/settings.json y .vscode/tasks.json.
4. Rota todo lo que haya estado al alcance. Asume que quedaron expuestos todos los secretos visibles desde una máquina afectada y rótalos por orden de prioridad: tokens de npm, PAT de GitHub y claves SSH, y luego credenciales de la nube. Debido a los nuevos recolectores, presta especial atención a las identidades de nube como GCP, AWS y Azure, incluidos los roles que pudiera asumir un runner de CI, no solo las claves estáticas.
5. Limpia GitHub. Elimina los repositorios y workflows no autorizados, revisa las ejecuciones recientes de Actions para detectar el patrón de publicación OIDC descrito arriba y confirma que no se hayan publicado paquetes inesperados desde tus cuentas.
6. Refuerza el pipeline. De ahora en adelante: exige revisiones en las ramas protegidas para impedir que commits huérfanos publiquen paquetes; limita la confianza de OIDC a ramas y workflows específicos, en lugar de aplicarla a repositorios completos; exige 2FA con protección de publicación en npm; y combina la verificación de procedencia con comprobaciones de comportamiento, en vez de confiar únicamente en las atestaciones. Las listas de dependencias permitidas, la generación de SBOM y un periodo de espera desde la publicación antes de adoptar nuevas versiones reducen la ventana que aprovechan este tipo de ataques. Las guías de Snyk sobre las 10 mejores prácticas de seguridad para npm y los 8 consejos para proteger tu pipeline de CI/CD cubren el resto.
Cronología
1 de junio de 2026: Se publicaron versiones maliciosas en una primera oleada en todo el espacio de nombres
@redhat-cloud-services.1 de junio de 2026 (alrededor de la 1 p. m. UTC): Se divulgó públicamente el compromiso; se retiró la mayoría de las versiones maliciosas, pero dos seguían disponibles.
1 de junio de 2026 (alrededor de las 2 p. m. UTC): Se publicó la causa raíz: cuenta de un empleado comprometida y paquetes publicados mediante OIDC con procedencia SLSA válida.
1 de junio de 2026 (alrededor de las 2:20–3 p. m. UTC): Se identificó una segunda oleada de commits maliciosos y se agregó a la cobertura, junto con detalles de la carga útil sobre los nuevos recolectores de identidades de GCP/Azure.
2 de junio de 2026: Se agregaron a los paquetes existentes las versiones comprometidas que se descubrieron recientemente.
En curso: Ya están disponibles los avisos de Snyk para los paquetes afectados. La investigación continúa.
Consulta Snyk Vulnerability DB
Datos confiables e información práctica para ayudarte a desarrollar software de forma segura.
