A Bash tool that helps you spot known traces of the September 2025 and November 2025 npm supply-chain attacks—including the Shai-Hulud self-replicating worm, the chalk/debug crypto-theft incident, and the "Shai-Hulud: The Second Coming" fake Bun runtime attack. It cross-checks 979+ confirmed bad package versions across multiple campaigns and checks for the most relevant red flags in your project.
Covers multiple npm supply chain attacks from September 2025 and November 2025:
- Scope: 18+ packages with 2+ billion weekly downloads
- Attack: Cryptocurrency wallet address replacement in browsers
- Duration: ~2 hours before detection
- Packages: chalk, debug, ansi-styles, color-, supports-, and others
- Method: XMLHttpRequest hijacking to steal crypto transactions
- Scope: 517+ packages across multiple namespaces
- Attack: Credential harvesting and self-propagation
- Method: Uses Trufflehog to scan for secrets, publishes stolen data to GitHub
- Propagation: Self-replicates using stolen npm tokens
- Packages: @ctrl/, @crowdstrike/, @operato/*, and many others
- Scope: 300+ packages with millions of weekly downloads
- Attack: Fake Bun runtime installation with credential harvesting
- Method: Uses fake
setup_bun.jspreinstall hook to download and execute TruffleHog - Exfiltration: Creates GitHub Actions runners named "SHA1HULUD" and repositories with "Sha1-Hulud: The Second Coming" descriptions
- Packages: @zapier/, @posthog/, @asyncapi/, @postman/, @ensdomains/*, and many others
- Files:
setup_bun.js,bun_environment.js(10MB+ obfuscated payload),actionsSecrets.json(double Base64 encoded) - Workflow:
.github/workflows/formatter_*.ymlfiles using SHA1HULUD runners
# Clone the repository
git clone https://github.com/Cobenian/shai-hulud-detect
cd shai-hulud-detect
# Make the script executable
chmod +x shai-hulud-detector.sh
# Scan your project for Shai-Hulud indicators
./shai-hulud-detector.sh /path/to/your/project
# For comprehensive security scanning
./shai-hulud-detector.sh --paranoid /path/to/your/project
# Check exit code for CI/CD integration
./shai-hulud-detector.sh /path/to/your/project
echo "Exit code: $?" # 0=clean, 1=high-risk, 2=medium-riskCI/CD Integration: The script returns appropriate exit codes (0=clean, 1=high-risk, 2=medium-risk) for seamless integration into automated security pipelines.
You must have Deno installed and available on PATH to run the Deno version.
It will be run with the following permissions:
--allow-read: To read files in the target directory
# Clone the repository (required for compromised package list)
git clone https://github.com/username/shai-hulud-detector.git
cd shai-hulud-detector
# Make the script executable
chmod +x shai-hulud-detector.ts
# Scan your project for Shai-Hulud indicators
./shai-hulud-detector.ts /path/to/your/project
# For comprehensive security scanning
./shai-hulud-detector.ts --paranoid /path/to/your/project🚀 High-Performance Alternative: A TypeScript implementation (shai-hulud-detector.ts) is available that provides identical security coverage with dramatically improved performance.
- âś… Complete Feature Parity: Implements all detection logic from the bash version, automatically aligned with the latest CHANGELOG updates
- ⚡ 30x+ Faster Performance: Real-world testing shows the TypeScript version completes in minutes what the bash version takes hours to process
- đź”’ Zero Dependencies: Uses only Deno built-in APIs, no npm packages required
- 🎯 Enhanced Accuracy: Includes advanced lockfile-aware detection to reduce false positives
- 🔄 Parallel Processing: Leverages async/await and Promise.all() for concurrent file analysis
| Project Size | Bash Version | TypeScript Version | Speedup |
|---|---|---|---|
| Small Projects (< 1k files) | ~1.5 seconds | ~0.05 seconds | 32x faster |
| Small Project (20GB with node_modules) | 27 seconds | 2 seconds | 13.5x faster |
| Medium Project (Multi-Module pnpm) | 21m 48s | 30 seconds | 43x faster |
| Large Projects (80k+ files, 20GB+) | 17+ minutes | 47 seconds | >20x faster |
- Lockfile-Aware Detection: Automatically checks package-lock.json, yarn.lock, and pnpm-lock.yaml to distinguish between potential and actual threats
- Risk Stratification: Crypto patterns are categorized into HIGH/MEDIUM/LOW risk levels for better triage
- Graceful Cleanup: Async temporary file cleanup with signal handlers for interruption safety
- Deno runtime (single binary installation)
- Same permissions as bash version:
--allow-readfor file system access
The TypeScript implementation automatically stays current with bash version improvements by implementing the same detection algorithms and following the same CHANGELOG for feature updates.
- Malicious workflow files:
shai-hulud-workflow.ymlfiles in.github/workflows/(September 2025) andformatter_*.ymlfiles using SHA1HULUD runners (November 2025) - Known malicious file hashes: Files matching any of 7 SHA-256 hashes from different Shai-Hulud worm variants (V1-V7), sourced from Socket.dev's comprehensive attack analysis
- November 2025 Bun attack files:
setup_bun.js(fake Bun runtime installer) andbun_environment.js(10MB+ obfuscated credential harvesting payload) - Compromised package versions: Specific versions of 979+ packages from multiple attacks (September & November 2025)
- Suspicious postinstall hooks: Package.json files with postinstall scripts containing curl, wget, eval commands, or fake Bun installation (
"preinstall": "node setup_bun.js") - Trufflehog activity: Files containing trufflehog references, credential scanning patterns, or November 2025 enhanced patterns (automated TruffleHog download and execution)
- Shai-Hulud repositories: Git repositories named "Shai-Hulud" (used for data exfiltration) or with "Sha1-Hulud: The Second Coming" descriptions
- Secrets exfiltration files:
actionsSecrets.jsonfiles with double Base64 encoded credentials (November 2025) - SHA1HULUD GitHub Actions runners: GitHub Actions workflows using malicious runners for credential theft
- Suspicious content patterns: References to
webhook.siteand the malicious endpointbb8ca5f6-4175-45d2-b042-fc9ebb8170b7 - Suspicious git branches: Branches named "shai-hulud"
- Semver pattern matching: Packages that could become compromised during
npm updatedue to caret (^) or tilde (~) version patterns
- Namespace warnings: Packages from namespaces known to be affected (@ctrl, @crowdstrike, @art-ws, @ngx, @nativescript-community) but at safe versions
The script loads a list of the compromised packages from an external file (compromised-packages.txt) which contains:
- 979+ confirmed compromised package versions with exact version numbers (571+ from September 2025 + 300+ from November 2025)
- 18+ affected namespaces for broader detection of packages from compromised maintainer accounts
Important: The Shai-Hulud attack was self-replicating, meaning new compromised packages may still be discovered. The compromised packages list is stored in compromised-packages.txt for easy maintenance:
- Format:
package_name:version(one per line) - Comments: Lines starting with
#are ignored - Updates: The file can be updated as new compromised packages are discovered
- Fallback: If the file is missing, the script uses a core embedded list
Check these security advisories regularly for newly discovered compromised packages:
- StepSecurity Blog - Original comprehensive analysis
- Semgrep Security Advisory - Detailed technical analysis
- JFrog Security Research - Ongoing detection of new packages
- Wiz Security Blog - Attack analysis with package appendix
- Socket.dev Blog - CrowdStrike package analysis
- HelixGuard - Second Coming analysis
- Check the security advisories above for new compromised packages
- Add them to
compromised-packages.txtin the formatpackage_name:version - Test the script to ensure detection works
- Consider contributing updates back to this repository
Coverage Note: Multiple September and November 2025 attacks affected 979+ packages total. Our detection aims to provide comprehensive coverage across the Shai-Hulud worm (517+ packages), Chalk/Debug crypto theft (26+ packages), and "Shai-Hulud: The Second Coming" fake Bun runtime attack (300+ packages). Combined with namespace-based detection and enhanced attack pattern recognition, this provides excellent protection against these sophisticated supply chain compromises.
Core Mode (Default)
- Focuses specifically on Shai-Hulud attack indicators
- Recommended for most users checking for this specific threat
- Clean, focused output with minimal false positives
Paranoid Mode (--paranoid)
- Includes all core Shai-Hulud detection PLUS additional security checks
- Adds typosquatting detection and network exfiltration pattern analysis
- Important: Paranoid features are general security tools, not specific to Shai-Hulud
- May produce more false positives from legitimate code
- Useful for comprehensive security auditing
- macOS or Unix-like system
- Bash shell
- Standard Unix tools:
find,grep,shasum
- Sole run on standard deno runtime without additional dependencies / packages
- Use async / await to parallelize file operations
- Optimize for speed on large repositories
âś… No indicators of Shai-Hulud compromise detected.
Your system appears clean from this specific attack.
The script will show:
- 🚨 HIGH RISK: Definitive indicators of compromise
⚠️ MEDIUM RISK: Suspicious patterns requiring manual review- Summary: Count of issues found
- Immediate action required
- Update or remove compromised packages
- Review and remove malicious workflow files
- Scan for credential theft
- Consider full system audit
- Manual investigation needed
- Review flagged files for legitimacy
- Check if webhook.site usage is intentional
- Verify git branch purposes
The repository includes test cases to validate the script:
# Test on clean project (should show no issues)
./shai-hulud-detector.sh test-cases/clean-project
# Test on infected project (should show multiple issues)
./shai-hulud-detector.sh test-cases/infected-project
# Test November 2025 "Shai-Hulud: The Second Coming" attack (should show HIGH risk for all new patterns)
./shai-hulud-detector.sh test-cases/november-2025-attack
# Test on mixed project (should show medium risk issues)
./shai-hulud-detector.sh test-cases/mixed-project
# Test namespace warnings (should show LOW risk namespace warnings only)
./shai-hulud-detector.sh test-cases/namespace-warning
# Test semver matching (should show MEDIUM risk for packages that could match compromised versions)
./shai-hulud-detector.sh test-cases/semver-matching
# Test legitimate crypto libraries (should show MEDIUM risk only)
./shai-hulud-detector.sh test-cases/legitimate-crypto
# Test chalk/debug attack patterns (should show HIGH risk compromised packages + MEDIUM risk crypto patterns)
./shai-hulud-detector.sh test-cases/chalk-debug-attack
# Test common crypto libraries (should not trigger HIGH risk false positives)
./shai-hulud-detector.sh test-cases/common-crypto-libs
# Test legitimate XMLHttpRequest modifications (should show LOW risk only)
./shai-hulud-detector.sh test-cases/xmlhttp-legitimate
# Test malicious XMLHttpRequest with crypto patterns (should show HIGH risk crypto theft + MEDIUM risk XMLHttpRequest patterns)
./shai-hulud-detector.sh test-cases/xmlhttp-malicious
# Test lockfile false positive (should show no issues despite other package having compromised version)
./shai-hulud-detector.sh test-cases/lockfile-false-positive
# Test actual compromised package in lockfile (should show HIGH risk)
./shai-hulud-detector.sh test-cases/lockfile-compromised
# Test packages with safe lockfile versions (should show LOW risk with lockfile protection message)
./shai-hulud-detector.sh test-cases/lockfile-safe-versions
# Test mixed lockfile scenario (should show HIGH risk for compromised + LOW risk for safe)
./shai-hulud-detector.sh test-cases/lockfile-comprehensive-test
# Test packages without lockfile (should show MEDIUM risk for potential update risks)
./shai-hulud-detector.sh test-cases/no-lockfile-test
# Test typosquatting detection with paranoid mode (should show MEDIUM risk typosquatting warnings)
./shai-hulud-detector.sh --paranoid test-cases/typosquatting-project
# Test network exfiltration detection with paranoid mode (should show HIGH risk credential harvesting + MEDIUM risk network patterns)
./shai-hulud-detector.sh --paranoid test-cases/network-exfiltration-project
# Test clean project with paranoid mode (should show no issues - verifies no false positives)
./shai-hulud-detector.sh --paranoid test-cases/clean-project
# Test semver wildcard parsing (should correctly handle 4.x, 1.2.x patterns without errors)
./shai-hulud-detector.sh test-cases/semver-wildcards
# Test discussion workflow detection (should show CRITICAL risk for malicious discussion-triggered workflows)
./shai-hulud-detector.sh test-cases/discussion-workflows
# Test GitHub Actions runner detection (should show CRITICAL risk for SHA1HULUD self-hosted runners)
./shai-hulud-detector.sh test-cases/github-actions-runners
# Test file hash verification (should validate benign files against malicious hashes)
./shai-hulud-detector.sh test-cases/hash-verification
# Test destructive pattern detection (should show CRITICAL risk for data destruction commands)
./shai-hulud-detector.sh test-cases/destructive-patternsThe latest version includes enhanced detection for previously undetected attack techniques from the Koi.ai "Second Coming" analysis:
- Test Case:
test-cases/semver-wildcards/ - Validates: Proper parsing of version patterns like "4.x", "1.2.x", "x.x.x"
- Background: Fixes parsing errors that occurred when the script encountered wildcard version patterns
- Expected: Clean execution without syntax errors when processing wildcard patterns
- Test Case:
test-cases/discussion-workflows/ - Validates: Detection of malicious GitHub Actions workflows that trigger on issue/PR discussion events
- Background: Stealth persistence technique where workflows activate when legitimate users comment on issues/PRs
- Expected: CRITICAL risk alerts for workflows with
on: discussiontriggers containing suspicious activity
- Test Case:
test-cases/github-actions-runners/ - Validates: Detection of persistent backdoors installed as self-hosted GitHub Actions runners
- Background: Attackers install runners in
.dev-env/directories with SHA1HULUD naming patterns for persistent access - Expected: CRITICAL risk alerts for runner configurations with malicious naming patterns in development directories
- Test Case:
test-cases/hash-verification/ - Validates: SHA256 hash verification against known malicious file signatures
- Background: Enhanced detection of malicious files by their cryptographic fingerprints rather than just filename patterns
- Expected: Accurate identification of malicious files by hash, with clean files passing verification
- Test Case:
test-cases/destructive-patterns/ - Validates: Detection of destructive fallback commands that activate when credential theft fails
- Background: From Koi.ai report - when credential exfiltration fails, malware deletes files as destructive fallback
- Expected: CRITICAL risk alerts for patterns like
rm -rf $HOME/*,fs.rmSync(..., {recursive: true}),Remove-Item -Recurse - Coverage: Cross-platform destruction patterns (Linux/macOS/Windows)
The --paranoid flag enables additional security checks beyond Shai-Hulud-specific detection:
- Typosquatting Detection: Identifies packages with names similar to popular packages (e.g., "raect" instead of "react", "lodsh" instead of "lodash")
- Network Exfiltration Patterns: Detects suspicious domains (webhook.site, pastebin.com), hardcoded IP addresses, WebSocket connections to external endpoints
- Enhanced Security Auditing: Useful for comprehensive project security reviews
Note: Paranoid mode may produce more false positives from legitimate code patterns, so review findings carefully.
The script now intelligently handles projects with lockfiles to reduce false positives:
- Lockfile Detection: Automatically detects package-lock.json, yarn.lock, and pnpm-lock.yaml files
- Actual Version Checking: When semver ranges could match compromised versions, checks the actual installed version from lockfiles
- Smart Risk Assessment:
- HIGH RISK: Lockfile contains exact compromised version (immediate threat)
- LOW RISK: Lockfile contains safe version (protected by lockfile, but avoid updates)
- MEDIUM RISK: No lockfile present (potential update risk)
Example: If your package.json has debug@^4.0.1 (which could match compromised [email protected]), but your lockfile pins to [email protected], you'll see a LOW RISK message explaining that your current installation is safe.
This feature addresses Issue #42 and eliminates confusion for users with older projects that have established lockfiles.
The script performs these comprehensive checks:
- Package Database Loading: Loads the complete list of 1,677+ compromised packages from
compromised-packages.txt(September & November 2025, plus 953 packages from Koi.ai "Second Coming" analysis) - Workflow Detection: Searches for
shai-hulud-workflow.ymlfiles (September 2025) andformatter_*.ymlfiles with SHA1HULUD runners (November 2025) - Hash Verification: Calculates SHA-256 hashes of JavaScript/JSON files against 7 known malicious bundle.js variants representing the complete evolution of the Shai-Hulud worm (V1-V7)
- November 2025 Bun Attack Detection: Identifies
setup_bun.js(fake Bun installer) andbun_environment.js(obfuscated payload) files with enhanced SHA256 hash verification - Package Analysis: Parses
package.jsonfiles for specific compromised versions, affected namespaces, and fake Bun preinstall hooks - Postinstall Hook Detection: Identifies suspicious postinstall scripts including fake Bun installation patterns (
"preinstall": "node setup_bun.js") - Content Scanning: Greps for suspicious URLs, webhook endpoints, and malicious patterns
- Cryptocurrency Theft Detection: Identifies wallet address replacement patterns, XMLHttpRequest hijacking, and known crypto theft functions from the September 8 attack
- Enhanced Trufflehog Activity Detection: Looks for credential scanning tools, secret harvesting, and November 2025 automated TruffleHog download patterns
- Git Analysis: Checks for suspicious branch names and repository names
- Repository Detection: Identifies "Shai-Hulud" repositories and "Sha1-Hulud: The Second Coming" repository descriptions
- Secrets Exfiltration Detection: Identifies
actionsSecrets.jsonfiles with double Base64 encoded credentials - GitHub Actions Runner Detection: Identifies malicious SHA1HULUD runners in GitHub Actions workflows
- Discussion Workflow Detection: Identifies malicious GitHub Actions workflows that trigger on discussion events (a stealth persistence technique where workflows activate when issues/PRs receive comments)
- Self-Hosted Runner Detection: Detects persistent backdoor installations via self-hosted GitHub Actions runners stored in
.dev-env/directories with SHA1HULUD naming patterns - Destructive Payload Detection: Identifies destructive fallback patterns that activate when credential theft fails, including
rm -rf $HOME/*,fs.rmSync(..., {recursive: true}),Remove-Item -Recurse, and cross-platform destruction commands - Package Integrity Checking: Analyzes package-lock.json and yarn.lock files for compromised packages and suspicious modifications
- Hash Detection: Only detects files with exact matches to the 7 known malicious bundle.js hashes
- Package Versions: Detects specific compromised versions and namespace warnings, but new compromised versions may not be detected
- False Positives: Legitimate use of webhook.site, Trufflehog for security, or postinstall hooks will trigger alerts
- Worm Evolution: The self-replicating nature means new variants may emerge with different signatures
- Coverage: Covers known compromised packages from major September 2025 and November 2025 attacks
- Package Integrity: Relies on lockfile analysis to detect compromised packages, but sophisticated attacks may evade detection
If you discover additional IoCs or compromised packages related to the Shai-Hulud attack, please update the arrays in the script and test thoroughly.
This script is for detection only. It does not:
- Automatically remove malicious code
- Fix compromised packages
- Prevent future attacks
Always verify findings manually and take appropriate remediation steps.
Recent investigations have revealed a potential connection between the Shai-Hulud campaign and the Nx package ecosystem:
- Repository Migration Patterns: Attackers are using repositories with "-migration" suffixes to distribute malicious packages
- Advanced Package Integrity Checks: Double base64-encoded
data.jsonfiles have been discovered in compromised package versions - Additional Compromised Versions:
[email protected]and[email protected]have been identified as compromised - New Package Targets:
angulartics2andkoa2-swagger-uipackages have been added to the compromised list
The script now includes:
- Fixed lockfile false positives: Improved package version extraction to prevent incorrect flagging of safe packages (fixes issue #37)
- Robust lockfile parsing: Uses block-based JSON parsing instead of proximity-based grep to accurately extract package versions
- Context-aware XMLHttpRequest detection: Reduces false positives for legitimate framework code (React Native, Next.js)
- Improved risk stratification: XMLHttpRequest modifications now properly classified based on context and crypto patterns
- Parallel processing optimization: ~20% performance improvement with semver pattern matching
- Duplicate-free package database: Cleaned 600+ unique compromised package entries
- Repository migration pattern detection
- Package-lock.json integrity verification
- Context-aware Trufflehog detection to reduce false positives
- Risk level classification (HIGH/MEDIUM/LOW) for better triage
- StepSecurity Blog: CTRL, tinycolor and 40 NPM packages compromised
- JFrog: New compromised packages in largest npm attack in history
- Aikido: NPM debug and chalk packages compromised
- Semgrep Security Advisory: NPM packages using secret scanning tools to steal credentials
- Aikido: S1ngularity-nx attackers strike again
- Socket: Ongoing supply chain attack targets CrowdStrike npm packages
- Ox Security: NPM 2.0 hack: 40+ npm packages hit in major supply chain attack
- Phoenix Security: NPM tinycolor compromise
- Initial Discovery: September 15, 2025
- Scale: 571+ packages compromised across multiple attack campaigns
- Attack Type: Self-replicating worm using postinstall hooks
- Malicious Endpoint:
https://webhook.site/bb8ca5f6-4175-45d2-b042-fc9ebb8170b7 - Exfiltration Method: GitHub repositories named "Shai-Hulud"
We welcome contributions to improve any of the code, documentation, tests and packages covered.
-
Fork the repository
git clone https://github.com/Cobenian/shai-hulud-detect.git cd shai-hulud-detector -
Update the package list
- Add new packages to
compromised-packages.txtin the formatpackage_name:version - Include a source/reference for where you found the compromised package
- Group packages by namespace for organization
- Add new packages to
-
Test your changes
# Test that the script loads the new packages ./shai-hulud-detector.sh test-cases/clean-project # Run all test cases to ensure nothing breaks ./shai-hulud-detector.sh test-cases/infected-project ./shai-hulud-detector.sh test-cases/mixed-project
-
Submit a Pull Request
- Create a descriptive PR title (e.g., "Add @example/package compromised versions")
- Include details about the source of the information
- Reference any security advisories or reports
- Explain any version patterns or attack details
- Bug fixes: Report and fix issues with detection accuracy
- New IoCs: Add detection for additional indicators of compromise
- Documentation: Improve clarity and add examples
- Test cases: Add new test scenarios for edge cases
- Verify sources: Only add packages confirmed by reputable security firms
- Test thoroughly: Ensure changes don't break existing functionality
- Document changes: Update relevant documentation and changelog
- Follow patterns: Match existing code style and organization
- Security first: Never include actual malicious code in test cases
If you can't submit a PR, you can still help by reporting new compromised packages:
- Open an issue with the title "New compromised package: [package-name]"
- Include the package name, version, and source of information
- Provide links to security advisories or reports
- We'll review and add verified packages to the detection list
For a complete list of changes and version history, see the CHANGELOG.md.
This project is licensed under the MIT License - see the LICENSE file for details.