This directory hosts a Bash-based scanner that flags compromised npm packages and payload breadcrumbs associated with documented attacks (September 2025 qix incident, Shai-Hulud 2.0, etc.). Indicators are stored under attacks/ so that new campaigns can be onboarded without rewriting the script.
# Scan current directory for all known attacks
./npm-supply-chain-detector
# Scan a specific project
./npm-supply-chain-detector /path/to/project
# Check for specific attack only
./npm-supply-chain-detector -a shai-hulud-2
# List all available attacks
./npm-supply-chain-detector --list-attacks
# Run the bundled sparkSec recipe runner (lists commands if no args are passed)
./sparkSec/sparkSec.sh security-scan-npmTip: Symlink
sparkSec/sparkSec.shsomewhere in yourPATH(e.g.,/usr/local/bin/sparkSec) to invoke the same commands from anywhere.
- Clone this repository:
git clone https://github.com/sparkfabrik/supply-chain-security-detectors.git
- (Optional) Place it at
/opt/supply-chain-security-detectorsso that Sparkdock’ssjustcommands can discover it automatically. - (Optional) Symlink
sparkSec/sparkSec.shinto yourPATHso you can runsparkSec security-*directly from this repo. - Alternatively, export
SUPPLY_CHAIN_SECURITY_DETECTORS_PATH=/path/to/your/clonebefore running Sparkdock’ssjust security-*commands. - Keep the repository up to date to receive new attack signatures.
The detector can be executed directly (./npm-supply-chain-detector) or via Sparkdock (sjust security-scan-npm), which shells out to the same script.
- Multi-Attack Detection: Checks for multiple supply chain attacks simultaneously
- Package Version Scanning: Detects compromised package versions in package.json, package-lock.json, and yarn.lock
- Malicious Code Detection: Scans JavaScript files for known attack signatures
- Payload Artifact Detection: Identifies malicious files dropped by attacks
- Workflow Backdoor Detection: Checks for malicious GitHub Actions workflows
- Node.js Optimization: Uses a Node.js helper for faster dependency parsing when available
- Date: November 21-23, 2025
- Packages: ~700 compromised packages
- Targets: posthog-node, @postman/, @ensdomains/, @zapier/* and many others
- Reference: Wiz.io Blog
- Date: September 8-15, 2025
- Packages: ~70 compromised packages
- Targets: chalk, ansi-styles, color, debug and related packages
# Scan current directory
npm-supply-chain-detector
# Scan specific directory
npm-supply-chain-detector /path/to/project# Check for all attacks (default)
npm-supply-chain-detector -a all
# Check for Shai-Hulud 2.0 only
npm-supply-chain-detector -a shai-hulud-2
# Check for September 2025 qix attack only
npm-supply-chain-detector -a september-2025-qix# Show help
npm-supply-chain-detector --help
# List all available attacks
npm-supply-chain-detector --list-attacks-
Package Manifests:
package.json- all dependency types (dependencies, devDependencies, etc.)package-lock.json- locked versionsyarn.lock- Yarn lockfile
-
Installed Packages:
node_modules/- checks installed package versions- Scopes packages (e.g.,
@postman/*,@ensdomains/*)
-
Source Code:
.js,.jsx,.ts,.tsx,.mjs,.cjsfiles- Checks for malicious signatures and heavily obfuscated code
-
Artifacts:
- Payload files (e.g.,
setup_bun.js,cloud.json) - Backdoor workflows (e.g.,
.github/workflows/discussion.yaml)
- Payload files (e.g.,
0- No issues found, scan successful1- Compromised packages or malicious code detected2- No package manifests found to scan
To add a new attack signature:
-
Update
attacks/attacks.json:{ "id": "new-attack-2025", "name": "New Attack 2025", "file": "new-attack-2025.txt", "date": "2025-12-01", "packages": 100, "description": "Description of the attack", "signatures": ["malicious-signature-1", "malicious-signature-2"], "payloadFiles": ["malicious-file.js"], "workflowPaths": [".github/workflows/malicious.yaml"] } -
Create
attacks/new-attack-2025.txt:# New Attack 2025 - Compromised Packages # Format: ["package-name"]="version" ["compromised-package"]="1.2.3" ["another-package"]="4.5.6"
-
Update the script's case statement (if needed) in the
load_compromised_packages()function to handle the new attack ID.
supply-chain-security-detectors/
├── npm-supply-chain-detector # Main scanner script
├── scripts/
│ └── list-deps.js # Node.js helper for dependency extraction
├── attacks/
│ ├── attacks.json # Attack metadata
│ ├── shai-hulud-2.txt # Shai-Hulud 2.0 package list
│ └── september-2025-qix.txt # September 2025 qix package list
└── README.md # This file
- Bash 4.0+: Required for associative arrays
- Node.js (optional): Enables faster dependency parsing
- Standard Unix tools: grep, sed, find, cut
- With Node.js: Uses optimized dependency parser (~2-5 seconds for medium projects)
- Without Node.js: Falls back to grep-based parsing (~5-10 seconds for medium projects)
- Scan depth: Default maximum depth of 5 subdirectories (configurable)
- This tool checks for known compromised versions and signatures
- A clean scan does not guarantee complete security
- Always run
npm auditfor additional vulnerability checks - Keep the attack definitions up to date
- Review and investigate any warnings about version ranges
- Isolate: Disconnect affected systems from the network
- Rotate credentials: GitHub, cloud providers, npm, API keys
- Clean: Remove node_modules, clear npm cache, reinstall dependencies
- Audit: Review GitHub Actions, commits, and published packages
- Report: Contact security team and relevant package maintainers
This tool is integrated with Sparkdock's task runner (sjust). Place the repository at /opt/supply-chain-security-detectors or export SUPPLY_CHAIN_SECURITY_DETECTORS_PATH so the recipes can find it, then use:
# Run supply chain scan
sjust security-scan-npm
# Scan specific attack
sjust security-scan-npm-attack shai-hulud-2Released under the GNU General Public License v3.0 (same as Sparkdock).