Supply-chain attacks don't usually announce themselves. There's no dramatic system crash or flashing red warning. Instead, they quietly slip in through something every developer trusts by default: dependencies.
That's what makes Shai Hulud 2.0 dangerous. It is not just malware. It is a self-replicating npm worm built to spread through developer ecosystems and quietly compromise repositories, CI pipelines, and cloud credentials.
What is Shai Hulud 2.0?
Shai Hulud 2.0 (often tagged as Sha1-Hulud: The Second Coming) is the next step after the 2024-2025 worm. The first version centered on exfiltration. 2.0 is built for automation, scale, and persistence.
Its lifecycle follows a wormable pattern:
- Infects via a compromised npm package, often a patch-version update of a trusted library.
- Harvests GitHub tokens, npm credentials, and cloud keys (AWS, GCP, Azure) using embedded tools like TruffleHog.
- Backdoors every other npm package maintained by the victim by republishing them with the worm attached.
- Establishes persistence by setting up a malicious GitHub Actions runner.
Why 2.0 is different
Unlike a one-shot script, Shai Hulud 2.0 uses a multi-stage flow aimed at getting around typical Node-side monitoring. Three things stand out.
The Bun loader. The initial dropper (setup_bun.js) detects or installs the Bun runtime. Bun is fast and less watched than Node in many shops, so the worm uses it to run its core payload (bun_environment.js) with less noise.
Destructive wiper logic. The worm ships a dead-man switch. If exfil fails or it cannot reach its C2 server, it may try to wipe the user's home directory. That bricks the local environment and makes forensics harder.
Credential validation. It does not only collect secrets. It validates them against the GitHub API right away to rank the infected host before deciding what to do next.
Those design choices are easier to take seriously when you see how far the campaign spread after vendors started publishing numbers.
Real-world impact: November 2025
Wiz and Aikido both analyzed the November 2025 wave. Wiz Threat Research put the broader campaign on the order of hundreds of trojanized npm packages and 25,000+ affected GitHub repositories, with stolen material exfiltrated to GitHub. Affected scopes discussed across those reports include Zapier, ENS Domains, and AsyncAPI; Aikido also publishes version-level indicators you can cross-check against your lockfiles.
Vendor post-mortems: Postman confirmed malicious versions across 17 public @postman/* packages on November 24, 2025, and later published a root cause analysis of how compromised dependencies in CI led to abuse of an npm publish token; PostHog published a post-mortem the same day for posthog-js, posthog-node, and related packages, including how their publish credentials were reached through an earlier GitHub-side chain, not only the worm payload in isolation.
Known indicators of compromise
If you are auditing your environment, look for these red flags.
Repository-level indicators
- Signature: GitHub repository descriptions containing
"Sha1-Hulud: The Second Coming." - Self-hosted runners: Any GitHub Actions runner named
SHA1Hulud - Workflow injections: New or modified files in
.github/workflows/nameddiscussion.yaml,shai-hulud.yaml, orformatter_*.yml
File-level indicators
The worm stages stolen data in specific JSON files before exfiltration. Look for:
truffleSecrets.json/actionsSecrets.jsoncloud.json/environment.jsonsetup_bun.jsorbun_environment.js
Behavioral signals
- Unexpected
preinstallscripts: Check yourpackage-lock.jsonfor dependencies runningnode setup_bun.js - Automated publishes: npm accounts publishing new versions at unusual hours without a matching CI build log
Detecting Shai Hulud Compromise
Manual auditing of thousands of repositories and developer profiles is a losing battle. The Shai Hulud Detector is a small CLI that scans for Known indicators of compromise like Suspicious repository descriptions, or JSON files containing secrets, credentials or environment configuration.
What it can do
- Scan individual GitHub users
- Scan all members of a GitHub organization
- Dual detection methods: repository description patterns and suspicious file detection
- Concurrent scanning with configurable workers
- Color-coded output for easy identification (FLAG/OKAY/ERROR status)
- Detailed verbose mode
Quick Start
Install the detector directly from PyPI:
pip install shai-hulud-detector
export GITHUB_TOKEN=<your_token_here>
Audit your entire organization:
shai-hulud-detector scan --org <your-org-name> --workers 10
Scan specific high-risk maintainers:
shai-hulud-detector scan alice bob charlie --verboseThe CLI uses the GitHub API to list repositories and read the metadata and paths it needs. Read access to the org and repos you care about is enough. Prefer short-lived, narrowly scoped tokens over one broad personal access token.
What to do if you find a compromise
If the tool flags an infection, treat it as patient zero. Speed matters.
- Immediate isolation. Disconnect the infected machine from the network so C2 cannot trigger the home-directory wiper.
- Credential rotation. Revoke and rotate GitHub PATs, npm tokens, and cloud (AWS, GCP, Azure) access keys, not only the one you first suspect.
- Audit npm packages. If the infected user is a maintainer, check every package they can touch for unauthorized patch releases.
- Clean CI/CD. Delete unauthorized GitHub Actions runners and audit workflow files for injected steps.
After an incident (or in rotation): run
shai-hulud-detectoron a schedule you can keep, or as a one-off after a related scare. Source and additional detection ideas live on GitHub.Upstream hardening: Dependency cooldowns like pnpm's
minimumReleaseAge: 7dact as a security buffer, giving the community time to detect and flag potentially malicious package versions before they reach production environments.
The tool is open source under the MIT license, with the full source available on GitHub and distributed via PyPI. In npm-heavy environments, it can be integrated into incident response workflows as a quick first-pass scanner for detecting known compromise indicators across GitHub accounts.


