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
Detections & IOCs
As of 2026-07-28, 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