Shai-Hulud V2: Anatomy of a Self-Propagating npm Worm
- Patrick Duggan
- Dec 4, 2025
- 4 min read
Updated: Aug 11
--- title: "Shai-Hulud V2: Anatomy of a Self-Propagating npm Worm" slug: shai-hulud-v2-npm-supply-chain-worm date: 2025-12-04 author: Patrick Duggan tags: [supply-chain, npm, worm, shai-hulud, threat-intelligence, pattern-38] category: Threat Intelligence featured: true ---
The Hook
> *"The spice must flow."*
Except in this case, the spice is malware, and it's flowing through npm's preinstall hooks into 700+ packages and 27,000+ GitHub repositories.
We found a self-propagating worm in the wild. It's named after the sandworms from Dune. And it's eating the JavaScript ecosystem from the inside out.
TL;DR
• What: Self-propagating npm supply chain worm ("Shai-Hulud V2")
• Scale: 700+ compromised npm packages, 27,000+ affected GitHub repos
• Vector: npm `preinstall` hooks → TruffleHog credential harvesting → GitHub Actions injection
• Named: After the sandworms from Frank Herbert's Dune
• Status: Active in the wild as of December 2025
The Attack Chain
Phase 1: Initial Infection
npm install <compromised-package>
↓
preinstall hook executes setup_bun.js
↓
Creates ~/.dev-env/ persistence directory
The worm disguises itself as Bun runtime setup. Clever. Developers see "bun" and assume it's legitimate tooling.
Phase 2: Credential Harvesting
~/.dev-env/ established
↓
TruffleHog scans local filesystem
↓
Results cached in ~/.truffler-cache/
↓
AWS keys, GitHub tokens, API secrets extracted
They're using TruffleHog - a legitimate security tool - for malicious purposes. Ironic.
Phase 3: Lateral Movement
Credentials harvested
↓
Identifies npm packages victim maintains
↓
Injects worm into victim's packages
↓
New victims install, cycle repeats
This is the "worm" behavior - true self-propagation through the developer's own packages.
Phase 4: CI/CD Compromise
GitHub access obtained
↓
Injects .github/workflows/discussion.yaml
↓
Workflow triggers on GitHub Discussions
↓
Executes on GitHub Actions runners
The `discussion.yaml` trigger is novel. Most security scanning focuses on `push` and `pull_request` triggers. Discussion-triggered workflows fly under the radar.
Indicators of Compromise (IOCs)
File Hashes (SHA256)
| Hash | Description | |------|-------------| | `a3894003ad1d293ba96d77881ccd2071446dc3f65f434669b49b3da92421901a` | Primary payload | | `62ee164b9b306250c1172583f138c9614139264f889fa99614903c12755468d0` | Variant #2 | | `9d59fd0bcc14b671079824c704575f201b74276238dc07a9c12a93a84195648a` | Variant #3 |
Filesystem Indicators
| Path | Purpose | |------|---------| | `~/.dev-env/` | Persistence directory | | `~/.truffler-cache/` | Credential cache | | `setup_bun.js` | Initial loader | | `bun_environment.js` | Secondary payload | | `.github/workflows/discussion.yaml` | CI/CD injection |
Package.json Red Flags
{
"scripts": {
"preinstall": "node setup_bun.js"
}
}
Any `preinstall` script referencing "bun" or "setup" should be investigated.
MITRE ATT&CK Mapping
| Technique | ID | Description | |-----------|----|----| | Supply Chain Compromise | T1195.001 | npm package injection | | Boot/Logon Autostart | T1547.001 | ~/.dev-env persistence | | Credentials from Files | T1552.001 | TruffleHog scanning | | Keychain Access | T1555.001 | macOS credential theft |
• Initial Access
• Persistence
• Credential Access
• Lateral Movement
Detection
Check Your System Now
# Check for persistence directories
ls -la ~/.dev-env/ 2>/dev/null && echo "⚠️ INFECTED"
ls -la ~/.truffler-cache/ 2>/dev/null && echo "⚠️ INFECTED"npm Audit Gaps
Standard `npm audit` won't catch this. The malicious code executes during install, before audit runs. You need:
1. Pre-install hook scanning 2. Behavioral analysis of postinstall scripts 3. Filesystem monitoring for ~/.dev-env creation
Attribution
Threat Actor: Unknown ("Shai-Hulud Operators")
• Cybersecurity background (sandworms "control the spice")
• Deliberate misdirection
• Just a sci-fi nerd
Microsoft pulls this feed daily. AT&T pulls this feed daily. Starlink pulls this feed daily. Get the DugganUSA STIX feed — $9/mo →
Resources: The scale (700+ packages, 27k+ repos) indicates organizational resources, not a solo actor.
• npm ecosystem deeply
• GitHub Actions trigger mechanisms
• How to weaponize legitimate tools (TruffleHog)
• Persistence techniques across platforms
Correlation: Pattern 38
We've been tracking Pattern 38 (GitHub issue comment supply chain attacks) for months. Shai-Hulud V2 represents a parallel evolution:
| Vector | Pattern 38 | Shai-Hulud V2 | |--------|-----------|---------------| | Entry point | GitHub issue comments | npm preinstall | | Payload | ZIP with malware | JavaScript worm | | Target | Developers seeking help | npm maintainers | | Persistence | Registry run keys | ~/.dev-env | | Credential theft | Browser | TruffleHog |
Same goal (compromise developers), different vectors. Possible coordination or shared TTP evolution.
What We're Doing
1. STIX Feed: Full IOC bundle available at `analytics.dugganusa.com/api/v1/stix-feed` 2. OTX Pulse: Published to AlienVault OTX for community defense 3. Detection Rules: Sigma rules for discussion.yaml and ~/.dev-env monitoring 4. GitHub Reports: Coordinating with GitHub Security on affected repos
Recommendations
For Developers
1. Audit preinstall hooks in all dependencies 2. Check for ~/.dev-env and ~/.truffler-cache directories 3. Review GitHub Actions workflows for unexpected discussion.yaml files 4. Rotate credentials if any IOCs found
For Organizations
1. Block preinstall scripts in CI/CD with `--ignore-scripts` 2. Monitor filesystem for ~/.dev-env creation 3. Review GitHub Actions trigger configurations 4. Subscribe to threat feeds (shameless plug: ours is free)
Resources
• STIX Bundle: `compliance/evidence/threat-intelligence/stix-bundles/shai-hulud-v2-npm-worm-2025-12.json`
• OTX Pulse: https://otx.alienvault.com/user/pduggusa
• DugganUSA STIX Feed: https://analytics.dugganusa.com/api/v1/stix-feed
*"He who controls the spice controls the universe." - Frank Herbert*
*He who controls npm preinstall hooks controls your credentials.* - DugganUSA, probably
Get Free IOCs
Subscribe to our threat intelligence feeds for free, machine-readable IOCs:
AlienVault OTX: https://otx.alienvault.com/user/pduggusa
STIX 2.1 Feed: https://analytics.dugganusa.com/api/v1/stix-feed
Questions? [email protected]
The cheapest, fastest, most accurate threat feed on the internet.
275+ enterprises pulling daily. 1M+ IOCs. 17.4M indexed documents. We beat Zscaler by 43 days on NrodeCodeRAT. Starter tier $9/mo — less than any competitor’s sales demo.
Was this useful? Thirty seconds, no cookies, no tracking, no third parties, your address hashed and never stored. If the box below does not load, the same question lives at https://analytics.dugganusa.com/nps.html?post=shai-hulud-v2-anatomy-of-a-self-propagating-npm-worm




Comments