The Worm That Ate the Supply Chain: How One Threat Actor Compromised GitHub, npm, and the Tools You Trust
This Isn’t a Single Breach. It’s a Campaign.
Imagine a threat actor so persistent, so methodical, that they’ve spent the better part of a year systematically compromising the tools developers use every single day – the CI pipelines, the package registries, the code editor extensions. Now imagine they got into GitHub’s own internal repositories by poisoning a VS Code extension installed on an employee’s laptop.
That’s not a hypothetical. That’s TeamPCP, also tracked by Google Threat Intelligence Group as UNC6780. And their ongoing supply-chain campaign – anchored by a self-replicating worm dubbed “Mini Shai-Hulud” – has been one of the most aggressive attacks on developer infrastructure in recent memory.
The worm doesn’t just steal your npm tokens. It steals your crypto wallets. It decrypts your saved Chrome passwords. It validates every credential it finds with TruffleHog, uses them to access your cloud infrastructure, and then sells that access to ransomware operators. If you try to revoke the stolen tokens? Some variants will wipe your home directory as a parting gift.
Here’s what happened, why it matters, and what you should do about it.
What Is Mini Shai-Hulud?
Named after the sandworms of Dune (because apparently threat actors are Frank Herbert fans), Mini Shai-Hulud is a self-propagating supply-chain worm that targets GitHub Actions pipelines, npm, and PyPI. It doesn’t just plant malicious code but it reproduces. Steal a token from one package maintainer? Use it to publish malicious versions of every package that token can touch. Those malicious packages steal more tokens. The worm spreads.
The original Shai-Hulud worm appeared in September 2025, when over 500 npm packages were removed from the registry after a self-replicating credential-stealing worm swept through the ecosystem. It harvested GitHub tokens, npm publish tokens, and cloud credentials (AWS, GCP, Azure) from developer machines and CI runners, then used those stolen tokens to infect every package it could reach.
Mini Shai-Hulud is the evolved, more dangerous successor and it’s been devastating throughout 2026.
The Latest Wave: AntV Ecosystem (May 19, 2026)
On May 19, 2026, the attackers compromised the npm account atool, a maintainer of the popular @antv family of data-visualization packages. In a single 22-minute automated burst (01:39–02:06 UTC), they published approximately 639 malicious versions across 323 packages.
Those packages, including @antv/g2, @antv/g6, @antv/x6, @antv/l7, @antv/s2, and related libraries like echarts-for-react and timeago.js, collectively account for roughly 16 million weekly downloads.
The malicious versions embedded an obfuscated ~498KB JavaScript payload, executed via npm lifecycle hooks (preinstall scripts). It downloaded and ran the Bun runtime to evade Node.js-based detections, then went to work stealing everything it could find.
Rule of thumb: any @antv package published on May 19, 2026 should be treated as compromised.
The GitHub Breach: 3,800 Internal Repositories
One day after the AntV attack, on May 20, 2026, GitHub publicly confirmed that a threat actor had exfiltrated roughly 3,800 internal GitHub repositories.
The vector was almost painfully simple: a GitHub employee installed a poisoned VS Code extension from the official marketplace on their workstation. That single action was enough to compromise the device and give the attacker access to GitHub’s internal codebase.
GitHub disclosed the incident in a series of posts on X, stating they had “detected and contained a compromise of an employee device involving a poisoned VS Code extension.” They isolated the endpoint, removed the malicious extension, and began rotating critical secrets overnight.
The extension in question? Nx Console (nrwl.angular-console), a verified extension with over 2.2 million installs. The malicious version (v18.95.0) silently collected credentials from any workspace a developer opened. It was live for approximately 18 minutes on the VS Code Marketplace before being pulled.
Eighteen minutes. That’s all it took.
TeamPCP claimed the attack on the Breached cyber-crime forum, offering the stolen repositories for sale at a minimum of $50,000, with the usual threat to leak everything if no buyer emerged.
GitHub has stated there is no evidence that customer data was impacted, only internal repositories.
Same Team, Same Campaign
Here’s what connects the dots: both the Mini Shai-Hulud supply-chain worm and the GitHub internal repositories breach are attributed to the same threat actor. These aren’t copycats or coincidences. This is one sustained, coordinated campaign targeting developer tooling across the entire software supply chain.
TeamPCP (also known by handles like PCPcat, ShellForge, and DeadCatx3) operates with a consistent playbook: compromise the tools developers trust, steal credentials, use those credentials to compromise more tools, and monetize through access brokerage and extortion. Their primary payload, tracked as SANDCLOCK, is a credential stealer that scrapes process memory, sweeps filesystems for API keys and SSH keys, and targets cloud metadata services.
Google Threat Intelligence Group (GTIG) formally tracks this activity as UNC6780.
What the Worm Actually Does (The Technical Deep-Dive)
This is where things get genuinely alarming. The Mini Shai-Hulud payload isn’t just a simple token stealer. It’s a full-spectrum credential harvesting operation. Here’s what security researchers have documented:
Postinstall Hook
The worm adds a postinstall script to compromised packages – something like node scripts/check-env.js || true. The || true ensures the script never throws an error, so the install completes silently and nobody’s the wiser.
The Great Credential Sweep
Once executed, the payload (an obfuscated JavaScript file, sometimes exceeding 11 MB after deobfuscation) sweeps 134 distinct credential paths on developer machines and CI runners. The target list is breathtaking in its scope:
- Cloud credentials: AWS (~/.aws/credentials, IMDS, ECS task metadata, Secrets Manager, SSM parameters), Azure (~/.azure/, Key Vault), GCP (~/.config/gcloud/, Secret Manager)
- DevOps & CI/CD: GitHub PATs and OAuth grants, npm tokens (filtered for
bypass_2fa: true), Terraform state files and credentials, Kubernetes configs and service account tokens - SSH keys and TLS certificates:
~/.ssh/id_*, *.pem, *.key, *.p12, Let’s Encrypt certificates - AI tooling: Claude AI configs (~/.claude.json, MCP server configs), Kiro IDE settings — not just stealing credentials but also planting persistence hooks in AI coding agent configurations
- Password managers: 1Password CLI, Bitwarden CLI, LastPass CLI configurations
- Messaging app sessions: Signal, Slack cookies, Discord, Telegram, Element
- VPN configs: NordVPN, ProtonVPN, OpenVPN, FileZilla server lists
- Shell history: .bash_history, .zsh_history, .mysql_history, .psql_history
- System files: /etc/passwd, /etc/shadow, auth logs
Crypto Wallet Theft
The payload explicitly targets cryptocurrency wallet data across a remarkable range of platforms:
- Bitcoin: wallet.dat files
- Ethereum: keystore directories
- Solana: validator keypairs
- Desktop wallets: Exodus, Electrum, Atomic Wallet, Ledger Live
- Browser-based wallets: MetaMask vault data (Chrome, Brave, Firefox), Phantom wallet data
- Other chains: Cardano signing keys, Monero, Litecoin, Dogecoin, Zcash, Dash, Ripple configurations
If you run a crypto wallet on the same machine you develop on this worm was designed to find it.
Chrome Password Decryption on Linux
The payload also targets saved browser passwords. On Linux, Chrome’s legacy password storage used a key derived from PBKDF2("peanuts", "saltysalt") which is a well-known weakness that means any code running in the user’s context can decrypt saved passwords. The malware takes full advantage.
Encrypted Exfiltration
Everything the worm collects is compressed, encrypted with AES-256-GCM, and the AES key is wrapped with RSA-4096 OAEP SHA-256 using an attacker-controlled public key embedded in the payload. Even if defenders intercept the exfiltrated data, they cannot read it without the attacker’s private key.
The encrypted data is then exfiltrated through two redundant C2 channels: a webhook endpoint and an Internet Computer (ICP) canister, a clever choice that makes the C2 infrastructure resilient and difficult to take down.
Self-Propagation
When the worm finds npm publish tokens, it doesn’t just hoard them. It:
- Lists every package the token can publish.
- Injects the malicious payload into each package’s
package.json(adding the postinstall hook) and tarball. - Bumps the version number and publishes directly to the npm registry via raw HTTP PUT – bypassing the npm CLI entirely and its standard telemetry.
- Filters specifically for tokens with
bypass_2fa: true– because even 2FA won’t save you if the token can skip it.
The worm has also demonstrated cross-ecosystem jumps, attempting to propagate from npm into PyPI via import-time code execution in compromised Python packages and extending its reach beyond the JavaScript ecosystem entirely.
Process Memory Extraction
On GitHub Actions runners, the payload spawns a child process that reads /proc/{pid}/mem of the Runner.Worker process, extracting masked secrets directly from runner memory. This means even secrets that GitHub masks in logs are still accessible to the malware at runtime.
Dead Man’s Switch
Some variants include a background daemon that monitors whether stolen tokens are still valid. If tokens are revoked, meaning that you try to cut off the attacker’s access, the daemon can wipe the victim’s entire home directory. The attackers prioritize speed over stealth, and they’d rather destroy your data than lose access gracefully.
The Ransomware Connection
TeamPCP doesn’t stop at credential theft. According to security researchers, they use TruffleHog to rapidly validate every stolen credential against live services confirming which cloud keys, GitHub tokens, and API keys still work, often within hours of theft. Those validated credentials are then used in two ways:
- Direct exploitation: Accessing cloud infrastructure (AWS, Azure, GCP), pivoting through CI/CD systems, and selling access to other threat actors.
- Initial access brokerage: TeamPCP appears to operate as an Initial Access Broker (IAB), selling validated access to groups including ransomware operators. Reporting suggests connections to groups like ShinyHunters and an associated ransomware operation tracked as CipherForce.
So that stolen npm token doesn’t just mean someone published a malicious package. It means someone with a validated cloud credential from your CI pipeline could be handing ransomware operators the keys to your production infrastructure.
The 2026 Hit List
This campaign didn’t start with the AntV packages, and it hasn’t stopped. Here’s a timeline of confirmed and attributed incidents throughout 2026:
March 2026: Trivy → Checkmarx → LiteLLM Cascade
- Aqua Security Trivy (March 19): Compromised GitHub Action tags and release pipelines. The root vulnerability was tracked as CVE-2026-33634 (CVSS 9.4). Thousands of CI/CD workflows ran poisoned Trivy actions. Stolen credentials powered the next wave of attacks.
- Checkmarx KICS (March 21–23): GitHub Action workflows and OpenVSX plugins trojanized. Anyone running the affected actions in a ~13-hour window had credentials stolen.
- LiteLLM (March 23): CI/CD pipeline compromised (which itself used Trivy). Malicious PyPI releases 1.82.7 and 1.82.8 exfiltrated AI provider API keys — particularly damaging because LiteLLM stores keys for multiple AI services in one place.
- Telnyx Python SDK also compromised during this wave.
April 2026: Dormant Packages and the Bitwarden Cascade
- @fairwords packages (April 8): Three packages –
@fairwords/websocket,@fairwords/loopback-connector-es, and@fairwords/encryption– were compromised. All three had been dormant since 2022, making them easy targets with likely stale but still-valid maintainer tokens. Malicious versions 1.0.38–1.0.39, 1.4.3–1.4.4, and related versions were published with the worm’s postinstall credential stealer. - Checkmarx KICS Docker image (April 22): TeamPCP poisoned
checkmarx/kics:lateston Docker Hub. - Bitwarden CLI (April 22): Bitwarden’s CI/CD automatically pulled the malicious KICS image via Dependabot. This cascaded into the compromise of
@bitwarden/clinpm package version 2026.4.0. A password manager’s own publishing pipeline, compromised by a security scanner’s Docker image. The irony writes itself.
May 2026: TanStack, AntV, Microsoft, node-ipc, GitHub
- TanStack (May 11): 84 malicious artifacts across 42
@tanstackpackages published in approximately 6 minutes.@tanstack/react-routeralone has ~12 million weekly downloads. This was the first documented npm malware with valid SLSA Build Level 3 provenance – the attacker abused the official build system itself. The payload included a 1-in-6 disk-wipe trigger specifically targeting hosts in Israeli and Iranian locales. - node-ipc (May 14): Three versions — 9.1.6, 9.2.3, and 12.0.1 – were compromised with an obfuscated stealer/backdoor. The payload was injected into the CommonJS bundle (
node-ipc.cjs) as an obfuscated IIFE that triggered on everyrequire('node-ipc'). It harvested credentials across ~90 categories and exfiltrated via HTTPS and a DNS TXT-based channel, overriding the system DNS resolver to use Google Public DNS (8.8.8.8) to bypass local DNS security.node-ipchas hundreds of downstream dependents. - AntV ecosystem (May 19): 323 packages, 639 malicious versions, 16 million weekly downloads. 22 minutes.
- Microsoft durabletask Python SDK (PyPI): Three progressively compromised versions delivering a credential-stealing payload that spreads through AWS and Kubernetes environments.
- Nx Console VS Code extension (May 18–19): Verified extension with 2.2M installs backdoored. Used to breach GitHub’s internal repositories.
Also in the Campaign Scope
- SAP CAP packages (
@cap-js/sqlite,@cap-js/postgres,@cap-js/db-service,mbt) – compromised via misconfigured npm Trusted Publishing OIDC binding that trusted any workflow in the repository, not just the canonical release workflow - Axios npm package (targeted in a concurrent compromise – reporting suggests this may be a different threat actor, UNC1069, but may have used tokens stolen in the broader TeamPCP credential ecosystem)
- Checkmarx Jenkins AST plugin (third Checkmarx compromise in three months – malicious plugin installed on hundreds of Jenkins controllers)
- UiPath, Mistral AI, OpenSearch, Guardrails AI, Intercom client – packages tied to these organizations also hit in various waves
- PyTorch Lightning (PyPI) – versions 2.6.2 and 2.6.3 compromised with import-time credential-stealing code

