How to Check NPM Vulnerabilities: Building a Custom NPM Vulnerability Scanner
How I created a custom npm vulnerability scanner using deps.dev API to track dependencies and vulnerabilities beyond traditional tools
Building an NPM Vulnerability Scanner to Check Your Dependencies
The npm ecosystem is both a blessing and a curse for JavaScript developers. With over 2 million packages, it's incredibly powerful, but it's also a prime target for supply chain attacks. Incidents involving Poisoned Packages, more recently chalk packages, malicious typo squatting packages, and countless prototype pollution vulnerabilities have made one thing clear: trusting npm packages blindly is playing with fire.
Traditional tools only scratch the surface. That's why I built a custom npm vulnerability scanner that goes beyond basic checks, and I'm going to show you exactly how to use it to check npm vulnerabilities in your own projects as a great starting point.
🚀 Want to try it right now? Check out the Quick Start Guide to get the scanner running in under 2 minutes with the included test project and save time !
The NPM Security Challenge: Why checking npm vulnerabilities Matters
Recent supply chain attacks have made the npm ecosystem's vulnerabilities painfully clear. From my experience working with enterprise organisations, I've seen that a reactive approach isn't sustainable and you need to actively test packages with all the available tools and catch anomalies early in your processes.
The problems are multifaceted:
- Supply chain attacks are increasing, with attackers compromising maintainer accounts - See Gartner Predictions
- Malicious packages can exfiltrate credentials, create backdoors, or mine cryptocurrency
- Transitive dependencies create blind spots - one package pulls in dozens of others
- Abandoned packages may not receive security updates
- Zero-day vulnerabilities in popular packages can affect thousands of projects instantly
Traditional npm audit only scratches the surface, checking against npm's vulnerability database after vulnerabilities are already known and reported. But what about:
- Newly published malicious packages?
- Recently compromised legitimate packages?
- Package age and maintenance status?
- Behavioural analysis of suspicious packages?
The cybersecurity community is actively seeking better tooling and processes to address these gaps. That's where a custom npm vulnerability scanner can be the first step in that process.
Why Use deps.dev API for NPM Vulnerability Scanning?
The deps.dev API aggregates data from multiple sources including npm, GitHub, and various security databases. Unlike npm's built-in tools, it provides:
- Comprehensive vulnerability data from multiple security databases
- Release date information for tracking dependency freshness and potential abandonment
- Version history and metadata for understanding maintenance patterns
- No authentication required - completely free to use
- Multiple package ecosystem support (npm, PyPI, Maven, etc.)
- Broader coverage that may catch vulnerabilities missed by npm's database
This approach aligns with what I always tell organisations: you need continuous security validation, not just point-in-time checks.
How to Build Your NPM Vulnerability Scanner
I created a simple but effective dependency scanner as an npm script. Here's how you can implement it in your projects.
🚀 Want to try it right now? Check out the Quick Start Guide to save time get all the code from github and start testing in under 2 minutes with the included test project!
Below is an explanation of the project and what it does.
Step 1: Get the Scanner
The main scanner is a single JavaScript file that parses your dependencies and queries the deps.dev API. You can grab it from the GitHub repo and start playing with it straight away:
# Clone the complete project with test setup
git clone https://github.com/cyberdesserts/npm-scanner.git
cd npm-scanner/weather-cli-test
npm install
# Or just download the scanner file to your project
curl -o dependency-scanner.js https://raw.githubusercontent.com/cyberdesserts/npm-scanner/main/weather-cli-test/dependency-scanner.js
Step 2: The Scanner Implementation
The scanner will:
- Parse
package.jsonto extract dependencies - Query the deps.dev API for each package
- Collect vulnerability and release date information
- Generate a comprehensive report
The core functionality involves three main API endpoints from deps.dev:
// Get version information and release dates
GET /v3/systems/npm/packages/{package}/versions/{version}
// Get vulnerability advisories
GET /v3/systems/npm/packages/{package}/versions/{version}/advisories
// Get all available versions (optional)
GET /v3/systems/npm/packages/{package}/versions
Step 3: Running the NPM Vulnerability Scanner
Add this to your package.json:
{
"scripts": {
"scan-deps": "node scripts/dependency-scanner.js"
}
}
Then run it to check npm vulnerabilities:
npm run scan-deps
Understanding Your NPM Vulnerability Scan Report
Here's what a typical scan report looks like when you check npm vulnerabilities:
Scanning 8 dependencies...
Scanning [email protected]...
Scanning [email protected]...
Scanning [email protected]...
Scanning [email protected]...
Scanning [email protected]...
Scanning [email protected]...
Scanning [email protected]...
Scanning [email protected]...
=== DEPENDENCY SCAN REPORT ===
Total packages scanned: 8
Packages with vulnerabilities: 2
⚠️ VULNERABLE PACKAGES:
📦 [email protected]
Published: 2020-02-20T17:27:44.065Z
Vulnerabilities: 2
- Prototype Pollution (High severity)
Lodash versions prior to 4.17.21 are vulnerable to Prototype Pollution
- Command Injection (Moderate severity)
ReDoS vulnerability in lodash
📦 [email protected]
Published: 2019-04-16T14:32:18.123Z
Vulnerabilities: 1
- Timing Attack (Low severity)
JWT signature verification vulnerable to timing attacks
📅 OLDEST DEPENDENCIES:
[email protected] - 2019-04-16 (1,614 days old)
[email protected] - 2020-02-20 (1,337 days old)
[email protected] - 2020-07-04 (1,173 days old)
✅ SECURE PACKAGES:
[email protected] - No vulnerabilities found
[email protected] - No vulnerabilities found
[email protected] - No vulnerabilities found
Results saved to dependency-scan.json
What This Report Tells You About NPM Vulnerabilities
From this example scan, you can immediately identify several security concerns:
- Immediate Action Required: The high severity prototype pollution in lodash needs immediate attention, this is a classic vulnerability that's been exploited in the wild
- Age Red Flags: Dependencies over 1000 days old may be abandoned or poorly maintained
- Attack Surface: 2 out of 8 packages having vulnerabilities shows how quickly risk accumulates
- Maintenance Debt: Old packages like jsonwebtoken from 2019 are prime targets for supply chain attacks
This visibility helps you understand:
- Which updates are security-critical vs. nice-to-have
- Whether to find alternative packages for abandoned dependencies
- Risk assessment for compliance and security reviews
How to Fix NPM Vulnerabilities: A Practical Approach
Once you've used your npm vulnerability scanner to check npm vulnerabilities, here's how to fix them effectively:
1. Integrate with npm audit for Immediate Action
Combine your custom scanner with npm's built-in tools:
{
"scripts": {
"scan-deps": "node scripts/dependency-scanner.js",
"security-check": "npm audit && npm run scan-deps",
"fix-and-scan": "npm audit fix && npm run scan-deps",
"security-full": "npm audit fix --force && npm run scan-deps"
}
}
Important: Use npm audit fix --force cautiously, it may introduce breaking changes, but sometimes security trumps compatibility.
Learn more: npm audit documentation
2. Version Pinning and Lock File Management
One of the most effective ways to fix npm vulnerabilities is controlling when updates happen:
I found this video was great to explain the mechanics of package-lock.json
Example
{
"dependencies": {
"express": "4.18.0", // Exact version, not "^4.18.0"
"lodash": "4.17.21" // No semver ranges
}
}
Best practices:
- Use
npm install --save-exactfor new packages - Always commit
package-lock.json - Use
npm ciin production, nevernpm install - Make package updates separate PRs for scrutiny
3. Automate NPM Vulnerability Scanning
I recommend running your npm vulnerability scanner periodically:
GitHub Actions:
name: NPM Vulnerability Scan
on:
schedule:
- cron: '0 9 * * *' # Daily at 9 AM
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm run scan-deps
Local Cron Job:
# Daily scan at 9 AM
0 9 * * * cd /path/to/project && npm run scan-deps >> scan.log 2>&1
Beyond Basic NPM Vulnerability Scanning: A Layered Security Approach
I've found that no single tool solves npm vulnerabilities completely. Here's a comprehensive approach:
1. Time-Based Safety Measures
Several organisations implement "cooldown periods" before adopting new packages:
- JFrog Curation policies requiring packages to be published for X days
- Internal registries with delayed mirroring from npm
- Manual review processes for new dependencies
This approach helps catch malicious packages that are quickly identified and removed.
2. Private Registry Solutions
According to feedback from DevSecOps engineers, consider using:
- Artifactory with private repositories and package approval workflows
- Nexus Firewall for vetted internal repositories
- Proxy registries with security scanning integration
3. Runtime and Development Environment Protection
Developer workstation security:
- Remove admin rights from developers
- Use password managers for environment variables instead of plaintext files
- Implement tools like Aikido Safechain to block malware installation
Pipeline and production:
- SBOM scanning on every build and deployment
- eBPF monitoring to spot zero-day exploits in runtime
- Never run
npm installin production pipelines, usenpm cionly - Use
--ignore-scriptsjudiciously (opt-out rather than opt-in)
4. Proactive Detection and Response
Modern security approaches focus on rapid detection rather than perfect prevention:
- Frequent vulnerability feeds (hourly updates vs daily)
- Behavioural analysis of packages for suspicious activity
- Automated alerting via Slack/email for new threats
- Malware detection integrated into CI/CD pipelines
- There is room for more ideas on the vulnerability scanning side to check for package anomalies.
Key Takeaways: How to Check and Fix NPM Vulnerabilities
Here's what I've learned about managing npm vulnerabilities effectively:
- Accept the reactive reality: Perfect prevention isn't possible, so focus on rapid detection and response
- Layer your defenses: No single tool solves npm security, combine scanning, private registries, time delays, and process controls
- Automate what you can: Manual reviews don't scale, but automated scanning and alerting do
- Make security frictionless: If security tools are too painful, developers will work around them
- Measure effectiveness continuously: Don't just scan once, make vulnerability checking part of your daily workflow and continue to improve on it.
Next Steps: Implementing Your NPM Vulnerability Scanner
The npm supply chain security challenge isn't solved by any single tool, it requires a comprehensive approach combining technology, process, and culture. The deps.dev scanner gives you a good foundation to build something for yourself.
What you can do today:
- Install and test the scanner using the GitHub repo
- Building on this foundation, you can add:
- Slack/email notifications for critical vulnerabilities
- Add tests for other types of anomalies when scanning packages (Claude Code can be helpful for planning ideas)
- CI/CD integration to fail builds on high-risk dependencies
- Custom scoring based on your organisation's risk tolerance
- Historical trending to track your security posture over time
- Multi-project dashboards for portfolio-wide visibility
How effective is your current approach to npm vulnerabilities ?
I'd love feedback on this implementation, I am still learning about package hygiene so feel free to reach out, contribute improvements, or fork the project to adapt it for your specific needs.