- 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/cli2026.4.0 - El código malicioso
bw1.jsincluido en el paquete usa la misma infraestructura y técnicas de ofuscación, comoaudit.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
~/.bashrcy~/.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 código malicioso estaba dentro de
- 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.jscomparte infraestructura central conmcpAddon.jsde Checkmarx, analizado el día anterior- Usa el mismo endpoint C2,
audit.checkmarx[.]cx/v1/telemetry, y está ofuscado con__decodeScrambledy la semilla0x3039 - 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
- Usa el mismo endpoint C2,
- 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.Workerde GitHub Actions para buscar tokens de GitHub - También contiene un loader
setup.mjspara paquetes npm republicados, un workflow YAML de GitHub Actions, una clave pública RSA hardcodeada y una cadena tipo manifiesto ideológico
- Dentro de una estructura gzip+base64 incluye un script en Python que raspa la memoria de
- El alcance de la recolección de credenciales es muy amplio
- Los tokens de GitHub se obtienen mediante scraping de memoria de
Runner.Workery 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 mediantegcloud config config-helper - También se apuntan
.npmrc, claves SSH, variables de entorno y archivos de configuración de Claude/MCP
- Los tokens de GitHub se obtienen mediante scraping de memoria de
- 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
- Se crean repositorios públicos bajo la cuenta de la víctima siguiendo la convención de nombres con temática de Dune
- 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().localey las variables de entornoLC_ALL,LC_MESSAGES,LANGUAGE,LANG
- Si la configuración regional del sistema comienza con
- El entorno de ejecución es Bun v1.3.13, descargado desde GitHub Releases
Diferencias frente al incidente de Checkmarx
bw1.jsincluye 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.lockpara evitar ejecuciones simultáneas - Inyecta la carga en
~/.bashrcy~/.zshrcpara lograr persistencia en el perfil de shell - Usa branding explícito, como establecer la descripción del repositorio en
Shai-Hulud: The Third Cominge incluir"Would be executing butlerian jihad!"en cadenas de depuración
- Usa el archivo de bloqueo hardcodeado
- 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
@pcpcatsque ellos eran los responsables - Ese malware intentaba disfrazarse con descripciones que parecían legítimas
- Tras descubrirse el ataque a Checkmarx, TeamPCP afirmó a través de la cuenta social
- 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
- Marcadores ideológicos como el nombre de repositorio Shai-Hulud, el manifiesto
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
atreidescogitorfedaykinfremenfutargesseritgholaharkonnenheighlinerkanlykralizeclasgunlazamelangementatnavigatorornithopterphibianpowindahpranaprescientsandwormsardaukarsayyadinasietchsiridarsligstillsuitthumpertleilaxu
- Se deben revisar archivos inesperados bajo
- 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 agcloud,az,azd - También debe verificarse la presencia de
/tmp/tmp.987654321.locky cambios en~/.bashrcy~/.zshrc
- Es necesario buscar conexiones salientes hacia
- 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
-
Paquete malicioso
-
Indicadores de red
94[.]154[.]172[.]43https://audit.checkmarx[.]cx/v1/telemetry
-
Indicadores del sistema de archivos
/tmp/tmp.987654321.lock/tmp/_tmp_<Unix Epoch Timestamp>/package-updated.tgz
1 comentarios
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=7en.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 maliciosoTambién encaja bastante bien con casos como
axios,ua-parser-jsynode-ipc; no evitaría algo comoevent-stream, que permaneció oculto durante mucho tiempo, pero sí parece efectivo contra la mayoría de los ataques agudos a la cadena de suministroComo 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
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
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
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ícitamenteSi es un sistema que podría afectar la supervivencia de la empresa, vale la pena soportar esa molestia
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
Pero al menos las versiones sí están fijadas
rbw + vaultwardenfunciona bastante bien como una versión autoalojable en Rust de BitwardenO, 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 listpensando que solo vería los nombres de las contraseñas, pero en realidad mostró todas las contraseñas y hasta los códigos TOTP actualesLo más aterrador fue entrar por ssh al servidor, abrir weechat dentro de tmux, y ver que el contenido completo del comando
bwestaba accesible desde el historial de entrada de weechatNo 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
bwy no pienso volver a instalarloPor cierto, uso ghostty como terminal
Me pregunto si habrá alguna extensión
bwclipara weechat, y de hecho es la primera vez que me entero de que Bitwarden tiene CLIYo 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
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
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
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
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 inmediatoPara 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/
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
Discretion is the better part of valorEn resumen, da la impresión de una actitud de no dispararse al propio pie
En la filtración de
Vault7habí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 perfectamenteParece 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
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
Siempre asumí que no se podía, pero honestamente nunca lo investigué a fondo
Por ejemplo, si dos dispositivos agregan contraseñas mientras están offline y luego vuelven a conectarse, ¿qué pasa?
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
https://mrshu.github.io/github-statuses/
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