1 puntos por GN⁺ 6 일 전 | 1 comentarios | Compartir por WhatsApp
  • El paquete Bitwarden CLI para npm fue comprometido como parte del ataque de cadena de suministro de Checkmarx en curso, y el alcance confirmado hasta ahora se limita a la compilación @bitwarden/cli 2026.4.0
  • El código malicioso bw1.js incluido en el paquete usa la misma infraestructura y técnicas de ofuscación, como audit.checkmarx[.]cx/v1/telemetry, y también encaja con indicios de una intrusión en CI/CD mediante una GitHub Action comprometida
  • Los objetivos de recolección abarcan no solo tokens de GitHub, sino también credenciales de AWS, Azure y GCP, .npmrc, claves SSH, variables de entorno e incluso archivos de configuración de Claude/MCP
  • La información robada lleva a la creación y los commits en repositorios públicos de GitHub, a la propagación por republicación usando tokens de npm, a la inyección de workflows, e incluye también funciones de persistencia como la modificación de ~/.bashrc y ~/.zshrc
  • Las organizaciones que usen Bitwarden CLI deben tratar este incidente como una exposición de credenciales y una intrusión en CI/CD, y es clave revisar los logs de CI y rotar cualquier secreto potencialmente expuesto

Resumen general

  • El paquete npm de Bitwarden CLI fue comprometido como parte del ataque de cadena de suministro de Checkmarx en curso, y la versión afectada confirmada es @bitwarden/cli2026.4.0
    • El código malicioso estaba dentro de bw1.js, incluido en el paquete
    • La ruta de ataque coincide con indicios de uso de una GitHub Action comprometida dentro del pipeline de CI/CD de Bitwarden, y con el patrón de la campaña observado en otros repositorios
  • El alcance confirmado hasta ahora está limitado a la compilación de Bitwarden CLI, y el compromiso sigue el vector de cadena de suministro de GitHub Actions identificado en la campaña de Checkmarx
    • Solo está involucrado el paquete CLI para npm
    • Hasta ahora no se ha confirmado impacto en la extensión de Chrome, el servidor MCP ni otras distribuciones oficiales
  • La investigación sigue en curso, y más adelante se publicarán el análisis técnico completo, las versiones afectadas, los indicadores de compromiso y la guía de respuesta
  • Si usas Bitwarden CLI, es necesario revisar los logs de CI y rotar los secretos que pudieran haber quedado expuestos

Análisis técnico

  • La carga maliciosa bw1.js comparte infraestructura central con mcpAddon.js de Checkmarx, analizado el día anterior
    • Usa el mismo endpoint C2, audit.checkmarx[.]cx/v1/telemetry, y está ofuscado con __decodeScrambled y la semilla 0x3039
    • También realiza exfiltración basada en commits por medio de la API de GitHub y robo de tokens con republicación a través del registro de npm
  • La estructura de la carga embebida también es de la misma familia
    • Dentro de una estructura gzip+base64 incluye un script en Python que raspa la memoria de Runner.Worker de GitHub Actions para buscar tokens de GitHub
    • También contiene un loader setup.mjs para paquetes npm republicados, un workflow YAML de GitHub Actions, una clave pública RSA hardcodeada y una cadena tipo manifiesto ideológico
  • El alcance de la recolección de credenciales es muy amplio
    • Los tokens de GitHub se obtienen mediante scraping de memoria de Runner.Worker y de variables de entorno
    • Las credenciales de AWS se buscan en archivos de ~/.aws/ y en variables de entorno
    • Los tokens de Azure se recolectan mediante azd, y las credenciales de GCP mediante gcloud config config-helper
    • También se apuntan .npmrc, claves SSH, variables de entorno y archivos de configuración de Claude/MCP
  • También se confirmó en detalle el método de exfiltración vía GitHub
    • Se crean repositorios públicos bajo la cuenta de la víctima siguiendo la convención de nombres con temática de Dune {word}-{word}-{3digits}
    • Se hacen commits con resultados cifrados, y en el mensaje del commit se inserta el token junto con el marcador LongLiveTheResistanceAgainstMachines
  • Incluso incluye mecanismos de propagación por cadena de suministro
    • Usa tokens npm robados para localizar paquetes con permisos de escritura y republicarlos con un preinstall hook insertado
    • Inyecta workflows de GitHub Actions para recolectar más secretos de los repositorios
  • Existe un kill switch por configuración regional rusa
    • Si la configuración regional del sistema comienza con "ru", termina silenciosamente
    • Revisa Intl.DateTimeFormat().resolvedOptions().locale y las variables de entorno LC_ALL, LC_MESSAGES, LANGUAGE, LANG
  • El entorno de ejecución es Bun v1.3.13, descargado desde GitHub Releases

