惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
MyScale Blog
MyScale Blog
The GitHub Blog
The GitHub Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
量子位
博客园 - 司徒正美
V
V2EX
I
InfoQ
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
美团技术团队
N
Netflix TechBlog - Medium
L
LangChain Blog
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Stack Overflow Blog
Stack Overflow Blog
A
About on SuperTechFans
Microsoft Azure Blog
Microsoft Azure Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
31 paquetes npm de Red Hat comprometidos roban credencial...
lu1tr0n · 2026-06-01 · via DEV Community

El 1 de junio de 2026, la firma de seguridad StepSecurity reportó que 31 paquetes npm comprometidos aparecieron publicados bajo el scope @redhat-cloud-services, el namespace oficial que Red Hat usa para los clientes JavaScript de su plataforma Hyperscale Cloud Console (Insights, RBAC, remediations y compañía). En conjunto, las versiones maliciosas sumaban 158.590 descargas semanales.

No es un robo de tokens cualquiera. El payload roba credenciales de nube y CI/CD, se auto-propaga publicando nuevas versiones backdooreadas con los tokens que captura, y deja persistencia incluso dentro de tu editor. Si instalaste alguna versión afectada, la recomendación oficial es asumir que tu pipeline o tu máquina ya están comprometidos.

TL;DR

  • El 1 de junio de 2026, StepSecurity detectó 31 paquetes del scope @redhat-cloud-services en npm con versiones maliciosas.
  • Las versiones afectadas sumaban 158.590 descargas semanales; las más usadas: types@3.6.1 y frontend-components@7.7.2.
  • El malware se ejecuta vía script preinstall, antes de cualquier código de tu app, al correr npm install.
  • Roba tokens de GitHub, npm, AWS, GCP, Azure, Kubernetes, Vault, claves SSH y archivos .env del sistema.
  • Lee /proc//mem del proceso Runner.Worker para extraer secretos en vivo de GitHub Actions.
  • Se auto-propaga: usa tokens npm robados y el parámetro bypass_2fa para publicar nuevas versiones backdooreadas.
  • Deja persistencia en ~/.claude/settings.json (hook SessionStart) y .vscode/tasks.json (folderOpen).

Qué pasó

