🛡️ Enterprise-grade GitHub Action and CLI tool to detect compromised packages from the Shai Hulud supply chain attack
This tool scans your JavaScript projects for compromised packages identified in the ongoing Shai Hulud supply chain attack targeting npm packages that impersonate CrowdStrike fixes.
- ✅ Dual Purpose: Works as both GitHub Action and standalone CLI tool
- 🔍 Multi-Package Manager Support: Scans npm, Yarn, and pnpm lock files
- 💾 Smart Caching: Falls back to cached lists when remote fetch fails
- ⚙️ Configurable: YAML configuration with sensible defaults
- 🚨 GitHub Integration: Automatically comments on PRs and fails CI checks
- 🏢 Enterprise Ready: Suitable for air-gapped environments
This action is available in the GitHub Actions Marketplace. Add it to your workflow (.github/workflows/security-scan.yml):
name: Security Scan
on: [push, pull_request]
jobs:
shai-hulud-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: drewpayment/node-pkg-scanner@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}The action will automatically:
- Scan your repository for compromised packages
- Comment on pull requests if issues are found
- Fail the CI check when compromised packages are detected
- Support npm, Yarn, and pnpm projects
Clone and use this tool directly with Bun for local scanning:
First, install Bun if you haven't already:
curl -fsSL https://bun.sh/install | bashOr visit bun.sh for alternative installation methods.
# Clone the repository
git clone https://github.com/drewpayment/node-pkg-scanner.git
cd node-pkg-scanner
# Install dependencies
bun install
# Run the scanner
bun run cli scan
# Scan with custom config
bun run cli scan --config ./custom-config.yml
# Scan specific directory
bun run cli scan --directory ./my-project
# Scan without failing on detection (for reporting only)
bun run cli scan --no-failFor teams that want to use the scanner without installing Node.js, npm, or Bun, you can use the pre-compiled standalone binaries:
Option 1: Multi-platform build (Development/Testing)
# Clone the repository and build all binaries from one machine
git clone https://github.com/drewpayment/node-pkg-scanner.git
cd node-pkg-scanner
bun install
bun run build:binariesOption 2: Native platform builds (Production - Recommended)
# On each target platform, run:
bun run build:binaryFor production distribution, use Option 2 for best compatibility:
- Run
bun run build:binaryon macOS → Createsnode-pkg-scanner-macos - Run
bun run build:binaryon Windows → Createsnode-pkg-scanner-windows.exe - Run
bun run build:binaryon Linux → Createsnode-pkg-scanner-linux
This creates platform-specific binaries with optimal compatibility.
The most powerful use case is integrating the scanner into npm's preinstall hook to prevent compromised packages from being installed:
Step 1: Place the appropriate binary in your project (e.g., in a security/ directory)
Step 2: Add to your package.json:
{
"scripts": {
"preinstall": "./security/node-pkg-scanner-macos scan --quiet || (echo '❌ Security scan failed - aborting install' && exit 1)"
}
}Step 3: Make executable (Mac/Linux):
chmod +x security/node-pkg-scanner-macosNow every time someone runs npm install, yarn install, or pnpm install, the scanner will run first and prevent installation if compromised packages are detected.
See the examples/ directory for platform-specific package.json examples and advanced configurations.
# Path to the configuration file
configPath: .config.yml
Create a `.config.yml` file in your repository root:
```yaml
# Severity level for compromised packages (error, warning, info)
severityLevel: error
# URL to fetch the compromised packages list from
compromisedPackagesUrl: https://raw.githubusercontent.com/Cobenian/shai-hulud-detect/main/compromised-packages.txt
# Root directory to scan (optional - defaults to current directory)
# rootDirectory: ./src
# Additional packages to check for (beyond the remote list)
additionalPackages: []
# - suspicious-package-name
# Directories to exclude from scanning
excludeDirectories:
- node_modules
- .git
- dist
- build
# Cache timeout in minutes
cacheTimeout: 60| Input | Description | Default |
|---|---|---|
config-path |
Path to configuration file | .config.yml |
fail-on-error |
Fail the action when compromised packages found | true |
github-token |
GitHub token for API access | ${{ github.token }} |
| Output | Description |
|---|---|
compromised-found |
Whether any compromised packages were found (true/false) |
compromised-count |
Number of compromised packages found |
compromised-packages |
JSON array of compromised packages found |
# Basic scan
bun run cli scan
# Scan with custom config
bun run cli scan --config ./custom-config.yml
# Scan specific directory
bun run cli scan --directory ./my-project
# Scan without failing on detection (for reporting only)
bun run cli scan --no-fail
# Quiet mode (minimal output)
bun run cli scan --quiet# Using standalone binary (no dependencies required)
./security/node-pkg-scanner-macos scan
./security/node-pkg-scanner-windows.exe scan # Windows
./security/node-pkg-scanner-linux scan # Linux
# All the same options are available
./security/node-pkg-scanner-macos scan --config custom-config.yml --quiet# Create default config file
bun run cli init
# Overwrite existing config
bun run cli init --forceYou can provide your own compromised packages list by setting a custom URL in the configuration:
compromisedPackagesUrl: https://your-domain.com/compromised-packages.txtThe file should be a simple text file with one package name per line:
malicious-package-1
suspicious-package-2
fake-crowdstrike-fix
To block PRs automatically, configure branch protection rules in your GitHub repository:
1. Go to Settings → Branches
2. Add or edit a branch protection rule
3. Check "Require status checks to pass before merging"
4. Add "Node Package Scanner" to required status checks
### Azure DevOps / Other CI Platforms
Use the CLI tool in any CI/CD platform:
```yaml
# Azure DevOps example (Bun with repo clone)
- script: |
curl -fsSL https://bun.sh/install | bash
git clone https://github.com/drewpayment/node-pkg-scanner.git scanner
cd scanner && bun install
bun run cli scan --directory ../
displayName: 'Scan for compromised packages'# GitLab CI example (Bun with repo clone)
security-scan:
image: oven/bun:latest
script:
- git clone https://github.com/drewpayment/node-pkg-scanner.git scanner
- cd scanner && bun install
- bun run cli scan --directory ../| Package Manager | Files Scanned |
|---|---|
| npm | package.json, package-lock.json |
| Yarn | package.json, yarn.lock |
| pnpm | package.json, pnpm-lock.yaml |
- Primary: Attempts to fetch latest compromised packages from remote URL
- Fallback: Uses cached version if remote fetch fails and cache is valid
- Last Resort: Uses embedded fallback list if no cache available
Cache is stored in system temp directory and respects the cacheTimeout configuration.
- No Credentials Required: Uses public package registries and GitHub APIs
- Minimal Permissions: Only requires basic repository read access
- Offline Capable: Works in air-gapped environments with cached lists
- Audit Trail: All actions are logged and trackable
"Failed to fetch compromised packages list"
- Check internet connectivity
- Verify the URL is accessible
- Check if cached version exists and is valid
"No package files found"
- Verify you're in the correct directory
- Check
excludeDirectoriesconfiguration - Ensure package manager files exist
"GitHub API rate limiting"
- Provide a GitHub token with appropriate permissions
- Use the tool less frequently or implement caching
Enable verbose logging by setting the DEBUG environment variable:
# With npm global install
DEBUG=node-pkg-scanner* node-pkg-scanner scan
# With Bun (cloned repository)
DEBUG=node-pkg-scanner* bun run cli scan- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
MIT License - see LICENSE file for details.
If you discover a security vulnerability, please send an email to security@your-org.com instead of using the issue tracker.
- Socket.dev Blog: Ongoing Supply Chain Attack
- Compromised Packages List
- Supply Chain Security Best Practices