Shai-Hulud Rides Again: The Bitwarden CLI Compromise and the Cascade We're Now Living In
On April 22, 2026, @bitwarden/cli@2026.4.0 was published with a credential-stealing payload — via a GitHub Action that was itself compromised in the Checkmarx breach a month earlier. The cascade is not a metaphor; it is the mechanism. Why supply chain velocity is outpacing upstream defenses, and why runtime enforcement is the only surface attackers cannot bypass.
Hannes Ullman
bifrost security
Shai-Hulud Rides Again: The Bitwarden CLI Compromise and the Cascade We’re Now Living In
A second wave has already started. On April 22, 2026 — one month after the campaign we covered — @bitwarden/cli@2026.4.0 was published to npm with a credential-stealing payload. The vector was checkmarx/ast-github-action, compromised by TeamPCP in March. The attackers named this wave Shai-Hulud: The Third Coming. The cascade is not a metaphor. It is the mechanism.
The chain, in facts
Malicious release: @bitwarden/cli@2026.4.0. Last clean: 2026.3.0. Patched in 2026.4.1 on April 23.
- Release window: 5:57 PM–7:30 PM ET on April 22, 2026.
- Reach:
@bitwarden/clisees around 297,000 monthly downloads across versions. - Entry vector:
checkmarx/ast-github-action, running in Bitwarden’s own repo — downstream of the Checkmarx breach we covered previously. - First of its kind: per researcher Adnan Khan, the first known compromise of a package published via npm’s trusted publishing flow — the mechanism the ecosystem adopted to reduce supply chain risk (The Hacker News).
- Payload: a 10MB obfuscated
bw1.jsrun from apreinstallhook. Seven parallel credential collectors swept the usual targets — SSH keys,.npmrc,.aws/credentials,.gitconfig,.kube/config,.azure/credentials— plus GitHub and npm tokens, cloud secret managers (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault), and GitHub Actions runner secrets scraped from Python memory (Endor Labs). - Exfiltration:
audit.checkmarx[.]cx— the attackers impersonated the very vendor whose breach had just enabled them. Data was encrypted with AES-256-GCM and RSA-OAEP; a fallback channel committed encrypted blobs into victim-owned GitHub repositories with Dune-themed names. - Self-propagating worm: the payload used stolen npm tokens to download, poison, and republish every package the victim had publish rights to. Each compromise became a launch pad for the next.
- AI-coding-tool persistence: a dedicated module — labeled Butlerian Jihad in the payload — probed for Claude Code, Gemini CLI, OpenAI Codex, Kiro, Aider, and OpenCode, then injected persistence hooks into
~/.bashrcand~/.zshrcwhen any responded.
Why this keeps happening
Credentials harvested in one breach are the keys to the next. The dependency graph is a transitive trust graph, and attackers now traverse it programmatically — the Bitwarden worm republished to every package whose token it could steal. This is the mechanism we flagged in the previous post (“one compromised tool… becomes a skeleton key to every secret those pipelines touch”) now visibly in motion. Shai-Hulud: The Third Coming is not a rebrand. It is the literal third wave, and the naming is a taunt: the attackers expect more.
The uncomfortable part: the defenses the ecosystem built — npm trusted publishing, signed actions, verified artifacts — were bypassed by compromising the step before them. When the attacker owns the publish pipeline, every signature and every provenance attestation is issued on their behalf. Provenance tells you what pipeline built an artifact; it does not tell you whether that pipeline was honest at the moment it built it.
Exploitation is accelerating
This runs alongside a broader compression: how fast any weakness becomes a working exploit. zerodayclock.com tracks it — time-to-weaponization has been collapsing year over year. Supply chain cascades add a second compressed axis: the time between an upstream compromise and a downstream victim. A month ago, Checkmarx. Today, Bitwarden’s CLI. Tomorrow, whichever package one of Bitwarden’s contributors held a token for.
Defense windows are narrowing on both ends. “Patch promptly” assumes there are patches to apply, and that you recognize the thing that needs patching as yours.
The runtime argument, restated
You cannot out-patch a self-propagating worm. You cannot out-review a force-pushed tag. You cannot out-verify a signature issued by a hijacked pipeline. Every one of those defenses lives upstream of execution, and every one of them was bypassed here.
The one surface an attacker cannot talk their way past is the kernel. The moment the malicious bw1.js runs and tries to read credentials it has never accessed before, or tries to append to your ~/.bashrc, it has to ask the operating system for permission. Give the operating system an allowlist scoped to what the bw binary does — decrypt a vault, read a config, write to a known output path — and the first syscall outside that set is the attack’s last.
This is what we argued in When Trusted Security Tools Turn Against You. The Bitwarden CLI compromise is the receipt.
What to do this week
Expect more of these. The Trivy cascade is not finished, and the campaign names itself for a reason. If you haven’t audited which of your dependencies had active npm or GitHub tokens on April 22, start there. If you haven’t wrapped your security tooling in runtime enforcement yet, start there too.
bifrost Security provides automated, behavior-based AppArmor profiles for containerized workloads. Learn more at bifrostsec.com or get started.
Tags
Ready to see runtime security in action?
bifrost automatically generates tailored security profiles for your containers and cuts CVE noise by up to 90%. Free trial, no credit card required.