JustAppSec
Back to news

Fake Bitwarden CLI package stole credentials and backdoored other packages

3 min readPublished 01 May 2026Updated 01 May 2026Source: Palo Alto Networks Unit 42

TL;DR - @bitwarden/[email protected] is a malicious impersonator. Its preinstall script bootstraps the Bun runtime (v1.3.13), then runs a large obfuscated payload that harvests cloud credentials, CI/CD secrets, npm tokens, and SSH keys. If it finds a usable npm token, it downloads packages that identity can publish, injects a new preinstall hook, and republishes them - spreading the infection automatically.

What happened

Unit 42 published a threat-research write-up on npm supply chain attacks, including detailed analysis of a malicious package impersonating Bitwarden's CLI tool - @bitwarden/[email protected].

The attack chain is tight. A preinstall lifecycle script runs a bootstrapper (bw_setup.js) that detects OS and architecture, downloads the Bun runtime (v1.3.13) directly from Bun's official GitHub releases, then executes the main payload (bw1.js). That payload is a heavily obfuscated, multi-megabyte JavaScript file that bundles multiple SDKs and provider-specific credential collectors.

Unit 42 documents the harvesting targets: cloud credentials (AWS, Azure, Google Cloud), CI/CD secrets, npm tokens, GitHub PATs, and SSH keys from developer workstations and CI runners. Once the payload finds a usable npm token, it shifts from theft to propagation. It downloads tarballs of packages that token can publish, injects a new preinstall hook - for example "preinstall": "node setup.mjs" - and republishes the trojanised versions under the stolen identity.

Unit 42 also documents the command-and-control infrastructure: a C2 domain at audit.checkmarx[.]cx and a fallback mechanism using the GitHub Search API as a dead drop.

This is not a "one compromised package" incident. A single infected developer or CI runner with publish rights becomes a vector into every package that identity controls. The blast radius scales with token permissions, not with how many people installed the original malicious version.

ItemDetail
Malicious package@bitwarden/[email protected]
Execution triggerpreinstall lifecycle script
Downloaded runtimeBun v1.3.13
Reported behaviourCredential harvesting + worm-like propagation via republished backdoored packages
C2 domainaudit.checkmarx[.]cx
Fallback mechanismGitHub Search API used as dead drop

Who is impacted

  • Teams and developers who installed @bitwarden/[email protected] during the exposure window Unit 42 describes.
  • Organisations whose developer workstations or CI runners allow npm lifecycle scripts (preinstall/postinstall) to execute during dependency install.
  • Any environment holding high-value secrets in environment variables or local config - cloud credentials, npm tokens, GitHub tokens, SSH keys.
  • Highest risk: maintainers with npm publish rights. Unit 42 describes automated backdooring and republishing of packages using stolen tokens, meaning a single compromised identity can propagate the payload across multiple packages.

What to do now

  • Scope your exposure first. Check whether any developer workstation, CI runner, or build environment pulled @bitwarden/[email protected] during the window Unit 42 identifies. Check npm lockfiles, build logs, and container image history.
  • Rotate every credential that may have been in scope. Unit 42 explicitly names: npm tokens, GitHub PATs, AWS/Azure/Google Cloud keys, SSH keys, and CI/CD secrets. Rotate them all, do not try to guess which ones were captured.
  • Hunt for propagation in packages you maintain:
    • unexpected version bumps or newly added preinstall lifecycle scripts in any package your identities can publish
    • unexpected workflow files, artifact downloads, or new repository activity in GitHub orgs connected to affected tokens
    • new or modified files named setup.mjs or similar bootstrapper patterns in your package source
  • Apply ecosystem hardening controls Unit 42 recommends:
    • add ignore-scripts=true to .npmrc to disable lifecycle scripts during install
    • use package-lock.json and npm ci in CI pipelines to reduce dependency drift
    • enforce a cooldown period before allowing newly published package versions (blocking versions published in the last 24-72 hours)
    • route npm traffic through a private registry or proxy instead of directly hitting registry.npmjs.org
  • Follow Bitwarden, npm, and your internal IR playbooks for any additional scoping and response steps specific to your environment.

Related


Content is AI-assisted and reviewed by our team, but issues may be missed and best practices evolve rapidly, send corrections to [email protected]. Always consult official documentation and validate key implementation decisions before making design or security choices.

Need help?Get in touch.