Lyrie
Supply-Chain Deep-Dive
0 sources verified·10 min read
By Lyrie Threat Intelligence·4/30/2026

TL;DR

Between late February and April 22, 2026, a crew called TeamPCP executed a cascading supply chain attack that progressed through four distinct trusted tools — Trivy (OSS vulnerability scanner), KICS (Checkmarx IaC scanner), Checkmarx GitHub Actions, and finally Bitwarden CLI — harvesting developer credentials at each stage and using stolen CI/CD secrets from one tool to compromise the next. The Bitwarden CLI payload (@bitwarden/[email protected]) was live for just 90 minutes on April 22 before takedown, but it targeted 297,738 monthly downloads and every CI/CD pipeline using Bitwarden's programmatic vault access. The self-propagating worm architecture means secondary spread through victim npm packages may have continued well after the malicious version was yanked.


Background: The Problem With Trusting Your Security Tools

There is a painful irony at the center of the TeamPCP campaign: every tool they compromised was a tool developers specifically use to improve security. Trivy scans containers for vulnerabilities. KICS scans infrastructure-as-code for misconfigurations. Bitwarden CLI injects secrets into pipelines so teams don't have to hardcode credentials. These are precisely the tools granted deep access to production secrets, cloud credentials, and CI/CD token stores. Compromising them doesn't just yield one developer's machine — it yields the keys to every downstream deployment.

This is not a novel insight. The SolarWinds Orion compromise in 2020 followed the same logic. What TeamPCP demonstrated in early 2026 is that the technique now operates at open-source ecosystem scale, with sub-2-hour exposure windows, and that the attackers have industrialized both the detection-evasion and the credential exfiltration infrastructure.


Technical Analysis

Stage 1: Trivy — The Initial Beachhead (February–March 2026)

Trivy is maintained by Aqua Security and downloaded millions of times per month. TeamPCP compromised it in late February 2026, injecting credential-stealing malware into the scanner binary. The initial access vector has not been fully disclosed, but post-incident analysis by Socket and Endor Labs suggests it was a combination of weak CI/CD secret management and a dependency confusion attack on Trivy's own build pipeline.

Once the trojanized Trivy was live, it behaved identically to the legitimate scanner — running vulnerability reports, returning expected output — while simultaneously harvesting:

  • SSH keys from developer home directories
  • Kubernetes configuration files (~/.kube/config)
  • Cloud provider credentials (AWS ~/.aws/credentials, GCP ~/.config/gcloud/, Azure ~/.azure/)
  • Environment variables containing CI/CD secrets
  • npm authentication tokens (.npmrc)
  • GitHub personal access tokens and runner tokens

Every developer or pipeline that pulled and executed the compromised Trivy image handed TeamPCP a copy of their entire secrets surface. This gave the attackers authenticated access to the downstream repositories and CI/CD pipelines of an unknown but likely large number of organizations. Checkmarx's KICS repository was among them.

Stage 2: KICS and Checkmarx GitHub Actions (March 23, 2026)

Using secrets stolen from Trivy's compromise, TeamPCP on March 23, 2026 pivoted to KICS — Checkmarx's open-source infrastructure-as-code security scanner. They injected the same credential-harvesting payload into the official checkmarx/kics Docker Hub image.

Socket's analysis described the poisoned image in detail: "The bundled KICS binary was modified to include data collection and exfiltration capabilities. The malware could generate an uncensored scan report, encrypt it, and send it to an external endpoint — creating a serious risk for teams using KICS to scan IaC files that may contain credentials or other sensitive configuration data." [1]

Simultaneously, they compromised two components of Checkmarx's developer tooling infrastructure:

1. Two Open VSX marketplace plugins — Checkmarx security extensions used directly in developer IDEs

2. Two GitHub Actions workflows, including checkmarx/ast-github-action — a workflow component imported by hundreds of downstream repositories

The GitHub Actions compromise is the critical pivot. GitHub Actions workflows are trusted by definition — they run in the context of the importing repository, with full access to its secrets. Any repository that references checkmarx/ast-github-action without pinning a specific commit hash was now running TeamPCP's code in their own CI/CD context, with access to their own secrets.

Bitwarden's repository was one of those repositories.

Stage 3: Bitwarden CLI — The Worm Activation (April 22, 2026)

The compromised Checkmarx GitHub Action ran inside Bitwarden's build pipeline and harvested the credentials needed to publish to npm under the @bitwarden scope. At 5:57 PM ET on April 22, 2026, @bitwarden/[email protected] was pushed to npm.

At 7:30 PM ET — 93 minutes later — Bitwarden detected the compromise and yanked the package.

In that window, a package with 297,738 monthly downloads was serving malware to every automated npm install or dependency update that pulled the latest version.