Diferencias frente al incidente de Checkmarx

  • bw1.js incluye indicadores de compromiso adicionales que no aparecían en la documentación del incidente de Checkmarx
    • Usa el archivo de bloqueo hardcodeado /tmp/tmp.987654321.lock para evitar ejecuciones simultáneas
    • Inyecta la carga en ~/.bashrc y ~/.zshrc para lograr persistencia en el perfil de shell
    • Usa branding explícito, como establecer la descripción del repositorio en Shai-Hulud: The Third Coming e incluir "Would be executing butlerian jihad!" en cadenas de depuración
  • Aunque las herramientas compartidas sugieren fuertemente conexión con el mismo ecosistema de malware, las firmas operativas dificultan más la atribución
    • Tras descubrirse el ataque a Checkmarx, TeamPCP afirmó a través de la cuenta social @pcpcats que ellos eran los responsables
    • Ese malware intentaba disfrazarse con descripciones que parecían legítimas
  • Esta carga muestra una postura pública distinta
    • Marcadores ideológicos como el nombre de repositorio Shai-Hulud, el manifiesto "Butlerian Jihad" y los mensajes de commit sobre resistencia contra las máquinas aparecen directamente dentro del malware
    • Siguen abiertas varias posibilidades: otro operador usando la misma infraestructura compartida, una facción más ideológica o un cambio en la postura pública de la campaña

Recomendaciones

  • Las organizaciones que hayan instalado el paquete npm malicioso de Bitwarden deben tratar este incidente como una exposición de credenciales y una intrusión en CI/CD
  • Deben eliminar de inmediato el paquete afectado de los sistemas de desarrollo y entornos de build, y rotar todas las credenciales que puedan haber quedado expuestas en esos entornos
    • Esto incluye tokens de GitHub, tokens de npm, credenciales de nube, claves SSH y secretos de CI/CD
  • En GitHub se debe revisar si hubo creación de repositorios no autorizados y workflows anómalos
    • Se deben revisar archivos inesperados bajo .github/workflows/, ejecuciones sospechosas de workflows, descargas de artifacts y repositorios públicos que sigan el patrón de nombres con temática de Dune {word}-{word}-{3digits}
    • Si hay posibilidad de afectación, también deben revisarse en los repositorios publicados recientemente las siguientes palabras clave
      • atreides
      • cogitor
      • fedaykin
      • fremen
      • futar
      • gesserit
      • ghola
      • harkonnen
      • heighliner
      • kanly
      • kralizec
      • lasgun
      • laza
      • melange
      • mentat
      • navigator
      • ornithopter
      • phibian
      • powindah
      • prana
      • prescient
      • sandworm
      • sardaukar
      • sayyadina
      • sietch
      • siridar
      • slig
      • stillsuit
      • thumper
      • tleilaxu
  • En npm se debe auditar si hubo publicaciones no autorizadas
    • Se deben revisar publishes no aprobados, cambios de versión y hooks de instalación agregados recientemente
  • En los entornos de nube se deben volver a revisar los logs de acceso
    • Es necesario rastrear accesos anómalos a secretos, uso de tokens y credenciales emitidas recientemente
  • En endpoints y runners se deben rastrear la infraestructura de exfiltración observada y los rastros de acceso a archivos
    • Es necesario buscar conexiones salientes hacia audit[.]checkmarx[.]cx
    • Debe verificarse si hubo ejecución de Bun en entornos donde normalmente no se usa
    • Hay que revisar rastros de acceso a .npmrc, .git-credentials, .env, almacenes de credenciales cloud y accesos a gcloud, az, azd
    • También debe verificarse la presencia de /tmp/tmp.987654321.lock y cambios en ~/.bashrc y ~/.zshrc
  • En GitHub Actions debe revisarse si se crearon workflows no autorizados
    • Es necesario comprobar si se crearon workflows en ramas temporales
    • También debe revisarse si se creó o descargó un artifact como format-results.txt
  • A largo plazo, hace falta reducir el radio de impacto de futuros incidentes de cadena de suministro
    • Se debe reducir el alcance de permisos de los tokens y usar credenciales de vida corta cuando sea posible
    • Deben restringirse los permisos para crear y publicar paquetes, y reforzarse los permisos de GitHub Actions
    • Debe deshabilitarse el acceso innecesario a artifacts y monitorearse la creación de repositorios públicos o cambios en workflows fuera de los procedimientos normales de release

