Shai-Hulud V2: Anatomy of a Self-Propagating npm Worm
- Patrick Duggan
- Dec 4, 2025
- 3 min read
--- 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
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]




Comments