devtake.dev

Bitwarden CLI got backdoored for 90 minutes. The worm calls itself 'Shai-Hulud: The Third Coming.'

A malicious @bitwarden/[email protected] hit npm on April 22. The payload steals npm tokens, cloud secrets, and Claude Code credentials, then self-replicates.

Dieter Morelli · · 4 min read · 5 sources
Bitwarden CLI compromised by the Shai-Hulud npm worm
Image via Aikido Security · Source

Someone backdoored @bitwarden/cli on npm for about 90 minutes on the evening of April 22. That’s 78,000 weekly downloads of a security tool used by 10 million people and 50,000 businesses, and it arrived with a self-replicating worm that calls itself “Shai-Hulud: The Third Coming.” If you pulled 2026.4.0 off npm in the window, you treat every credential that machine has touched as burned.

What we know

  • Compromised package: @bitwarden/[email protected]. Distributed through the npm delivery path, not via Bitwarden’s official binaries.
  • Window: 5:57 PM to 7:30 PM Eastern on April 22, 2026, per Bitwarden’s own incident post. Roughly 90 minutes.
  • Entry point: not a stolen developer token. The Hacker News reports the attacker compromised the CI/CD pipeline itself, specifically publish-ci.yml in github.com/bitwarden/clients, and used it to push a malicious version under the legitimate Bitwarden npm identity. That bypasses trusted-publishing controls because the publisher is genuinely the trusted GitHub Action.
  • Payload: the install script bw_setup.js downloads the Bun runtime, which executes a 10 MB obfuscated script bw1.js. Aikido Security’s analysis lists SHA256 hashes for both files and the exfiltration endpoint audit.checkmarx[.]cx:443/v1/telemetry.
  • What gets stolen: SSH keys, AWS/GCP/Azure credentials, npm tokens, Git credentials, environment variables, cloud secret manager data via ambient credentials, plus Claude Code authentication tokens and MCP configuration files.
  • Self-propagation: after stealing an npm token, the worm enumerates the victim’s other packages, injects itself, and republishes. OX Security notes the payload skips execution on machines configured for Russian, a Lazarus-style geo-fence that suggests Russian-speaking operators.
  • Bitwarden’s scope statement: “No evidence that end user vault data was accessed or at risk, or that production data or production systems were compromised.” The attack hit the npm distribution surface, not Bitwarden’s vault infrastructure.

The broader campaign runs through a fake checkmarx[.]cx domain (not the real Checkmarx) and researchers are calling the family “Shai-Hulud: The Third Coming.” It’s the third self-replicating npm worm under the Shai-Hulud banner since September 2025. BleepingComputer flagged a separate self-spreading npm campaign earlier the same morning, hitting 16 Namastex Labs packages. Same idea, different operator, same week.

What we don’t know

  • How many installs landed inside the 90-minute window. npm doesn’t publish download timestamps with enough granularity for a public count, and Bitwarden hasn’t released its telemetry number.
  • Whether any other Bitwarden-maintained npm packages were contaminated before the revoke. The investigation is ongoing.
  • Which downstream packages picked up the worm via the victim-reupload mechanism. If your CI ran a fresh npm install after an infected developer’s token republished one of your dependencies, you need to audit the lockfile diff.
  • Whether the entry vector (the publish-ci.yml GitHub Action) had a branch-protection gap, a compromised OIDC trust, or a different root cause. Bitwarden hasn’t shared that detail yet.
  • The identity of the group behind the Checkmarx campaign. The Russian locale skip is suggestive, nothing more.

What this means for you

If you run bw in a script, check your lockfiles. If @bitwarden/[email protected] appears anywhere in your install history between 5:57 PM and 7:30 PM ET on April 22, assume compromise on that host. Rotate every token that was in scope: npm, GitHub PATs, SSH keys, cloud credentials, Claude Code API keys, and any MCP server configs. Revoke, reissue, audit. Then downgrade or move to Bitwarden’s signed binaries from their website.

Pin your package versions by hash, not by range, especially for security tooling. This is the same lesson from the Trivy action rewrite three weeks ago, the protobuf.js RCE a few days ago, and the Vercel OAuth breach the same week: a trusted name isn’t a version guarantee, and CI pipelines are the soft entry to the real keys. A @latest tag in a security-adjacent install script is an accident waiting for the right 90-minute window.

If you run an open-source project with npm publishing rights, the thing to fix today is your GitHub Actions trust surface. The Bitwarden attacker didn’t steal a human’s 2FA token. They got into the workflow that publishes on behalf of the org, which means every repo using publish actions needs to re-audit branch protection, OIDC trust, and the secrets inventory for that pipeline. Trusted publishing only works if the CI itself is trusted. Assume it isn’t, until you’ve proven otherwise.

My take: Shai-Hulud 3.0 is the first npm worm that explicitly targets AI-agent credentials (Claude Code tokens, MCP configs) in the same pass as SSH keys. That’s a new class of blast radius. An Anthropic API key doesn’t just give you free Opus tokens; on a dev machine, it’s attached to file-system, shell, and browser tools that an agent can drive. Expect the next round of supply-chain attacks to treat agent credentials as first-class loot. Rotate them the way you rotate root SSH keys, not the way you rotate a PyPI token.

Sources

Mentioned in this article