#### The Payload Architecture

The malicious version introduced two new files — bwsetup.js and bw1.js — while modifying package.json to redirect execution:

preinstall: "node bwsetup.js"
bin: { "bw": "bwsetup.js" }   // previously: "bw": "build/bw.js"

bwsetup.js acts as a stager: it checks for the Bun JavaScript runtime, downloads Bun 1.3.13 from GitHub if absent, then executes bw1.js via Bun. This two-stage approach means the primary payload runs outside Node.js's standard module system — bypassing many npm-level security controls designed for Node execution.

bw1.js is a 10.15 MB single-line obfuscated payload. Its architecture:

  • String table obfuscation: 43,436-entry array (_0x1ee1) with runtime decoder (_0x214e), so all URLs, file paths, and API names only resolve at execution time
  • Secondary cipher: A scrambled-alphabet cipher (seed 0x3039) protects the most sensitive strings — C2 domains, shell commands, credential file paths — from recovery via the main table
  • Array rotation IIFE: Self-invoking function rotates the string array at startup, preventing static analysis from reconstructing readable call sites

#### Anti-Analysis and Operator Self-Exclusion

Before executing any malicious activity, the payload runs a gauntlet of self-termination checks:

| Check | Condition | Action |

|---|---|---|

| Russian locale | Intl API / $LC_* / $LANG starts with ru | process.exit(0) |

| Not in CI/CD | Checks 30+ CI environment variables | process.exit(0) |

| PID lock exists | $TMPDIR/tmp.987654321.lock with live PID | process.exit(0) |

| Signal handlers | SIGINT / SIGTERM | Replaced with no-ops |

| Console output | console.log / console.error | Silenced |

The Russian locale check is operational security: TeamPCP doesn't want to compromise their own development machines. It also gives attribution researchers a data point.

The CI/CD-only execution constraint is deliberate targeting: the attackers aren't interested in individual developer machines; they want the secrets that live in pipeline environments — the AWS deploy keys, the Docker registry tokens, the npm publish credentials that let them continue propagating.

#### Credential Exfiltration

The payload harvested:

  • npm authentication tokens
  • GitHub tokens and Actions runner tokens
  • AWS credentials and configuration
  • GCP service account files
  • Azure CLI credentials
  • Environment variables (full env dump)
  • SSH keys and known_hosts

Stolen data is AES-256-GCM encrypted using the attacker's public key — meaning even if you find an exfiltration repository, you cannot read the contents without the private key — then pushed to newly created public GitHub repositories in the victim's own namespace, using the stolen GitHub token. The repository naming pattern typically incorporated "results-TIMESTAMP-ID.json" filenames with the string "Shai-Hulud: The Third Coming" in repository metadata.

This exfiltration model is clever: using the victim's own GitHub account to store stolen data means traditional network egress monitoring won't flag it (GitHub traffic is expected), and the use of the victim's account provides plausible attribution confusion.

#### Self-Propagation

If the payload found npm publish tokens with write access to other packages, it would inject itself into those packages and publish new versions. This is the worm behavior that gives the Shai-Hulud campaign its name — the worm moves through the npm ecosystem by riding the publish rights of compromised developers.

The Lapsus$ Postscript

On April 26–27, 2026, Lapsus$ announced they had obtained Checkmarx source code, API keys, database credentials, and employee data, and published a subset to their leak site. Checkmarx confirmed the data appeared to originate from a GitHub repository, and that "access to that repository was facilitated through the initial supply chain attack of March 23, 2026." [2]

TeamPCP's credential harvest from Checkmarx had apparently been acquired or sold to Lapsus$, adding a ransomware/extortion layer to what was originally a pure credential-theft operation.


IOCs / Indicators of Compromise

Malicious npm package:

Payload files introduced:

  • bwsetup.js — Node ESM stager, Bun downloader
  • bw1.js — 10,154,904 bytes, single-line obfuscated Bun payload

Bun version fetched:

  • bun-v1.3.13 from github.com/oven-sh/bun/releases

Exfiltration indicators:

  • New GitHub repositories created in victim namespace with results-*.json files
  • Repository metadata containing string: Shai-Hulud: The Third Coming
  • Encrypted JSON with envelope and key fields (AES-256-GCM, attacker-keyed)

Behavioral indicators:

  • preinstall hook executing node bwsetup.js during npm install
  • Bun binary extracted to package directory (node_modules/.bin/ or package root)
  • Outbound connections to GitHub API for repository creation using victim token
  • $TMPDIR/tmp.987654321.lock PID lock file presence

Affected GitHub Action:

  • checkmarx/ast-github-action (unpinned refs, March–April 2026)

KICS Docker Hub:

  • checkmarx/kics images published March 23–24, 2026 (verify digest against official Checkmarx advisories)

