A security tool to detect compromised npm packages from the Shai-Hulud supply chain attacks (original September 2025 and Shai-Hulud 2.0 November 2025). Scans both package.json and package-lock.json files to detect exact installed versions. Available in both Python and Node.js implementations with centralized YAML configuration for easy maintenance.
Latest Update: November 24, 2025 - 738+ compromised packages tracked with 1,291 unique package@version combinations. Now detects both original Shai-Hulud and Shai-Hulud 2.0 attack variants.
Shai-Hulud is a self-replicating worm that began compromising npm packages on September 14-15, 2025, representing the first successful self-propagating attack in the npm ecosystem and one of the most severe JavaScript supply-chain attacks observed to date. Named after the giant sandworms from Frank Herbert's Dune series, this malware has evolved into multiple variants.
The original attack infected 200+ npm packages (as tracked in this tool) with multiple versions affected per package.
A new variant emerged in November 2025 with significant changes:
- 738+ compromised packages with 1,291 unique package@version combinations
- 25,000+ affected repositories across ~350 unique users
- New execution phase: Uses
preinstallscripts (not justpostinstall) - New payload files:
setup_bun.jsandbun_environment.js(in addition tobundle.js) - Enhanced persistence: Creates self-hosted runners named 'SHA1HULUD' and new GitHub workflow patterns
- Multi-cloud targeting: AWS, Azure, and GCP credential harvesting
- Docker privilege escalation: Attempts to gain root access via privileged containers
- Packages uploaded between November 21-23, 2025
Reference: Wiz Research - Shai-Hulud 2.0 Blog Post
Updated affected package list and detection capabilities:
- 996+ compromised packages with 1,647 unique package@version combinations
Patient Zero: The attack started with the rxnt-authentication package published on September 14, 2025, at 17:58:50 UTC by the compromised "techsupportrxnt" npm account.
Attack Chain (Original Shai-Hulud):
- Installation: Malicious package runs
postinstallscript executingbundle.js(3MB+ JavaScript payload) - Credential Harvesting: Uses TruffleHog to scan for GitHub/npm tokens, AWS/GCP/Azure credentials, environment variables, and IMDS-exposed cloud keys
- Data Exfiltration: Creates public "Shai-Hulud" repository under victim's GitHub account with stolen secrets in
data.json(double base64-encoded) - Persistence: Injects malicious GitHub Actions workflow (
.github/workflows/shai-hulud-workflow.yml) that exfiltrates repository secrets towebhook[.]site - Repository Migration: Forces private organizational repositories to become public personal repositories with "-migration" suffix and "Shai-Hulud Migration" description
- Worm Propagation: Uses stolen npm tokens to inject malware into other packages maintained by the victim, incrementing version numbers and adding
postinstallhooks
Attack Chain (Shai-Hulud 2.0 - November 2025):
- Installation: Malicious package runs
preinstallscript executingsetup_bun.jsorbun_environment.js(new payload files) - Data File Creation: Creates
cloud.json,contents.json,environment.json, andtruffleSecrets.jsonfiles - Credential Harvesting: Multi-cloud targeting (AWS, Azure, GCP) using official SDKs, scraping credentials from config files, environment variables, and IMDS
- Self-Hosted Runner Registration: Registers infected machine as self-hosted runner named 'SHA1HULUD'
- GitHub Workflow Injection:
- Creates
.github/workflows/discussion.yamlwith self-hosted runner for backdoor access - Creates
.github/workflows/formatter_*.ymlfor secret exfiltration (then deletes workflow to hide activity)
- Creates
- Docker Privilege Escalation: Attempts to gain root access via
docker run --rm --privileged -v /:/host - Cloud Secret Dumping: Uses authenticated sessions to dump secrets from AWS Secrets Manager, Google Secret Manager, and Azure Key Vault
- Repository Creation: Creates repositories with "Shai-Hulud" in description for exfiltration
- Development Credentials: GitHub PATs (
ghp_*,gho_*), npm authentication tokens - Cloud Credentials: AWS, GCP, Azure access keys and tokens
- API Keys: Atlassian, Datadog, and other service credentials
- System Information: Environment variables, host details, user accounts
- Source Code: Private repositories made public or cloned
Original Shai-Hulud (September 2025):
- 200+ packages compromised in this tracking database (including popular packages like
@ctrl/tinycolor,ngx-bootstrap) - Multiple GitHub accounts compromised (exact count varies by reporting source)
- Public repositories created with "Shai-Hulud Migration" label
- Developers potentially affected through package dependencies
Shai-Hulud 2.0 (November 2025):
- 738+ compromised packages with 1,291 unique package@version combinations
- 25,000+ affected repositories created across ~350 unique users
- 1,000+ new repositories added every 30 minutes during initial campaign hours
- Affects packages from major ecosystems: Zapier, ENS Domains, PostHog, Postman, AsyncAPI, and more
- Multi-cloud credential theft (AWS, Azure, GCP)
- Docker privilege escalation attempts
Verified Credential Theft (from ~20,000 analyzed repos):
- 775 compromised GitHub access tokens
- 373 AWS credentials exposed
- 300 GCP credentials exposed
- 115 Azure credentials exposed
CRITICAL: Wiz Research has confirmed cross-victim exfiltration is occurring. This means:
- One victim's stolen secrets may be published to repositories owned by a different, unrelated victim
- If you find suspicious data in your GitHub repositories, it may belong to another compromised user
- Your data may have been exfiltrated to repositories you don't own
- This complicates attribution and incident response
Investigation Implication: When reviewing exfiltrated data in your repositories, verify whether the data actually belongs to your organization or another victim.
This attack is directly linked to the August 2025 s1ngularity/Nx compromise, where initial GitHub token theft enabled the broader supply chain attack. Many initial Shai-Hulud victims were known victims of the s1ngularity attack. Security researchers also note the integration of AI-generated content within the campaign, with moderate confidence that an LLM was used to generate the malicious bash script.
Original Shai-Hulud Campaign:
- August 26, 2025: s1ngularity/Nx compromise occurs (precursor attack)
- September 14, 2025 17:58 UTC: First malicious package
rxnt-authenticationpublished ("Patient Zero") - September 15, 2025: Attack detected and reported by security researchers
- September 15-16, 2025: Worm spreads rapidly across npm ecosystem
- September 16, 2025: Over 180 packages confirmed compromised
- September 17, 2025: Ongoing monitoring and cleanup efforts
- September 18, 2025: v1.2.0 release with 200 packages tracked and enhanced prevention tools
Shai-Hulud 2.0 Campaign:
- November 21-23, 2025: Malicious packages uploaded to npm registry
- November 24, 2025: Attack detected and reported by Wiz Research and Aikido
- November 24, 2025: v2.0.0 release with 738+ packages tracked and Shai-Hulud 2.0 detection capabilities
- Ongoing: GitHub continues removing attacker-created repositories; attacker continues creating new repositories
- Python scanner: Requires
PyYAML(pip install pyyaml) - Node.js scanner: Requires
js-yaml(npm install js-yaml)
# Make executable
chmod +x shai_hulud_scanner.py
# Scan single package.json
python3 shai_hulud_scanner.py ./package.json
# Scan package-lock.json for exact versions
python3 shai_hulud_scanner.py ./package-lock.json
# Scan entire project directory
python3 shai_hulud_scanner.py ./my-project
# Scan current directory
python3 shai_hulud_scanner.py .# Install dependencies first
npm install
# Make executable
chmod +x shai_hulud_scanner.js
# Scan single package.json
node shai_hulud_scanner.js ./package.json
# Scan package-lock.json for exact versions
node shai_hulud_scanner.js ./package-lock.json
# Scan entire project directory
node shai_hulud_scanner.js ./my-project
# Scan current directory
node shai_hulud_scanner.js .β Exact Match Detection: Identifies packages with exact version matches to known compromised versions
π Dual File Support: Scans both package.json (declared dependencies) and package-lock.json (exact installed versions)
π¦ Comprehensive Coverage: package-lock.json scanning includes nested dependencies and transitive packages
π Recursive Scanning: Automatically scans all subdirectories while skipping node_modules
π Detailed Reporting: Shows package names, versions, dependency sections, and affected versions
π IOC Detection: Identifies Indicators of Compromise for both original Shai-Hulud and Shai-Hulud 2.0:
- Original Shai-Hulud:
"postinstall": "node bundle.js"hooks,bundle.jsfiles,shai-hulud-workflow.yml - Shai-Hulud 2.0:
"preinstall"hooks,setup_bun.js,bun_environment.js,discussion.yaml,formatter_*.ymlworkflows - Common: References to
webhook.siteexfiltration endpoints, SHA1HULUD runner patterns, Docker privilege escalation
π¨ CRITICAL: Found 2 CONFIRMED compromised packages:
β’ @ctrl/deluge v7.2.2 in dependencies
Affected versions: 7.2.2, 7.2.1
β’ ngx-bootstrap v19.0.3 in devDependencies
Affected versions: 18.1.4, 19.0.3, 20.0.4, 20.0.5, 20.0.6, 19.0.4, 20.0.3
β οΈ WARNING: Found 1 packages with different versions:
β’ @ctrl/deluge v7.2.0 in dependencies
Known affected versions: 7.2.2, 7.2.1
β
No affected packages found
- Stop all development work on affected projects
- Remove compromised packages:
npm uninstall <package-name> - Clear npm cache:
npm cache clean --force - Delete node_modules:
rm -rf node_modules
- GitHub Personal Access Tokens
- npm Authentication Tokens
- SSH Keys
- API Keys (AWS, Atlassian, Datadog, etc.)
- Check GitHub for public repos named "Shai-Hulud" or with "Shai-Hulud" in description
- Look for repos with "-migration" suffix (original Shai-Hulud)
- Review GitHub audit logs for unauthorized repository creation
- Check for branches named shai-hulud
- Scan for IOCs (Indicators of Compromise):
- Original Shai-Hulud:
- Search for
"postinstall": "node bundle.js"in package.json files - Look for
bundle.jsfiles (3MB+ in size, contains malicious payload) - Examine
.github/workflows/shai-hulud-workflow.ymlfiles
- Search for
- Shai-Hulud 2.0:
- Search for
"preinstall"hooks in package.json files - Look for
setup_bun.jsandbun_environment.jspayload files - Check for data files:
cloud.json,contents.json,environment.json,truffleSecrets.json - Examine
.github/workflows/discussion.yaml(with self-hosted runner) - Examine
.github/workflows/formatter_*.ymlfiles - Check for 'SHA1HULUD' runner name in workflows
- Look for Docker privilege escalation commands (
docker run --rm --privileged -v /:/host)
- Search for
- Common:
- Check for
webhook.sitereferences in code or network logs - Review self-hosted runner registrations
- Check cloud provider credentials and secret manager access
- Check for
- Original Shai-Hulud:
Package data is centralized in affected_packages.yaml. To add new compromised packages:
- Edit
affected_packages.yaml - Add entries in the format:
- name: "package-name" versions: ["1.0.0", "1.0.1"]
- Both Python and JavaScript scanners will automatically use the updated data
This centralized approach eliminates the need to update multiple files when new threats are discovered.
# Create central scanning script
curl -O https://your-domain.com/shai_hulud_scanner.py
chmod +x shai_hulud_scanner.py
# Mass scan multiple projects
for dir in /projects/*/; do
echo "Scanning $dir"
python3 shai_hulud_scanner.py "$dir"
done# GitHub Actions example
- name: Scan for Shai-Hulud packages
run: |
curl -O https://your-domain.com/shai_hulud_scanner.js
npm install js-yaml
node shai_hulud_scanner.js .
if [ $? -ne 0 ]; then
echo "SECURITY ALERT: Compromised packages detected!"
exit 1
fi# Add to security toolkit
cp shai_hulud_scanner.py /usr/local/bin/
cp shai_hulud_scanner.js /usr/local/bin/
cp affected_packages.yaml /usr/local/bin/
# Create alias for easy access
echo 'alias scan-shai="python3 /usr/local/bin/shai_hulud_scanner.py"' >> ~/.bashrc- Target Platforms: Linux, macOS, and Windows (Shai-Hulud 2.0 adds Windows support)
- Payload Size: 3MB+ minified JavaScript bundle (original), new payloads in Shai-Hulud 2.0
- Self-Propagation: First successful self-replicating worm in npm ecosystem
- Execution Phases: Original uses
postinstall, Shai-Hulud 2.0 usespreinstall(increases exposure in build environments) - Dependencies: Python requires PyYAML, Node.js requires js-yaml
- Safe: Read-only operations, no modifications to your files
- Fast: Optimized for quick scanning of large codebases
- Accurate: Based on official IoC lists from security researchers (Wiz Research, Aikido)
- AI-Generated Components: Security researchers assess with moderate confidence that an LLM was used to generate parts of the malicious bash script
- Persistence Mechanisms:
- Original: GitHub Actions workflows, malicious branches, and repository migrations
- Shai-Hulud 2.0: Self-hosted runners, discussion-based workflows, formatter workflows
- Cloud Integration:
- Original: Targets AWS and GCP environments using SDK libraries and IMDS endpoints
- Shai-Hulud 2.0: Multi-cloud targeting (AWS, Azure, GCP) with official SDKs, secret manager dumping
Original Shai-Hulud (September 2025):
- Malicious postinstall hook:
"postinstall": "node bundle.js"in package.json - Payload file:
bundle.js(typically 3MB+ minified JavaScript) - Exfiltration endpoint: References to
webhook.sitedomains - GitHub workflow:
.github/workflows/shai-hulud-workflow.ymlfor persistence - Repository naming: Repos with "Shai-Hulud" or "-migration" suffixes
- Branch indicators: Branches named
shai-huludcontaining malicious commits
Shai-Hulud 2.0 (November 2025):
- Malicious preinstall hook:
"preinstall": "node setup_bun.js"or"preinstall": "node bun_environment.js"in package.json - New payload files:
setup_bun.js,bun_environment.js(in addition tobundle.js) - Data files:
cloud.json,contents.json,environment.json,truffleSecrets.json - GitHub workflows:
.github/workflows/discussion.yaml(withruns-on: self-hostedandRUNNER_TRACKING_ID: 0).github/workflows/formatter_*.yml(pattern matching, used for secret exfiltration)
- Self-hosted runner: Runner named 'SHA1HULUD' registered on infected machines
- Docker privilege escalation: Commands like
docker run --rm --privileged -v /:/host - Repository descriptions: Repos with "Shai-Hulud" in description
- Multi-cloud targeting: AWS Secrets Manager, Google Secret Manager, Azure Key Vault access attempts
- Exfiltration endpoint: References to
webhook.sitedomains (same as original)
Common to Both Variants:
- Exfiltration endpoint: References to
webhook.sitedomains - Repository naming: Repos with "Shai-Hulud" in name or description
- Release Notes v1.2.0 - Complete changelog and new features
- Security Assessment - Comprehensive security analysis
- Prevention Guide - 490+ lines of integration instructions
- GitHub Actions Workflow - Automated CI/CD protection
- Preinstall hook detection: Detects
preinstallscripts (Shai-Hulud 2.0 execution phase) - New payload file detection: Scans for
setup_bun.jsandbun_environment.js - Data file detection: Identifies
cloud.json,contents.json,environment.json,truffleSecrets.json - GitHub workflow scanning: Detects
discussion.yamlandformatter_*.ymlworkflow patterns - Self-hosted runner detection: Identifies 'SHA1HULUD' runner registrations
- Docker privilege escalation detection: Scans for privileged container execution patterns
- Backward compatibility: Continues to detect original Shai-Hulud (September 2025) indicators
- 738+ compromised packages tracked (up from 200)
- 1,291 unique package@version combinations in database
- 25,000+ affected repositories identified
- ~350 unique users compromised
- Multi-format configs: JSON, YAML, CSV for different use cases
- GitHub Actions integration: Automated CI/CD blocking workflow
- Standalone blocker script:
prevention/block-shai-hulud.sh - Package sync tools: Automated threat intelligence updates
- IoC scanning for both original and Shai-Hulud 2.0 variants
- Severity categorization (Critical/High/Medium) with variant identification
- Enhanced threat intelligence with download counts and attack vectors
- Multi-cloud credential detection: AWS, Azure, GCP targeting patterns
For issues or questions:
- Security Team: [email protected]
- Development: [email protected]