BACK TO BLOGS Back to Press Releases

How Mini Shai-Hulud worm moved through supply chain, impacting GitHub, Nx Console, & TanStack

Written by:

Andrea Pomaranski, Special Projects IT Engineer

How trusted credentials, trusted workflows, and trusted update mechanisms led to malware

A GitHub employee opened a Visual Studio Code extension they had likely used before. Within seconds, a 498 KB payload executed silently in the background.

Eighteen minutes later, Visual Studio Marketplace removed the malicious version. By then, the damage had already spread. GitHub would later confirm that the compromised workstation led to the breach of approximately 3,800 internal repositories.

The extension was real. The publisher was real. The repository was real. The version was not.

What makes this incident significant is not the malware itself. It is the path the malware took to get there.

This was not a traditional vulnerability exploit. No browser exploit, no remote code execution bug, and no software flaw attackers "broke into." The attack moved through trusted credentials, trusted publishing workflows, trusted repositories, trusted package managers, and trusted update mechanisms. Every step looked legitimate because every step was legitimate.

The first compromise wasn't GitHub

The GitHub breach did not begin with GitHub. It began a week earlier inside TanStack's CI/CD pipeline.

The attack was part of Mini Shai-Hulud, a self-propagating supply chain worm attributed to TeamPCP. Unlike traditional malware campaigns that focus on end-user systems, Mini Shai-Hulud targets software publishers themselves.  

Its objective is simple: Steal credentials from one development environment and use them to compromise the next.

The entry point was a carefully constructed pull request attack against the TanStack GitHub Actions workflows. The attacker created a fork of TanStack/router under the account zblgg, naming it zblgg/configuration to evade fork-list searches. The malicious commit was authored under a fabricated claude@users.noreply.github.com identity and prefixed with [skip ci] to suppress CI on the push event. The repository was then used to open PR #7378. That pull request triggered the repository's bundle-size.yml workflow through a pull_request_target configuration.

GitHub Security Lab published guidance on this attack pattern in 2021, warning that combining pull_request_target with an explicit checkout of untrusted PR code is dangerous and may lead to repository compromise. Unlike ordinary pull requests, pull_request_target executes in the security context of the target repository rather than the fork. In practice, that means untrusted code can execute with access to secrets, workflows, and permissions belonging to the project being targeted.

Poisoning the build pipeline without touching the build

The attacker poisoned GitHub Actions cache entries without modifying source code, workflow files, or repository history.

The malicious payload was designed to write into the pnpm store to the same cache key that TanStack’s release workflow later looked up. When the benchmark job completed, GitHub Actions saved a now-poisoned 1.1 GB store to that key. When the release workflow next ran against main, it restored the poisoned cache exactly as designed.

The trust boundary had shifted from source code to the build cache. Most organizations were not watching there.

Publishing without stealing npm credentials

Modern package ecosystems increasingly rely on trusted publishing models built around OpenID Connect (OIDC). Instead of storing long-lived npm tokens, publishers authenticate builds through federated trust relationships between GitHub Actions and package registries. When a trusted workflow runs, a trusted package can be published.

The attacker bypassed that model by extracting GitHub Actions OIDC tokens directly from runner memory. With those tokens in hand, they could publish packages authenticated through TanStack's own trusted publisher relationship. No npm token theft was required. No workflow modifications were required.

