Protos AI Agent, under the supervision of Christabel Lum
A self-replicating malware campaign—dubbed Shai-Hulud—is compromising hundreds of npm packages and automatically spreading by stealing developer and CI/CD credentials, then republishing infected versions across all packages owned by newly compromised maintainers. Several well-known libraries and even packages published under CrowdStrike namespaces were briefly affected (CrowdStrike says Falcon/platform are not impacted). Analysis confirms the scope has grown significantly, with tallies now exceeding 500 packages and security agency alerts being issued.
Why it matters: Unlike prior one-off npm compromises, Shai-Hulud behaves as a worm. One developer’s environment or CI runner can turn into an amplification node that silently repackages every library they publish—propagating the compromise through software supply chains at ecosystem speed. The addition of techniques that publicly expose private source code has elevated the risk beyond credential theft. In response, both CISA and major platforms like GitHub have issued formal guidance and are accelerating security changes.
postinstall
script executes a large bundle.js
, harvests npm/GitHub/cloud tokens, plants a GitHub Actions workflow, exfiltrates secrets, and then republishes infected versions across the victim maintainer’s other packages. Techniques include creating pull requests from shai-hulud
branches and making private repositories public.Shai-Hulud turns the trust and automation of modern software delivery into a force multiplier. It piggybacks on routine npm install
flows, steals short- and long-lived credentials from developer laptops and build agents, persists via GitHub Actions, and re-publishes itself across every package a victim maintains. The result is an ecosystem-level incident: even teams far from the initial blast radius face risk if any transitive dependency crossed paths with the worm during the window of exposure. The threat now explicitly includes the public leaking of private intellectual property, raising the stakes for all affected organizations.
A trojanized package (e.g., @ctrl/tinycolor@4.1.1/4.1.2
) is installed. A postinstall
hook runs a large bundle.js
payload. The initial vector is widely believed to be a targeted phishing campaign against developers.
Payload invokes a secrets-scanner (TruffleHog), probes cloud metadata endpoints, and enumerates npm/GitHub/AWS/GCP/Azure tokens from env vars and local stores.
Shai-Hulud
under the victim's account and commits a data.json
file containing the stolen secrets.-migration
suffix and adding "Shai-Hulud Migration" to the description.Using stolen tokens, the malware rebuilds and republishes each package owned by the victim, injecting the worm.
shai-hulud
), uploads the malicious workflow, and creates a pull request to merge it into the default branch.
bundle.js
invoked via postinstall
.46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09
(variants exist)78e701f42b76ccde3f2678e548886860
, fbf3fe241abf21b1a732352a037edec0
/tmp/github-migration
as a working directory.Shai-Hulud
(created under a compromised user's account).shai-hulud
.github/workflows/shai-hulud-workflow.yml
https://webhook[.]site/bb8ca5f6-4175-45d2-b042-fc9ebb8170b7
secretsmanager.*.amazonaws.com
, secretmanager.googleapis.com
TruffleHog
execution with arguments like filesystem /.
.npm publish
commands with the --force
flag.Shai-Hulud
, repos with description “Shai-Hulud Migration”, or branches named shai-hulud
. Review Actions history for unusual steps or outbound webhooks.npm install
on suspect days; revoke/rotate immediately.node
/npm
processes executing from temp dirs or large bundle.js
artifacts.npm config set ignore-scripts true
in CI for emergency builds.postinstall
for third-party deps in CI except for a vetted allow-list.postinstall
for external deps in CI except for an allow-list; pin by SHA where possible..github/workflows/*
creation, alert on branch names like shai-hulud
and "Shai-Hulud Migration" strings, and monitor for private repos being made public.