El reporte arrancó como un issue de seguridad en el repositorio RedHatInsights/javascript-clients (issue #492), abierto por la cuenta sailikhith-stepsecurity. En paralelo, StepSecurity publicó un análisis técnico y abrió issues equivalentes en otros dos repositorios de Red Hat: frontend-components y platform-frontend-ai-toolkit. La conclusión: alguien logró publicar versiones nuevas de 31 librerías legítimas, todas firmadas con la cuenta de mantenedor del proyecto.

El patrón es idéntico al de otros gusanos recientes de npm: no se trató de un typosquatting (paquetes con nombres parecidos a los reales) sino de un compromiso directo de paquetes auténticos. Es decir, no hace falta que el desarrollador se equivoque escribiendo el nombre; basta con que tenga una de estas dependencias en su árbol y corra una instalación para activar el payload. Por eso este tipo de paquetes npm comprometidos es tan peligroso: el vector de entrada es la confianza que ya le tenías al proveedor.

⚠️ Ojo: que un paquete venga de un proveedor serio como Red Hat no lo hace inmune. El compromiso fue de la cuenta de publicación, no del código fuente en GitHub. El tarball que llega a tu node_modules puede diferir del repositorio público.

Cómo funciona el malware

El punto de entrada es un script preinstall declarado en el package.json del paquete. Los lifecycle scripts de npm se ejecutan automáticamente durante la instalación, y preinstall corre antes que cualquier otra cosa: antes de compilar, antes de que tu aplicación arranque, con los permisos del usuario que lanzó npm install. Ese es el momento exacto en que el implante toma el control.

A partir de ahí, StepSecurity documentó una cadena de ofuscación de cuatro capas pensada para frustrar el análisis estático:

  • ROT-21 + arrays numéricos — el index.js pesa unos anómalos 4,2 MB y guarda su contenido como códigos de carácter codificados con ROT-21.
  • AES-128-GCM — dos blobs cifrados se descifran en tiempo de ejecución: _b (un descargador del runtime Bun) y _p (el implante principal, 634 KB ya descifrado).
  • obfuscator.io — un alfabeto base64 no estándar con una tabla de 2.219 cadenas rotada 284 ciclos.
  • Cifra propia "B5" — valores sensibles protegidos con PBKDF2 (200.000 iteraciones, SHA-256, salida de 32 bytes).

El detalle del descargador de Bun no es decorativo: al traer su propio runtime, el malware se independiza de la versión de Node que tengas instalada y reduce la huella de detección de las herramientas que vigilan procesos de Node.

Del npm install al robo de credenciales: la cadena de ejecución.

graph TD
  A["npm install"] --> B["preinstall hook"]
  B --> C["index.js 4.2MB ofuscado"]
  C --> D["descifra _b: descarga Bun"]
  C --> E["descifra _p: implante 634KB"]
  E --> F["roba credenciales"]
  E --> G["persistencia editor"]
  E --> H["auto-propagacion npm"]
  F --> I["exfiltra via HTTPS / GitHub"]

Enter fullscreen mode Exit fullscreen mode

Qué credenciales roba

El implante barre el sistema buscando todo secreto útil para moverse lateralmente. Según el análisis, los objetivos incluyen:

  • GitHub y npmGITHUB_TOKEN, ACTIONS_RUNTIME_TOKEN, ACTIONS_ID_TOKEN_REQUEST_TOKEN y NPM_TOKEN.
  • AWSAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN y el archivo ~/.aws/credentials.
  • Multinube — claves de cuentas de servicio de GCP, service principals de Azure y tokens de Kubernetes.
  • Herramientas dev — tokens de HashiCorp Vault, claves SSH privadas, config de Docker y claves GPG.
  • Archivos .env — recorre el sistema de archivos buscando variables de entorno en disco.

El componente más sofisticado es la extracción desde memoria. En un runner de GitHub Actions, el implante lee /proc/<pid>/mem del proceso Runner.Worker para sacar secretos directamente de la memoria viva, apuntando a las variables marcadas como isSecret: true por la API de Actions. Esto le permite capturar credenciales que nunca tocaron el disco ni quedaron en una variable de entorno persistente.

La exfiltración usa dos canales. El primero es HTTPS directo. El segundo es un dead-drop en GitHub: con el GITHUB_TOKEN robado crea refs y commits que contienen los datos sustraídos, de modo que el tráfico sale por api.github.com y se mimetiza con el ruido normal de un pipeline de CI.

El gusano: auto-propagación y bypass de 2FA

Lo que eleva este incidente de "robo de credenciales" a "gusano de cadena de suministro" es su capacidad de republicación autónoma. Con los tokens de npm capturados, el payload intenta publicar nuevas versiones backdooreadas de cualquier paquete al que la cuenta de la víctima tenga acceso. Y para eso explota el parámetro bypass_2fa de npm, que le permite saltarse la protección de doble factor que en teoría debería frenar publicaciones no autorizadas.

💭 Clave: el 2FA protege el login interactivo, pero los tokens de automatización históricamente podían publicar sin segundo factor. Ese hueco es justo lo que el gusano aprovecha para multiplicarse sin intervención humana.

El resultado es un efecto dominó: cada desarrollador o pipeline infectado se vuelve un nuevo emisor de paquetes maliciosos hacia el ecosistema. Es el mismo modelo de propagación que vimos en oleadas previas de npm, y explica por qué la ventana entre la publicación y la detección importa tanto.

Persistencia: cuando borrar el paquete no alcanza

Aunque desinstales la dependencia, el malware deja dos anclas pensadas para sobrevivir:

  • Secuestro de Claude Code — inyecta un hook SessionStart en ~/.claude/settings.json, de modo que el código se reactiva cada vez que arranca una sesión del agente.
  • Inyección en VS Code — escribe una tarea con disparador folderOpen en .vscode/tasks.json, que se ejecuta apenas abrís la carpeta del proyecto en el editor.

Estos dos mecanismos son lo que convierte una limpieza superficial en falsa sensación de seguridad. Eliminar node_modules y reinstalar versiones limpias no toca esos archivos.

Datos y cifras

El alcance se entiende mejor mirando los paquetes más descargados dentro del lote de paquetes npm comprometidos:

  • @redhat-cloud-services/types@3.6.1 — 15.060 descargas semanales.
  • @redhat-cloud-services/frontend-components-utilities@7.4.1 — 14.166.
  • @redhat-cloud-services/frontend-components@7.7.2 — 13.721.
  • @redhat-cloud-services/rbac-client@9.0.3 — 13.551.

En total, 31 paquetes y 158.590 descargas semanales combinadas. Otras versiones afectadas confirmadas en el issue incluyen chrome@2.3.1, insights-client@4.0.4, host-inventory-client@5.0.3, notifications-client@6.1.4, los tres paquetes MCP (hcc-feo-mcp@0.3.1, hcc-kessel-mcp@0.3.1, hcc-pf-mcp@0.6.1) y varios de la familia frontend-components-*.

Cómo saber si estás afectado y qué hacer

El primer paso es revisar si tenés instalada alguna de las versiones señaladas. Podés inspeccionar el árbol resuelto con npm ls en tu proyecto:

# macOS / Linux
npm ls --all 2>/dev/null | grep '@redhat-cloud-services'

# Windows (PowerShell)
npm ls --all 2>$null | Select-String '@redhat-cloud-services'

# Windows (CMD)
npm ls --all | findstr "@redhat-cloud-services"

Enter fullscreen mode Exit fullscreen mode

Si aparece alguna versión de la lista, no esperés: rotá todas las credenciales que hayan podido estar accesibles desde esa máquina o ese runner (tokens de npm, GitHub, AWS, GCP, Azure, claves SSH) y revisá los archivos de persistencia:

# Revisar persistencia (macOS / Linux)
cat ~/.claude/settings.json
cat .vscode/tasks.json

# Windows (PowerShell)
Get-Content $env:USERPROFILE\.claude\settings.json
Get-Content .vscode\tasks.json

Enter fullscreen mode Exit fullscreen mode

Para futuras instalaciones, la mitigación más directa contra payloads en preinstall es desactivar los lifecycle scripts:

# Instalar sin ejecutar scripts de ciclo de vida
npm install --ignore-scripts

# Hacerlo permanente en el proyecto (.npmrc)
echo "ignore-scripts=true" >> .npmrc

Enter fullscreen mode Exit fullscreen mode

💡 Tip: en CI, anclá versiones exactas con un lockfile y usá npm ci en vez de npm install. npm ci respeta el package-lock.json al pie de la letra, lo que evita que una versión "parche" recién publicada entre sin que lo notes.

También conviene pinear versiones conocidas-buenas con overrides en el package.json hasta que Red Hat publique versiones limpias y npm despublique las maliciosas:

{
  "overrides": {
    "@redhat-cloud-services/types": "3.5.0",
    "@redhat-cloud-services/frontend-components": "7.7.1"
  }
}

Enter fullscreen mode Exit fullscreen mode

Auditar el árbol de dependencias es el primer paso de la respuesta.

Contexto: por qué los preinstall scripts son el talón de Aquiles

Los lifecycle scripts existen por buenas razones: compilar bindings nativos, generar archivos, preparar el entorno. Pero le dan a cualquier paquete del árbol la capacidad de ejecutar código arbitrario en tu máquina con solo instalarlo. En un proyecto típico de frontend, ese árbol tiene cientos de dependencias transitivas, y basta una comprometida para abrir la puerta.

Este incidente se suma a una racha de ataques con el mismo molde durante 2025 y 2026: scopes legítimos comprometidos, payloads que roban tokens de CI y se auto-replican publicando nuevas versiones. La superficie de ataque ya no es solo el código que escribís, sino toda la maquinaria que lo construye y lo despliega. Tratar al pipeline de CI/CD como un entorno de confianza es, hoy, una apuesta peligrosa.

Qué sigue

npm suele despublicar las versiones maliciosas en cuestión de horas tras la confirmación, y Red Hat publicará versiones limpias con número incrementado. Pero la responsabilidad de la limpieza recae en cada equipo: rotar credenciales, purgar la persistencia y auditar qué se publicó desde cuentas potencialmente comprometidas. Para organizaciones que dependen del scope @redhat-cloud-services, este es el recordatorio de que la seguridad de la cadena de suministro no se delega: se verifica.

📖 Resumen en Telegram: Ver resumen

Preguntas frecuentes

¿Cuántos paquetes fueron comprometidos y cuántas descargas tenían?

Fueron 31 paquetes del scope @redhat-cloud-services, que en conjunto sumaban 158.590 descargas semanales según el análisis de StepSecurity del 1 de junio de 2026.

¿Cómo se activa el malware?

A través de un script preinstall en el package.json. Se ejecuta automáticamente al correr npm install, antes que cualquier código de tu aplicación, con los permisos del usuario que lanzó la instalación.

Desinstalé el paquete, ¿ya estoy a salvo?

No necesariamente. El malware deja persistencia en ~/.claude/settings.json (hook SessionStart) y en .vscode/tasks.json (disparador folderOpen). Hay que revisar y limpiar esos archivos además de reinstalar versiones limpias.

¿Qué credenciales debería rotar?

Todas las que hayan estado accesibles desde la máquina o el runner afectado: tokens de npm y GitHub, claves de AWS, GCP y Azure, tokens de Kubernetes y Vault, claves SSH y GPG, y cualquier secreto en archivos .env.

¿Cómo prevengo este tipo de ataques en el futuro?

Usá npm ci con lockfile en CI, considerá ignore-scripts=true en .npmrc, aplicá overrides para pinear versiones conocidas-buenas y monitoreá feeds de seguridad de la cadena de suministro.

¿Esto es lo mismo que el ataque a TanStack?

Es de la misma familia de gusanos de npm, pero un incidente distinto: otro scope (@redhat-cloud-services), otras versiones y otra fecha. Comparten el patrón de auto-propagación y robo de tokens de CI.

Referencias

📱 ¿Te gusta este contenido? Únete a nuestro canal de Telegram @programacion donde publicamos a diario lo más relevante de tecnología, IA y desarrollo. Resúmenes rápidos, contenido fresco todos los días.