The Attack Loop: How It All Connects
At a high level, the Mini Shai-Hulud worm and the broader TeamPCP campaign follow a devastatingly elegant loop:
- Fork and PR: The attacker forks a popular open-source repository and opens a pull request targeting
pull_request_targetworkflows – or simply uses a stolen maintainer token. - Abuse GitHub Actions: Misconfigured
pull_request_targettriggers or stolen OIDC tokens give access to repository secrets – including npm and PyPI publish tokens. - Harvest everything: The SANDCLOCK payload sweeps 134 credential paths, steals crypto wallets, decrypts browser passwords, scrapes process memory, and extracts cloud credentials.
- Validate with TruffleHog: Every stolen credential is tested live against cloud services. Working keys are prioritized. Access is validated within hours.
- Auto-publish malicious packages: Stolen npm/PyPI tokens are used to publish malicious versions via direct HTTP PUT – no CLI, no telemetry, no 2FA if the token allows bypass.
- Propagate and monetize: Validated cloud access is sold to ransomware operators. Stolen GitHub repos are sold on cybercrime forums. The worm keeps spreading.
The VS Code extension vector adds another dimension: by poisoning extensions installed on developer workstations, attackers steal credentials directly from the source – personal access tokens, SSH keys, and cloud credentials stored on the developer’s machine. This is how GitHub’s internal repositories were compromised.
And because the malicious packages are published through real CI workflows using stolen tokens, they carry valid provenance and SLSA attestations. The infrastructure says “this came from the official pipeline.” The pipeline was compromised. Trust is the vulnerability.
What This Means for You
If you or your organization uses any of the tools, packages, or ecosystems mentioned above – and statistically, you probably do – here’s what you need to do.
Immediate Actions
- Audit your dependencies. Check lockfiles (
package-lock.json,pnpm-lock.yaml,yarn.lock,requirements.txt) for any packages published during the known attack windows. Any@antv/*package from May 19, any@tanstack/*package from May 11, Bitwarden CLI 2026.4.0, LiteLLM 1.82.7-1.82.8, node-ipc 9.1.6/9.2.3/12.0.1, any Trivy or KICS actions run since March 19,@fairwords/websocket1.0.38-1.0.39, and@fairwords/loopback-connector-es1.4.3-1.4.4 should be treated as potentially compromised. - Rotate everything. If there’s any chance a compromised package or extension touched your environment, rotate all credentials: GitHub PATs, npm tokens, cloud provider keys (AWS, GCP, Azure), SSH keys, Kubernetes secrets, CI/CD tokens, crypto wallet keys, browser-stored passwords, and any secrets in
.envfiles or vaults. Don’t assume the attackers didn’t get to something – the credential sweep covers 134 path patterns. - Check for dead-man’s switches. Before rotating tokens on Linux machines, check for suspicious user services:
systemctl --user list-unitsand look for anything unusual, particularlygh-token-monitor.serviceor similar. Back up critical data before cleanup. - Pin and freeze. Stop using floating version ranges (
^,~,latest) in production. Pin to known-good versions with exact hashes. - Clear caches. Clear npm caches, internal artifact proxies (Verdaccio, Artifactory, Nexus), and any CI runner caches that may have cached malicious tarballs.
Long-Term Hardening
- Lock down GitHub Actions. Audit every workflow using
pull_request_target. Ensure secrets are never accessible to forks. Gate publishing behind GitHub Environments with manual approval. Use OIDC-based authentication scoped to specific workflow files and branches – not repo-level trust. - Use OIDC trusted publishing. For npm and PyPI, move to OIDC-based publishing scoped to specific workflow files and branches. Eliminate long-lived publish tokens entirely.
- Treat VS Code extensions as untrusted code. Because they are. Implement policies that restrict which extensions can be installed. Consider minimum-age policies (don’t install updates published in the last 48 hours). Nx Console was live for 18 minutes – a delay policy would have blocked it entirely.
- Disable or restrict npm lifecycle scripts. Run
npm ci --ignore-scriptsin CI when packages don’t require native builds. Most of these attacks rely onpreinstallandpostinstallhooks. - Use dependency scanning. Tools like Snyk, Socket, and StepSecurity have detection signatures for Mini Shai-Hulud variants. Enable them.
- Monitor registries for version bursts. 639 versions in 22 minutes is not normal. Set up alerts for unusual publication velocity in packages you depend on.
- Enforce MFA on npm and GitHub accounts. Non-negotiable at this point.
- Separate development and publishing environments. Don’t publish packages from the same machines where you browse the web and install VS Code extensions. Isolate your release pipeline.
- Monitor for C2 indicators. Watch for outbound connections to known Mini Shai-Hulud infrastructure, unexpected DNS TXT traffic, and processes that override the system DNS resolver.
The Bottom Line
TeamPCP / UNC6780 didn’t find one vulnerability and exploit it. They turned the entire developer toolchain into a weapon against itself. CI pipelines, package registries, code editor extensions, Docker images, Jenkins plugins and every layer of trust in the software supply chain has been targeted, and in many cases, successfully compromised.
Their operation reads like a worst-case scenario: a self-replicating worm that steals everything from cloud credentials to crypto wallets, validates access with TruffleHog, sells it to ransomware operators, and wipes your machine if you try to cut them off. The GitHub breach, 3,800 internal repositories stolen through a VS Code extension that was live for 18 minutes, is the exclamation point.
When the platform that hosts most of the world’s open-source code gets compromised through a code editor extension, the message is clear: the perimeter is everywhere, and trust is the attack surface.
This campaign is ongoing. New targets will appear. The worm will evolve. Harden your tooling, rotate your credentials, and for the love of all that is secure stop blindly trusting everything in your package.json.