Lyrie Take

The security tool supply chain is the most underdefended attack surface in enterprise environments.

TeamPCP's campaign exposes three compounding failures that Lyrie's threat model treats as first-class risks:

1. Transitive trust without verification. Developers and pipelines extend implicit trust to security tooling that other tooling uses. Checkmarx GitHub Actions are trusted because they're Checkmarx. Bitwarden CLI is trusted because it's Bitwarden. Neither trust relationship was verified at execution time against a tamper-evident baseline. Lyrie's behavioral monitoring would have flagged bwsetup.js at install time — a preinstall hook that downloads a Bun binary and executes a 10MB obfuscated payload is not normal Bitwarden CLI behavior, regardless of who published it.

2. The CI/CD environment is the crown jewels. TeamPCP wasn't interested in browser passwords. They targeted the environment variables and token stores of CI/CD pipelines because that's where the deploy keys live — the credentials that can push malicious code to production, publish packages to package registries, and persist access across the entire software supply chain. Lyrie's pipeline instrumentation treats any unexpected outbound connection or new GitHub API call from within a build job as an anomaly requiring immediate investigation.

3. Credential theft via public repositories. The AES-256-GCM + public GitHub exfiltration model is anti-forensic by design. Traditional DLP tools won't flag a GitHub push as exfiltration. Lyrie's approach — monitoring for unexpected repository creation events using CI-context tokens — catches this specific technique, which Shai-Hulud has now used across three campaigns.

The broader concern: TeamPCP's 60-day progression from Trivy to Bitwarden CLI represents a manually curated attack chain where each stage's stolen credentials were evaluated and selected for their downstream yield. This is not automated spray-and-pray. It's targeted, patient, and scalable.


Defender Playbook

Immediate (if you ran @bitwarden/[email protected]):

1. Rotate all secrets accessible from the affected environment: npm tokens, GitHub PATs, AWS/GCP/Azure credentials, SSH keys, Kubernetes configs

2. Search your GitHub org for repositories matching the Shai-Hulud pattern and revoke any tokens used

3. Check $TMPDIR/tmp.987654321.lock on affected build machines

4. Audit GitHub Actions runs in the affected time window for unexpected API calls

If you used checkmarx/ast-github-action without pinning (March–April 2026):

5. Treat all secrets accessible during those Actions runs as compromised

6. Audit GitHub Actions logs for unexpected git push or GitHub API calls

Structural hardening:

7. Pin GitHub Actions by commit SHA, not by tag or branch — tags can be moved

8. Pin npm dependencies with exact versions or use lock files; consider npm ci with integrity checking

9. Audit all preinstall / postinstall hooks in your dependency tree — these execute arbitrary code during npm install

10. Implement egress filtering in CI/CD environments: build jobs should not be able to create GitHub repositories or push to namespaces outside the build target

11. Use short-lived OIDC tokens for cloud provider access from CI/CD instead of long-lived static credentials

12. Evaluate Bitwarden CLI alternatives for secret injection (HashiCorp Vault Agent, AWS Secrets Manager SDK) for pipelines requiring the highest assurance

13. Monitor for anomalous npm publish events from your org's tokens using npm audit logs


Sources

1. Socket Security — "Checkmarx Supply Chain Compromise" (April 2026) — socket.dev/blog/checkmarx-supply-chain-compromise

2. The Register — "Ongoing supply-chain attack explicitly targeting security, dev tools" (April 27, 2026) — theregister.com/2026/04/27/supply_chain_campaign_targets_security/

3. Endor Labs — "Shai-Hulud: The Third Coming — Inside the Bitwarden CLI 2026.4.0 Supply Chain Attack" (April 2026) — endorlabs.com/learn/shai-hulud-the-third-coming

4. OX Security — "Inside the Shai-Hulud Supply Chain Attack" (April 2026) — ox.security/blog/shai-hulud-bitwarden-cli-supply-chain-attack/

5. GitGuardian — "No Off Season: Three Supply Chain Campaigns Hit npm, PyPI, and Docker Hub in 48 Hours" (April 2026) — blog.gitguardian.com/three-supply-chain-campaigns-hit-npm-pypi-and-docker-hub-in-48-hours/

6. The Hacker News — "Bitwarden CLI Compromised in Ongoing Checkmarx Supply Chain Campaign" (April 2026) — thehackernews.com/2026/04/bitwarden-cli-compromised-in-ongoing.html

7. Checkmarx Security Advisory — "Checkmarx Security Update" (April 26, 2026) — checkmarx.com/blog/checkmarx-security-update-april-26/


Lyrie.ai Cyber Research Division — Senior Analyst Desk

Lyrie Verdict

Lyrie's autonomous defense layer flags this class of exposure the moment it surfaces — no signature update required.