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

推荐订阅源

The Hacker News
The Hacker News
GbyAI
GbyAI
雷峰网
雷峰网
罗磊的独立博客
WordPress大学
WordPress大学
博客园_首页
Hugging Face - Blog
Hugging Face - Blog
The Cloudflare Blog
云风的 BLOG
云风的 BLOG
F
Full Disclosure
Google DeepMind News
Google DeepMind News
C
Cyber Attacks, Cyber Crime and Cyber Security
NISL@THU
NISL@THU
S
Schneier on Security
T
Tor Project blog
C
Cybersecurity and Infrastructure Security Agency CISA
Recent Announcements
Recent Announcements
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Check Point Blog
P
Palo Alto Networks Blog
C
CERT Recently Published Vulnerability Notes
S
Secure Thoughts
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Last Week in AI
Last Week in AI
T
Threatpost
I
Intezer
Y
Y Combinator Blog
G
GRAHAM CLULEY
MyScale Blog
MyScale Blog
阮一峰的网络日志
阮一峰的网络日志
T
The Exploit Database - CXSecurity.com
Scott Helme
Scott Helme
A
Arctic Wolf
Martin Fowler
Martin Fowler
Hacker News: Ask HN
Hacker News: Ask HN
V
V2EX
B
Blog RSS Feed
The Last Watchdog
The Last Watchdog
博客园 - 司徒正美
Simon Willison's Weblog
Simon Willison's Weblog
V
Vulnerabilities – Threatpost
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
www.infosecurity-magazine.com
www.infosecurity-magazine.com
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Proofpoint News Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
AI
AI
C
Cisco Blogs
T
The Blog of Author Tim Ferriss

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 Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
31 paquetes npm de Red Hat comprometidos roban credenciales de nube
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.