Shai-Hulud and the risks of external dependencies

silcoon1 pts0 comments

Shai-Hulud and the risks of external dependencies Shai-Hulud and the risks of external dependencies<br>July 29, 2026

Shai-Hulud is a malware created by TeamPCP that targeted npm to spread across the Node supply chain. Its name refers the giant sandworms that populate the desert planet Arrakis in the sci-fi series Dune by Frank Herbert. If you’ve seen the movie, they are the creatures that get attracted by vibrations in the sand. The reference is explained clearly in the README:

A sandworm surfaces in the desert. It takes everything.

An estimate of the damage caused by Shai-Hulud through multiple campaigns includes 500 compromised software packages, hundreds of organisations breached, 300 GB of data stolen, and roughly 500,000 credentials exfiltrated to the attackers.

TeamPCP decided to release its source code on 11 May. I’m not a security researcher, but I’ve always been interested in how criminals exploit complex systems and bypass their security. So I forked the repo to see what intrusion techniques or exploits were used. I also took some notes to turn into a code review article later. But the more I read through the code, the more I felt somehow disappointed.

Reading Shai-Hulud code

I didn’t find any advanced exploit system, but rather a collection of simple tricks to steal credentials, obfuscate strings, and inject malicious code into npm packages. At times, the code was inconsistent, contained a few bugs, and appeared incomplete.

So how did a codebase like this become so harmful? Because it exploited the Achilles’ heel in modern development. The trust we place in other people’s code and how much we love dependencies.

How it works

The codebase I’ve analysed is Mini Shai-Hulud. There have been three versions of the worm, with what appears to be an increasing number of features from one version to another.

The project uses Bun for its build process, and the README includes it’s usage instructions.

Drop this into a CI pipeline. The sandworm crawls through your infrastructure, feeding on credentials from every provider it can reach, then exfiltrates through encrypted channels. If it finds npm tokens or OIDC access, it backdoors packages and publishes them. Downstream consumers install the infection. The worm grows.

Preflight and infection

Once the worm starts running, it first performs some checks, becomes a daemon if it is not running inside a CI environment, and compromises the OpenSearch repository if the infected system has access to it, using an OIDC attack.

The worm uses two separate methods to poison a package. The OIDC attack involves injecting a new optional dependency, @opensearch/setup, pinned to a specific commit in another package, opensearch-project/opensearch-js, which has presumably already been compromised. The other method adds a preinstall script containing a malicious setup file that downloads Bun and then runs the worm.

Credentials harvesting

Because the code has access to the host system, it simply reads configuration files and grabs tokens from processes and apps.

In short, it steals almost everything a developer can access: AWS credentials and secrets, SSH keys, cloud configuration files, cryptocurrency wallets, web chat data, VPN configurations, Kubernetes credentials, HashiCorp Vault secrets, GitHub tokens, Actions secrets, Claude settings, .npmrc, .netrc, Bash, Zsh, and Python shell histories, and MySQL, PostgreSQL, and Redis credentials.

Data exfiltration

Once the malware has collected the credentials, it needs to send them to the attackers. The data is first compressed and encrypted using a public key embedded in the payload.

The malware then tries to contact the typosquatted domain git-tanstack.com. If that fails, it searches GitHub for other compromised repositories through signed commit messages and retrieves a fallback domain from one of them. If even that fails, it creates multiple GitHub repositories with names made from random adjectives and nouns drawn from Dune. The stolen data is later uploaded to these repositories through a GitHub Actions workflow.

A quick GitHub search showed thousands of repositories containing encrypted JSON data. A significant number of these repositories were created only a few days after the release of Mini Shai-Hulud’s source code, making me wonder whether someone had used it in a new campaign.

Embedded payload

The payload contains a few scripts that download and install Bun on the system before executing the malware. Two of the files are configuration files for VS Code and Claude, designed to be injected into repositories so that whenever a user opens the project in the editor or with a coding agent, the worm compromises the machine and replicates itself. There is also a GitHub Actions workflow designed to collect repository secrets and upload them as artifacts. Then there are two public keys: one used to encrypt data and another to verify commit signatures. Finally, there is a Python script that dumps the memory of a...

code shai hulud credentials data through

Related Articles