The result: 84 malicious versions published across 42 @tanstack/* packages. All carried valid Level 3 SLSA provenance attestations.

The packages were malicious. The trust signals were legitimate.

Similar trust failures appeared elsewhere in 2026. The JDownloader compromise abused trusted distribution infrastructure, while the Daemon Tools campaign abused valid developer signatures.

One stolen credential became the next breach

Among the credentials harvested during the TanStack compromise was a GitHub token belonging to an Nx developer. That credential provided contributor-level access to the nrwl/nx repository.

They did not need administrator privileges or a direct compromise of GitHub itself. They only needed enough authority to publish a trusted update.

According to public reporting, Nx's publishing workflow lacked a two-person approval requirement. A single compromised credential was sufficient to push a release to approximately 2.2 million installed extension users.  

ThreatLocker identified a connection  between the Nx Console compromise and the @antv campaign through a shared artifact: both created the same Python C2 backdoor at ~/.local/share/kitty/cat.py, providing additional evidence that the incidents were linked.

The orphan commit technique

Most repository monitoring focuses on branches. The attacker deliberately avoided them.

Instead of modifying an existing branch, they pushed an orphan commit (a commit with no parent and no connection to normal repository history). Many repository monitoring workflows focused on branches and pull requests would never see it.

The commit replaced the repository contents with only two files: package.json and an obfuscated index.js. The extension then referenced that orphan commit through a hardcoded SHA pointing at the official Nx repository.

When the extension loaded, npx resolved the package, installed the Bun runtime, and executed the payload automatically. No exploit occurred, and the update mechanism behaved exactly as designed. The attacker simply provided something malicious to trust.

The exposure window was enough

At 12:30 UTC on May 18, 2026, the attacker used stolen marketplace credentials to publish Nx Console version 18.95.0. The malicious addition consisted of just 2,777 bytes hidden inside a minified main.js file.

When developers opened a workspace, the extension downloaded and executed the full payload, targeting GitHub and npm credentials, AWS keys, GCP credentials, Docker config, and SSH private keys. It also harvested .env files, Vault tokens, Kubernetes service accounts, 1Password vaults, and Anthropic Claude Code configurations. It exfiltrated data through HTTPS, GitHub APIs, and DNS tunneling simultaneously. On macOS systems, it deployed a persistent Python backdoor that used GitHub Search as a dead-drop command-and-control mechanism.

Visual Studio Marketplace removed the version at 12:48 UTC. OpenVSX removed it at 13:09 UTC, roughly 39 minutes after publication, with no equivalent publisher-notification system to accelerate the takedown.

The number that doesn't add up

Marketplace telemetry reported only 28 downloads through the VS Code Marketplace and 41 through OpenVSX. Nx's own telemetry told a different story of approximately 6,000 extension activations during the same period.

The discrepancy exposes another trust assumption. Many software delivery mechanisms no longer operate through explicit downloads. Extensions update automatically. Package managers refresh dependencies automatically. Developers frequently consume new versions without taking any deliberate action. The attack surface is not merely the package; it is the trust relationship that delivers it.

One of those 6,000 activations occurred on a GitHub employee workstation. That single activation ultimately led to the compromise of approximately 3,800 internal GitHub repositories.

The capability the attacker didn't use

Researchers found that the payload included full Sigstore integration, including support for Fulcio certificate issuance and SLSA provenance generation.

With stolen OIDC credentials already in hand, the attacker possessed the technical capability to publish downstream malicious packages carrying valid cryptographic provenance attestations. They did not use that capability, but it existed. That changes the conversation around software provenance.

For years, the industry has responded to supply chain risk by layering stronger trust signals: package signing, developer signatures, provenance attestations, and reproducible builds. Mini Shai-Hulud demonstrated that if attackers inherit legitimate trust relationships, those signals remain valid. The trust model itself becomes the attack surface.

The blast radius kept growing

The GitHub breach was not the only downstream casualty. Grafana Labs disclosed that it had traced a separate compromise back to the same TanStack root cause. According to Grafana's public reporting, TeamPCP demanded a ransom on May 16 in exchange for not releasing stolen source code. Grafana declined and notified federal law enforcement.

StepSecurity separately linked the compromise of Microsoft's durabletask Python SDK to the broader campaign. The full list of affected organizations includes GitHub, Grafana Labs, Mistral AI, UiPath, Guardrails AI, OpenSearch, and others.

Following the GitHub breach, TeamPCP announced an auction of allegedly stolen GitHub source code on the Breached forum, listing a minimum bid of $50,000 and stating that members of Lapsus$ were authorized to broker the sale.

A compromise that began with a poisoned CI/CD cache entry ended with source code auctions, extortion demands, and breaches across GitHub and Grafana Labs, and downstream compromise of Microsoft-associated software. The worm didn't stop when the malicious extension was pulled. It stopped when the credentials it had already stolen were rotated.

The pattern, not the spike

The Trivy and LiteLLM compromise in February 2026 demonstrated the same emerging pattern: CI privilege escalation, credential theft, cross-ecosystem propagation, and a ransomware partnership for monetization. The campaign didn't stop there. The same playbook hit Checkmarx KICS and the Bitwarden CLI npm package in subsequent waves.

The Axios compromise abused trusted npm publishing. The JDownloader attack abused trusted download infrastructure. The Daemon Tools campaign abused valid developer signatures.

TanStack and Nx moved another layer higher, targeting CI/CD workflows, provenance systems, and trusted publishing relationships.  

Together, these campaigns represent a systematic progression through every layer of assumed trust: the package, the distribution channel, the developer signature, and finally the provenance attestation itself.

The lesson is not that package signing failed. It is not that provenance failed. It is not that software updates should stop. Those controls still matter. But they are no longer sufficient on their own when attackers can operate entirely inside legitimate credentialed workflows.  

The trust model itself has become part of the attack surface.

Start your path to stronger defenses

Start your trial

Try ThreatLocker free for 30 days and experience full Zero Trust protection in your own environment.

Book a demo

Schedule a customized demo and explore how ThreatLocker aligns with your security goals.

Ask an expert

Just starting to explore our platform? Find out what ThreatLocker is, how it works, and how it’s different.