A trojanized release of @bitwarden/cli spent roughly 93 minutes on npm on April 22, 2026, before Bitwarden pulled it. Socket’s advisory1, published the following day, links the attack to the Checkmarx-themed supply-chain campaign running through CI and security tooling since at least March. The shared infrastructure is specific: same C2 endpoint, same obfuscation routine, same Dune-flavored dead-drop mechanism. Pivoting to a password-manager CLI after build-time scanners is not accidental. This target class has session tokens and vault-unlocked credentials sitting in process memory.
The 93-Minute Window
Timing differs between sources: Socket’s advisory1 places the malicious publish at 5
PM ET; Bitwarden’s community statement2 sets the distribution window from 5 PM to 7 PM ET on April 22. The gap likely reflects the difference between when the attacker completed the publish and when npm’s CDN propagated it to install requests. Neither figure has been formally reconciled. The same Bitwarden community post estimates roughly 334 downloads2, but marks that as approximate; it is a forum comment, not a post-mortem figure.No legitimate 2026.4.0 ever existed. Bitwarden replaced the slot with CLI 2026.4.13, described in release notes as a “Re-release of CLI v2026.3.0,” which is the unambiguous signal that the entire 2026.4.0 release was the attacker’s artifact. The Snap package was confirmed unaffected; only the npm distribution path was poisoned.
From CI Artifact to Preinstall Hook
The entry point was a compromised GitHub Action in Bitwarden’s own CI/CD pipeline, the same attack class Socket attributed to the broader Checkmarx campaign1 throughout April 2026. The attacker didn’t need to touch Bitwarden’s source code or signing keys; they needed to land a single malicious file in the published npm package. That file was bw1.js, triggered through a preinstall hook in package.json.
JFrog noted4 that the script downloads the Bun runtime and executes bw1.js through it, keeping the Node.js dependency footprint clean and the payload off disk until after the hook fires.
What bw1.js Actually Steals
Socket’s advisory1 details the collection targets: GitHub and npm tokens, SSH keys, AWS/Azure/GCP credentials, .npmrc and .env files, shell history, and GitHub Actions secrets. The payload writes shell-RC persistence to ~/.bashrc and ~/.zshrc. It exits without executing if the system locale starts with ru.
The more notable addition is a dedicated module for AI coding-tool configurations: Claude, Cursor, Codex CLI, Aider, and Kiro. Those config files routinely contain API keys and sometimes implicit access to whatever files the developer has open. This isn’t an opportunistic add-on; it is a second-stage credential layer that maps to the current developer toolchain specifically.
Endor Labs’ Kiran Raj5 described the payload as among the most capable npm malware to date, citing multi-cloud harvesting, RSA-signed C2 commands, self-propagating worm logic, and the AI-tool config module. That framing holds on the technical merits, though “most capable ever” always has a short shelf life.
The Checkmarx-Campaign Throughline
Attribution here rests on shared infrastructure and code, not a formal government or vendor attribution report. Socket and others1 point to three specific reuses: the C2 endpoint audit.checkmarx[.]cx/v1/telemetry, the __decodeScrambled obfuscation routine with seed 0x3039, and the exfiltration dead-drop: AES-256-GCM1 encrypted data committed to public GitHub repos under victim accounts, using Dune-themed repo names with the string “Shai-Hulud: The Third Coming” as a marker.
The group has been linked to TeamPCP5, previously connected to Trivy and LiteLLM supply-chain incidents. The @pcpcats X account associated with the group was suspended around the time of the advisory.
One nuance Socket raises: the possibility that this incident involves a different operator reusing shared infrastructure rather than the same team running it. The Shai-Hulud naming appeared in earlier npm worm campaigns, and infrastructure sharing can mean resale or leakage as easily as continuity. Treat the attribution as working hypothesis.
Why the Target Pivot Changes the Blast Radius
The earlier Checkmarx-campaign victims (Trivy, LiteLLM) were build-time tools. An attacker who compromises a scanner gets scan output and whatever environment variables leak from the runner. An attacker who compromises the CLI you use to authenticate against your password manager gets something different: whatever bw had in memory when it ran.
Bitwarden’s statement2 is precise: “no evidence that end user vault data was accessed or at risk,” production systems not compromised. That is accurate as a server-side statement. It does not address what bw1.js could read from the process running on the developer’s machine: session tokens in memory, secrets the CLI had retrieved that session, files the process had access to during execution. Blast radius assessment requires local state, not just Bitwarden’s backend logs.
Remediation Checklist
If anyone in your organization ran npm install -g @bitwarden/cli between approximately 5
Confirm exposure:
- Check npm install logs or shell history for
@bitwarden/cliinstalls in that window - Search GitHub for new public repos under affected developer accounts containing “Shai-Hulud” in the name
- Audit recent commits from those accounts for base64-encoded or AES-encrypted blob files
Rotate on affected hosts:
- GitHub tokens and fine-grained personal access tokens
- npm publish tokens
- SSH keys, particularly those loaded into
ssh-agentduring the window - AWS, Azure, and GCP credentials present in environment variables or credential files
- API keys in
.env,.npmrc, and AI coding-tool configs (Claude, Cursor, Codex CLI, Aider, Kiro)
Session token handling:
Any bw session token generated during the window should be treated as compromised. If a developer unlocked their vault between those times, credentials retrieved during that session are in scope for rotation regardless of Bitwarden’s server-side assurances.
Persistence cleanup:
Audit ~/.bashrc and ~/.zshrc on affected machines for entries added after April 22 that reference unknown binaries or contain base64 strings.
Open Questions
Three things remain unresolved as of the advisory window.
First, the npm trusted publishing question. Researcher Adnan Khan flagged this5 as potentially the first supply-chain compromise of a package using npm’s trusted publishing feature, which ties releases to verified GitHub Actions runs and is npm’s current recommended path for eliminating long-lived publish tokens. If the framing holds, it is a specific failure mode for the mechanism npm has been pushing as a security improvement. Neither npm nor GitHub has issued a formal statement confirming or rebutting this characterization.
Second, attribution consistency. The Checkmarx-branded infrastructure has appeared across enough incidents that the “same campaign” framing deserves scrutiny. If the C2 endpoint and obfuscation seed are available to multiple operators (purchased, leaked, or published), then attributing each incident to TeamPCP may overcount a single adversary’s footprint. The @pcpcats suspension removes some signal. What’s left is infrastructure overlap, which is necessary but not sufficient for identity.
Third, the CI pipeline specifics. Bitwarden has confirmed a compromised GitHub Action was the vector but has not published which Action was affected, how it was compromised, or whether the same misconfiguration exists in other Bitwarden packages. GitHub Actions remain the weakest link in npm publishing pipelines because most maintainer security advice has focused on code signing and token hygiene while leaving the runner environment less hardened. The exfiltration channel compounds this: committing encrypted data to public GitHub repos rarely triggers outbound DLP alerts, because GitHub traffic is almost never on an organization’s blocklist.
Frequently Asked Questions
Are Bitwarden browser extensions, mobile apps, or Snap users affected by this compromise?
No. Bitwarden confirmed the incident was isolated to the npm registry path, and the Snap package was explicitly verified unaffected. Browser extensions, mobile apps, and direct GitHub release binaries were never in scope. A CVE is currently being issued specifically for @bitwarden/cli@2026.4.0 on npm, underscoring that only that single package version distributed during the roughly 93-minute window on April 22, 2026, carries the malicious bw1.js payload.
How did the broader security vendor response frame this incident, and what angles were under-covered?
Vendors including Socket, JFrog, OX Security, Endor Labs, StepSecurity, Aikido, GitGuardian, Mend, and SafeDep published analyses within 24 hours of the April 23 advisory. Most coverage focused on threat-actor IoCs and Checkmarx-campaign attribution. The under-reported operational angles are the concrete 30-minute remediation checklist for affected developers and the possibility that this represents the first confirmed failure of npm trusted publishing when a GitHub Action inside the pipeline is compromised.
Which specific AI coding assistants were targeted, and why do their configs represent a distinct risk category?
The payload included a dedicated module for Claude, Cursor, Codex CLI, Aider, and Kiro configurations. Unlike static secrets in .env files, these configs often grant implicit access to the developer’s current workspace and open files, exposing not just API keys but also the context of whatever the developer was actively editing. This transforms the malware from a simple credential scraper into a tool for harvesting live development context, making AI-tool config rotation and workspace auditing part of incident response.
What does the move from Trivy and LiteLLM to Bitwarden CLI signal about future supply-chain targets?
The campaign has pivoted from build-time scanners in March 2026 to a credential CLI in April, targeting memory-resident session tokens rather than static CI secrets. While Socket links the pattern to TeamPCP, the shared C2 endpoint, obfuscation seed, and dead-drop infrastructure suggest the underlying toolkit may be available to multiple operators. That raises the likelihood of copycat attacks against other password managers, VPN clients, or cloud-authentication tools that distribute via npm, regardless of whether the original group remains active.