A PowerShell script to detect indicators of the Shai-Hulud npm supply chain attack in your local files and Docker containers.
In September-November 2025, a self-replicating worm called "Shai-Hulud" compromised hundreds of packages in the npm ecosystem. The malware:
- Injects malicious files (
setup_bun.js,bun_environment.js) into packages - Harvests credentials (npm tokens, GitHub PATs, SSH keys, cloud credentials)
- Exfiltrates data to GitHub repositories
- Self-propagates by publishing infected versions of other packages you maintain
References:
| Check | Description |
|---|---|
| Malicious files | Scans for setup_bun.js and bun_environment.js |
| File hashes | Compares found files against known malicious SHA256 hashes |
| Install scripts | Detects suspicious preinstall/postinstall scripts in package.json |
| Code references | Searches for "shai-hulud" patterns in JS/TS/JSON files |
| Metadata exfiltration | Looks for cloud metadata service calls (169.254.169.254) |
| Docker containers | Runs the same checks inside running containers |
YOU MUST FIRST ALLOW THE SYSTEM TO RUN THE POWERSHELL SCRIPT
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass.\check-shai-hulud.ps1.\check-shai-hulud.ps1 -Path "C:\projects\my-app"Important: The script uses Docker Compose to interact with containers. You must run it from the directory containing your project's docker-compose.yml file, or Docker Compose won't recognize the service name.
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"Example output:
| Name | Image | Service Name |
|---|---|---|
myproject-frontend-1 |
myproject-frontend | frontend |
myproject-backend-1 |
myproject-backend | backend |
myproject-app-dev |
myproject-app-dev | app-dev |
The service name is typically the middle portion of the container name (between the project name and the instance number/profile).
cd C:\path\to\your\project # Directory containing docker-compose.ymlUse the absolute path to the script (no .\ prefix needed):
C:\github\Shai_Hulud_Check\check-shai-hulud.ps1 -DockerService "frontend" -DockerProfile "dev"Note: Only use .\ when running a script from the current directory. When using an absolute path like C:\github\..., do not include the .\ prefix or you will get path errors.
If you see Container 'servicename' is not running, you're likely in the wrong directory. Make sure you're in the directory containing the docker-compose.yml for that service.
.\check-shai-hulud.ps1 -Path "." -DockerService "DOCKER_CONTAINER_NAME" -DockerProfile "PROFILE"| Parameter | Required | Default | Description |
|---|---|---|---|
-Path |
No | . |
Local directory to scan |
-DockerService |
No | - | Docker Compose service name to scan |
-DockerProfile |
No | - | Docker Compose profile (e.g., "dev", "prod") |
0- Clean, no infection indicators found1- Potential infection detected
- Stop immediately - Do NOT run
npm installornpm publish - Revoke credentials - Rotate all potentially exposed secrets:
- npm tokens
- GitHub Personal Access Tokens
- SSH keys
- AWS/Azure/GCP credentials
- Check for data exfiltration - Search GitHub for repositories with description "Sha1-Hulud: The Second Coming"
- Roll back - Restore
package-lock.jsonfrom before November 21, 2025 - Clean install - Delete
node_modulesand reinstall from known-good lock file - Audit - Run
npm auditand review the official IOC list
- PowerShell 5.1 or later
- Docker (optional, for container scanning)
- Docker Compose (optional, for container scanning)
- This script checks for known IOCs and may not detect new variants
- Always refer to the latest security advisories for updated indicators
- This is a detection tool, not a remediation tool