top of page

Shai-Hulud V2: Anatomy of a Self-Propagating npm Worm

  • Writer: Patrick Duggan
    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




Tags: #supply-chain #npm #worm #shai-hulud #threat-intelligence #pattern-38



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


Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page