# Bitwarden CLI npm Supply Chain Compromise (@bitwarden/cli v2026.4.0) — Shai-Hulud: The Third Coming / TeamPCP

> 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 PM–7:30 PM ET), netting 334 confirmed installs before takedown. The embedded bw1.js payload harvested GitHub/npm tokens, SSH keys, .env files, AWS/Azure/GCP credentials, and AI-tool configs (Claude/Cursor/Codex/Aider/Kiro), memory-scraped the GitHub Actions Runner.Worker, AES-256-GCM-encrypted the loot, and exfiltrated to audit.checkmarx[.]cx and Dune-themed public GitHub repos while self-propagating as an npm worm. This is the third confirmed Shai-Hulud campaign wave, following the Trivy and LiteLLM compromises run by the same actor cluster.

- **Published:** 2026-04-27T12:00:00Z
- **Last reviewed:** 2026-04-27T12:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-0429
- **ID:** TL-2026-0429
- **Severity:** CRITICAL (CVSS 9.6)
- **Category:** SUPPLY_CHAIN
- **Status:** ACTIVE
- **Actor:** TeamPCP
- **Detections:** 9 · **IOCs:** 22 (full data via the Threadlinqs MCP server — Purple tier)

## Description

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 publishes the trojanized release. This is the worm component that drove Shai-Hulud's prior Trivy and LiteLLM waves and turns every successful credential capture into a downstream supply chain incident.

DEFENSE EVASION: The payload performs a Russian locale check (process.env.LANG / system locale APIs) and exits silently if a Russian-speaking environment is detected, suggesting the operators wish to avoid local law enforcement attention or are operating from a Russian-speaking jurisdiction. The obfuscator's seed 0x3039 is shared with the Trivy and LiteLLM bw1.js variants, providing strong code-similarity evidence linking the three campaigns to a single tooling baseline. Network exfiltration mimics legitimate Checkmarx telemetry shape on the audit.checkmarx[.]cx fake-vendor domain to evade DLP heuristics watching for unknown destinations.

ATTRIBUTION: TeamPCP — also tracked as the Shai-Hulud actor cluster by Endor Labs, Ox Security, and JFrog — has been linked to two prior npm supply chain campaigns in 2026: the Trivy GitHub Action compromise (~2026-03) and the LiteLLM npm package compromise (~2026-04, weeks before this incident). Attribution is HIGH confidence based on shared payload tooling (identical __decodeScrambled obfuscator with seed 0x3039), shared C2 infrastructure pattern (vendor-impersonation domains hosted on the same CIDR neighborhood), shared exfiltration marker string, and the Dune-themed GitHub repository naming convention seen in all three campaigns.

BLAST RADIUS: With 334 confirmed installs of @bitwarden/cli@2026.4.0 — many on developer workstations and CI runners with broad cloud privileges — the credential-theft impact is severe. Defenders must treat any cloud, GitHub, npm, or AI-platform credential touched by an affected host as compromised, rotate immediately, and audit downstream npm packages owned by victim npm accounts for worm-injected republishes.

REMEDIATION: Bitwarden has published a clean v2026.4.1 release. The malicious 2026.4.0 has been unpublished by npm. Affected organizations should: (a) inventory all hosts that ran `npm install @bitwarden/cli@2026.4.0` between 17:57 ET and 19:30 ET on 2026-04-22; (b) rotate every credential that existed on those hosts (cloud keys, GitHub PATs, npm tokens, SSH keys, AI-tool API keys); (c) audit GitHub for Dune-pattern public repos created on victim accounts; (d) block audit.checkmarx[.]cx and 94.154.172.43 at egress; (e) review every npm package owned by potentially-compromised npm accounts for unauthorized republishes.

## MITRE ATT&CK

- T1195 Supply Chain Compromise
- T1195.003 Compromise Hardware Supply Chain
- T1195.001 Compromise Software Dependencies and Development Tools
- T1199 Trusted Relationship
- T1059.007 Command and Scripting Interpreter: JavaScript
- T1204.003 User Execution: Malicious Image
- T1546.004 Event Triggered Execution: Unix Shell Configuration Modification
- T1554 Compromise Host Software Binary
- T1027 Obfuscated Files or Information
- T1140 Deobfuscate/Decode Files or Information
- T1480.001 Execution Guardrails: Environmental Keying
- T1036.005 Match Legitimate Resource Name or Location
- T1078.004 Valid Accounts: Cloud Accounts
- T1056.004 Input Capture: Credential API Hooking
- T1552.001 Unsecured Credentials: Credentials In Files
- T1552.004 Unsecured Credentials: Private Keys
- T1555 Credentials from Password Stores
- T1003.007 OS Credential Dumping: Proc Filesystem
- T1083 File and Directory Discovery
- T1057 Process Discovery
- T1071.001 Application Layer Protocol: Web Protocols
- T1573.001 Encrypted Channel: Symmetric Cryptography
- T1041 Exfiltration Over C2 Channel
- T1567.001 Exfiltration Over Web Service: Exfiltration to Code Repository
- T1537 Transfer Data to Cloud Account

## Sources

- [Bitwarden CLI Compromised in Ongoing Checkmarx Supply Chain Campaign](https://thehackernews.com/2026/04/bitwarden-cli-compromised-in-ongoing.html)
- [Socket — Bitwarden CLI Compromised (technical IOCs and bw1.js analysis)](https://socket.dev/blog/bitwarden-cli-compromised)
- [Bitwarden Statement on Checkmarx Supply Chain Incident](https://community.bitwarden.com/t/bitwarden-statement-on-checkmarx-supply-chain-incident/96127)
- [Endor Labs — Shai-Hulud The Third Coming: Inside the Bitwarden CLI 2026.4.0 Supply Chain Attack](https://www.endorlabs.com/learn/shai-hulud-the-third-coming----inside-the-bitwarden-cli-2026-4-0-supply-chain-attack)
- [Ox Security — Shai-Hulud: The Third Coming, Bitwarden CLI Backdoored](https://www.ox.security/blog/shai-hulud-bitwarden-cli-supply-chain-attack/)
- [JFrog — TeamPCP Campaign Spreads to npm via Hijacked Bitwarden CLI](https://research.jfrog.com/post/bitwarden-cli-hijack/)
- [SOCRadar — Bitwarden CLI Hijacked in npm Supply Chain Attack Linked to TeamPCP](https://socradar.io/blog/bitwarden-cli-hijacked-npm-supply-chain-teampcp/)
- [SecurityWeek — Bitwarden NPM Package Hit in Supply Chain Attack](https://www.securityweek.com/bitwarden-npm-package-hit-in-supply-chain-attack/)
- [BleepingComputer — Bitwarden CLI npm package compromised to steal developer credentials](https://www.bleepingcomputer.com/news/security/bitwarden-cli-npm-package-compromised-to-steal-developer-credentials/)
- [MITRE ATT&CK — T1195.003 Compromise Software Supply Chain: CI/CD](https://attack.mitre.org/techniques/T1195/003/)
- [OpenSSF — Pinning GitHub Actions to commit SHAs](https://github.com/ossf/scorecard/blob/main/docs/checks.md#pinned-dependencies)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-0429