Indicadores de compromiso

1 comentarios

 
GN⁺ 6 일 전
Comentarios en Hacker News
  • Me pregunto si hay una defensa mejor que establecer un período mínimo de espera para releases
    Con solo poner min-release-age=7 en .npmrc, probablemente se habrían salvado 334 personas de recibir @bitwarden/cli 2026.4.0, que se publicó hace unas 19 horas y luego resultó ser malicioso
    También encaja bastante bien con casos como axios, ua-parser-js y node-ipc; no evitaría algo como event-stream, que permaneció oculto durante mucho tiempo, pero sí parece efectivo contra la mayoría de los ataques agudos a la cadena de suministro
    Como ejemplo de configuración, hay formas de poner tiempos de espera en npm/pnpm/bun/uv, y como no había una herramienta de un clic para revisar y aplicar eso, terminé creando https://depsguard.com
    También acabo de ver https://cooldowns.dev, que tiene una idea parecida

    • Estoy usando Aikido safe-chain
      No solo aplica un período mínimo de espera para releases, sino que envuelve npm/uv y demás como un wrapper para revisar cada dependencia antes de instalarla contra una base de datos comercial de vulnerabilidades, buscando problemas conocidos o señales sospechosas
    • La idea del cooldown es buena, pero también me pregunto si este ataque realmente se habría detectado si nadie hubiera actualizado de inmediato
      En la práctica siempre habrá alguien que actualice al instante, pero el propio proceso por el que se descubren estos incidentes parece depender en parte de esos usuarios que actualizan rápido
    • Creo que es mejor empezar por no poner backend ni herramientas CLI en NPM
    • Para instalaciones nuevas, bueno, pero para dependencias existentes, ¿no bastaría con fijar la versión patch y fijar el sha?
    • Este tipo de ataques normalmente no llega hasta el upstream source, así que un enfoque de compilar desde el código fuente como https://www.chainguard.dev/libraries bloquearía como el 98% de los casos
      Si tienes que jalar binarios del registro tal cual, un cooldown puede reducir un poco el riesgo
      Para los casos más complejos donde también comprometen GitHub, parece que hace falta una combinación de heurísticas sobre commits y maintainers, más análisis de cambios de código con IA, y revisión humana cuando haya señales anómalas
      Por cierto, trabajo ahí
  • Lo clave en este incidente es que comprometieron el pipeline de build y desde ahí distribuyeron un paquete contaminado
    Aun así, si estás montando algo importante para el negocio sobre npm, creo que sí conviene hacer pinning de dependencias
    Muchos desarrolladores asumen que el lockfile basta, pero si sigue habiendo rangos ^, al actualizar el lockfile puedes terminar trayendo una versión nueva que yo no elegí explícitamente
    Si es un sistema que podría afectar la supervivencia de la empresa, vale la pena soportar esa molestia

    • Viéndolo al revés, cuando una vulnerabilidad de seguridad se corrige en una versión posterior, también sería ideal que el sistema la reciba y la aplique automáticamente
  • https://github.com/doy/rbw es una alternativa en Rust al CLI de Bitwarden
    El ecosistema de Rust también da cada vez más la impresión de ir hacia árboles de dependencias grandes y profundos como npm, pero aun así sigue habiendo muchos menos autores en quienes confiar que en el caso típico de JavaScript

    • Si ves https://github.com/doy/rbw/blob/main/Cargo.toml#L16, aquí también hay bastantes dependencias
      Pero al menos las versiones sí están fijadas
    • Me pregunto si hay alguna desventaja de usar el gestor de contraseñas integrado de Firefox
    • Parece que todo el mundo considera que Rust es más seguro, pero se ignora con demasiada facilidad cuánto aumenta el riesgo de traer malware a través de dependencias
    • La combinación rbw + vaultwarden funciona bastante bien como una versión autoalojable en Rust de Bitwarden
    • Por cosas como esta, creo que más software podría moverse hacia stacks como .Net, donde la mayoría se resuelve sin dependencias de terceros
      O, en sentido contrario, hacia lenguajes que metan más funcionalidad en la biblioteca estándar
  • Mi experiencia con el CLI de Bitwarden fue muy mala
    Corrí bw list pensando que solo vería los nombres de las contraseñas, pero en realidad mostró todas las contraseñas y hasta los códigos TOTP actuales
    Lo más aterrador fue entrar por ssh al servidor, abrir weechat dentro de tmux, y ver que el contenido completo del comando bw estaba accesible desde el historial de entrada de weechat
    No tengo idea de por qué pasó, y seguía ahí incluso entre sesiones de tmux y weechat; solo desapareció cuando reinicié el servidor
    Después de eso desinstalé de inmediato el CLI de bw y no pienso volver a instalarlo
    Por cierto, uso ghostty como terminal

    • Esto suena más bien a una queja no relacionada con el tema principal
    • Quise probar el CLI, vi que estaba basado en JavaScript y lo dejé ahí
    • Está realmente raro
      Me pregunto si habrá alguna extensión bwcli para weechat, y de hecho es la primera vez que me entero de que Bitwarden tiene CLI
      Yo uso keepass en local
  • No he usado el CLI, pero sí el plugin del navegador
    Si eso se llegara a comprometer, sería gravísimo, y no sé qué debería hacer para evitarlo
    Estoy pensando si la respuesta es seguir usando una versión anterior verificada
    Se siente extraño volver a pensar que buena parte de mi vida depende de que estos secretos sigan siendo secretos

    • Mientras más puntos de integración haya, mayor es la superficie de ataque
      Por eso no uso extensiones de navegador para el gestor de contraseñas
      Después de ver productos con problemas de seguridad en la integración con navegadores, empecé a evitarlos por completo; confío relativamente más en la integración de iOS, pero aun así me mantengo alerta
    • Creo que el cooldown debería venir por defecto en todas partes
      Incluyendo gestores de paquetes de desarrollo, gestores de paquetes del sistema operativo, extensiones de navegador y actualizaciones automáticas de apps independientes
      Empresas como Socket necesitan tiempo para detectar actualizaciones maliciosas; si todos descargan a los pocos minutos de publicarse, esa detección deja de tener sentido
    • Mis activos digitales más valiosos, mi correo electrónico y mi cuenta de Bitwarden, están protegidos siempre con una Yubikey que llevo conmigo y una llave de respaldo en otra ubicación
      Recomiendo mucho esta configuración
      El título sí me espantó un poco, pero siento que ya hago todo lo razonable sin caer en la paranoia
    • En lugar del plugin del navegador, puedes usar la app de escritorio o entrar directo al web vault
    • Para bloquearlo, en pocas palabras, son estas dos cosas
      https://cooldowns.dev
      https://depsguard.com
      Yo mantengo la segunda; si hubiera conocido la primera antes, probablemente ni me habría molestado en hacerla
      Ambas hacen casi lo mismo, y la mía quizá es un poco exagerada por estar hecha en Rust
  • Lo más importante aquí es que bastó con npm install
    Si el punto de compromiso fue preinstall, la idea convencional de inspeccionar después de instalar se cae de inmediato
    Para entonces el payload ya tuvo oportunidad de ejecutarse
    Esto se vuelve todavía más interesante en entornos de agents, CI y sandboxes efímeros, donde aunque la exposición sea breve, basta con que la instalación se repita automáticamente para quedar comprometido
    Otra cosa notable es que este payload no apuntaba solo a secretos, sino también a la configuración de herramientas de IA
    La manipulación del perfil del shell podría convertirse de forma muy real en una vía para contaminar el contexto que leerá el siguiente asistente de programación
    Escribí más sobre esa perspectiva, junto con el trabajo de AgentSH, en https://www.canyonroad.ai/blog/the-install-was-the-attack/

    • En la práctica nadie inspecciona paquetes después de instalarlos, y creo que enfocarse específicamente en los scripts de npm install es una postura que ya se ha refutado muchas veces
      Al final igual vas a ejecutar el binario real
      Y, si de verdad nos ponemos estrictos, también podrías descargar e inspeccionar el paquete antes de instalarlo; si no entiendes a fondo qué garantiza el instalador y cuál es su alcance, resulta más raro confiar a medias en el proceso de bajar y descomprimir código malicioso que podría ejecutarse
  • Un kill switch por locale ruso se ve tan audaz como cobarde

    • Lo peor es que ni siquiera sabemos si eso es una pista real o una false flag
    • Me vienen a la mente toda clase de dichos como Discretion is the better part of valor
      En resumen, da la impresión de una actitud de no dispararse al propio pie
    • Eso por sí solo no es evidencia concluyente
      En la filtración de Vault7 había material que decía que la NSA y la CIA dejaban este tipo de rastros deliberadamente para ocultar el origen, y es una técnica que otros actores estatales también podrían usar perfectamente
    • También parece una operación intimidatoria hecha por otro país
    • ¿Quién configuraría así el locale en una tarea de GitHub CI para npm publish?
      Parece una pista de desvío demasiado obvia, pero al mismo tiempo deja una impresión fuerte de intervención de un actor estatal
  • Si eres usuario de KeePass, vives con mucho menos estrés por estas cosas
    Solo en los últimos 5 años, usar KeePass en infraestructura local me ha evitado varios incidentes de seguridad

    • Aquí el problema no fue el vault en sí, sino la herramienta de acceso
      No veo por qué eso sería imposible también con una herramienta de acceso para KeePass; no me queda claro qué sería distinto
    • Necesito acceder a las contraseñas desde la infraestructura y desde el teléfono, y me pregunto cómo resuelven eso con KeePass
      Siempre asumí que no se podía, pero honestamente nunca lo investigué a fondo
    • Puede estar bien para alguien capaz de operar su propia infraestructura, pero llamar a eso stress free para el usuario promedio suena difícil
    • Entiendo la idea del archivo único, pero en la práctica me pregunto cómo resuelven la sincronización y los conflictos
      Por ejemplo, si dos dispositivos agregan contraseñas mientras están offline y luego vuelven a conectarse, ¿qué pasa?
    • Lo que todavía no termino de entender de KeePass es el respaldo en la nube
      Si cifras el respaldo, ¿dónde guardas esa contraseña? ¿Y dónde guardas la contraseña del proveedor de nube?
  • Lo que más me impresionó de este ataque es que los atacantes tuvieron que sincronizarse con precisión con un momento en que GitHub no estuviera caído

  • Por eso yo no uso gestores de contraseñas de terceros
    Porque tienes que seguir confiando en que harán bien la seguridad, las actualizaciones, los respaldos y todo eso
    Me hice mi propio generador de contraseñas stateless, así que no necesito respaldar ni sincronizar datos entre dispositivos
    Funciona con una contraseña maestra muy larga y fuerte, más el nombre del servicio y el usuario, y con eso corre un hash scrypt con parámetros adecuados para volver el brute force prácticamente imposible
    En las cuentas importantes también uso 2FA