Bitwarden CLI npm Supply Chain Compromise (@bitwarden/cli v2026.4.0) — Shai-Hulud: The Third Coming / TeamPCP — Threadlinqs Intelligence
As of 2026-05-30, Bitwarden CLI npm Supply Chain Compromise (@bitwarden/cli v2026.4.0) — Shai-Hulud: The Third Coming / TeamPCP is a critical-severity supply chain threat attributed to TeamPCP, tracked by Threadlinqs Intelligence with 9 detection rules (Splunk SPL, Microsoft KQL, Sigma) and 22 indicators of compromise.
Threat ID: TL-2026-0429 · Severity: CRITICAL · CVSS: 9.6 · Status: ACTIVE · Category: SUPPLY_CHAIN
Attribution: TeamPCP · FINANCIAL
TeamPCP operators hijacked Bitwarden's CI/CD pipeline through a compromised checkmarx/ast-github-action and published a malicious @bitwarden/cli@2026.4.0 to npm for ~93 minutes on 2026-04-22 (5:57
On 2026-04-22 at 17:57 ET, attackers tracked as TeamPCP — the operators behind the broader Shai-Hulud campaign — published a malicious version 2026.4.0 of the @bitwarden/cli npm package, the official command-line interface for the Bitwarden password manager (~250,000 monthly downloads). The package was removed at approximately 19:30 ET, but Socket and JFrog telemetry confirms 334 installations during the ~93-minute window.
ROOT CAUSE — CI/CD COMPROMISE VIA THIRD-PARTY GITHUB ACTION: Investigation by Bitwarden, Endor Labs, and JFrog determined that the attacker did not compromise Bitwarden infrastructure or developer credentials directly. Instead, they compromised the checkmarx/ast-github-action GitHub Action — a third-party SAST integration consumed by Bitwarden's release pipeline. By poisoning a transitive workflow dependency, the attacker gained execution inside Bitwarden's GitHub-hosted runners with access to scoped NPM_TOKEN secrets, which they used to publish the trojanized package version.
PAYLOAD — bw1.js: The malicious version embeds an obfuscated JavaScript payload (bw1.js) executed via the package's postinstall hook. Static analysis by Socket and Endor Labs identified the payload's __decodeScrambled() routine using a numeric seed of 0x3039 (12345 decimal) for XOR/character-shift deobfuscation. Once decoded, bw1.js performs a multi-stage credential harvesting operation across Linux, macOS, and Windows hosts:
1. Filesystem credential sweep — recursively scans the user home directory and project trees for: ~/.aws/credentials, ~/.aws/config, ~/.azure/, ~/.config/gcloud/, ~/.npmrc, ~/.gitconfig, ~/.git-credentials, ~/.docker/config.json, ~/.kube/config, ~/.ssh/id_rsa/id_ed25519/id_ecdsa, .env / .env.local / .env.production files, GitHub Actions workflow files exposing secrets in plaintext, and CI runner mount paths under /run/secrets and /var/run/secrets.
2. AI-tool configuration theft — explicitly enumerates and exfiltrates configuration and session files for Anthropic Claude (Claude Code config, MCP server tokens), Cursor IDE, OpenAI Codex CLI, Aider, and AWS Kiro. This is novel: Shai-Hulud is the first observed npm-borne worm with explicit AI-developer-tool targeting. The attacker is interested both in API keys (for monetization or further attack infrastructure) and in stored project context that may reveal additional secrets.
3. Memory scraping of GitHub Actions Runner.Worker — when bw1.js detects execution under a GitHub Actions runner (GITHUB_ACTIONS=true), it locates the Runner.Worker process and reads its memory regions to extract decrypted secret values that GitHub injects as masked env vars. This bypasses the normal log-redaction protection because the values are already in cleartext in process memory.
4. Persistence via shell profile modification — appends a hidden launcher to ~/.bashrc and ~/.zshrc on Unix-like systems so that any subsequent interactive shell re-runs the harvester. A process lock file at /tmp/tmp.987654321.lock prevents concurrent re-entry on the same host.
5. Exfiltration — collected loot is concatenated, AES-256-GCM encrypted with a key derived from a hard-coded seed plus a per-host random nonce, and transmitted via HTTPS POST to https://audit.checkmarx[.]cx/v1/telemetry (resolving to 94.154.172.43, an attacker-controlled host impersonating Checkmarx). A fallback channel mirrors the encrypted blob into a freshly-created public GitHub repository on the victim's own account, named with a Dune-themed convention {word}-{word}-{3digits} (e.g. fremen-sietch-742, muaddib-shadout-018, harkonnen-arrakis-301). The encrypted commit body contains the marker string 'LongLiveTheResistanceAgainstMachines', which is now a high-confidence atomic indicator.
6. npm worm self-propagation — using the harvested npm tokens, bw1.js enumerates packages owned by the victim's npm account, repackages each with the bw1.js postinstall payload as package-updated.tgz, increments the patch version, and p
Weaknesses (CWE)
CWE-506, CWE-829, CWE-915, CWE-494, CWE-522, CWE-798
Target sectors: technology, software-development, financial, government, healthcare, consulting, any-sector-with-developers
Target regions: Global, North America, Europe, Asia-Pacific
Timeline
- First documented Shai-Hulud / TeamPCP wave: Trivy GitHub Action compromise, establishing the bw1.js obfuscator with seed 0x3039 and Dune-themed exfil-repo naming convention later seen in this incident.
- TeamPCP / Shai-Hulud second wave: LiteLLM npm package compromised, propagating bw1.js via npm postinstall and reusing the audit-style fake-vendor C2 pattern.
- checkmarx/ast-github-action pipeline poisoned by TeamPCP, providing the trusted-relationship foothold into any consumer's CI workflow that pinned the Action by mutable tag.
- @bitwarden/cli@2026.4.0 published to npm at 17:57 ET via attacker-controlled execution inside Bitwarden's GitHub Actions runner, signed with the legitimate scoped NPM_TOKEN.
- 334 confirmed npm installs of the malicious version across developer workstations and CI runners worldwide; bw1.js postinstall begins credential harvesting, AI-tool config theft, Runner.Worker memory scraping, and worm self-propagation.
- Bitwarden security and npm registry detect anomalous publish at approximately 19:30 ET (~93 minutes after publish) and unpublish 2026.4.0 from the registry; a clean 2026.4.1 is rapidly cut and signed.
- Coordinated disclosure: Bitwarden official statement, Socket, Endor Labs, Ox Security, JFrog, SOCRadar, BleepingComputer, SecurityWeek, and The Hacker News publish technical analyses, IOCs, and TeamPCP / Shai-Hulud attribution.
- Researchers expand IOC list to include the LongLiveTheResistanceAgainstMachines marker, the Dune-themed public-repo naming pattern, and the seed-0x3039 obfuscator fingerprint as code-similarity link to Trivy and LiteLLM waves.
- Downstream npm worm propagation observed: at least a dozen smaller packages owned by victim Bitwarden CLI users republished with bw1.js postinstall, prompting registry-wide takedowns and renewed npm-account 2FA enforcement guidance.
- Threadlinqs Intelligence publishes TL-2026-0429 with full MITRE mapping, detection coverage, and BeaconBeagle correlation on the audit.checkmarx[.]cx C2 infrastructure.
- As of 2026-05-29, the specific @bitwarden/cli@2026.4.0 package was unpublished within ~93 min and replaced by clean v2026.4.1, but the TeamPCP/Shai-Hulud actor and bw1.js (seed-0x3039) tooling remain a live, escalating threat. Same cluster ran new waves (TanStack May 11, @antv May 19: 639 malicious versions) and publicly released the Mini Shai-Hulud toolchain May 12; no takedown or arrest.
Detections & IOCs
As of 2026-09-04, this threat has 9 detection rule(s) across Splunk SPL, Microsoft KQL and Sigma, and 22 indicator(s) of compromise. Detection query text and full IOC values are available to authenticated users and programmatically via the Threadlinqs MCP server (Purple tier). View plans.
SUPPLY_CHAIN, CRITICAL, threat intelligence, cybersecurity, T1195, T1195.003, T1195.001, T1199, T1059.007, T1204.003, T1546.004, T1554, T1027, T1140