npm Security Risks: Auditing AI-Generated Dependencies Without Dying
AI assistants generate npm dependency trees with hidden security risks. Learn how to audit, scan, and lock down dependencies from AI-assisted Node.js proje
The npm Dependency Problem
When an AI assistant scaffolds a Node.js project, it generates package.json with 20-50 dependencies. The syntax is correct. The versions resolve. The code runs.
But 40% of those dependencies are security liabilities the AI didn't reason about:
- Packages with known CVEs
- Dependencies maintained by a single person in their spare time
- Packages that haven't been updated in 3+ years
- Packages added for a single function that could be written in 10 lines
The AI assistant optimized for "code that runs," not "code that's secure." And most developers don't audit AI-generated dependency trees before shipping.
How npm Became a Supply Chain Battleground
Recent attacks (typosquatting by APT41, the broader ecosystem of compromised packages) show attackers are specifically targeting:
1. Popular packages with many dependents — A single compromised package reaches thousands of applications
2. Neglected packages — Maintainers who don't monitor their repos closely
3. AI-generated code that auto-installs dependencies — Developers who run npm install and trust the result without review
When an AI assistant suggests a dependency, developers often assume:
- The package is maintained
- The package is secure
- The package is necessary
All three assumptions are frequently wrong.
What AI Gets Wrong About npm
1. Unnecessary Dependencies
{
"dependencies": {
"lodash": "^4.17.21",
"moment": "^2.29.1",
"uuid": "^9.0.0"
}
}
AI assistants pull from templates and boilerplate. Half these packages might be unnecessary. lodash for three utility functions? moment when you only need date formatting? These increase attack surface without proportional benefit.
2. Outdated Versions
AI training data includes code from 2023 and earlier. Recommended versions might be months behind the latest. The AI doesn't consistently check for security patches.
3. Missing Peer Dependencies
AI sometimes omits peer dependencies that cause silent failures or force consumers to manage versions themselves. This creates the conditions for dependency confusion attacks.
4. No Security Advisories
The AI has no concept of CVEs, security advisories, or deprecated packages. It will happily suggest a package that was pulled for containing malware if that package appears in enough training examples.
Audit Strategy for AI-Generated Dependencies
Step 1: Get a Dependency Tree
# See what you actually have
npm ls --depth=0
# Export full tree for analysis
npm ls --json > dependencies.json
Step 2: Scan for Known Vulnerabilities
# Built-in npm audit
npm audit
# More aggressive scanning
npm audit --audit-level=moderate
# Also check with dedicated tools
npm install -g snyk
snyk test
Step 3: Evaluate Each Direct Dependency
For every package in your dependencies (not devDependencies), ask:
Is it necessary?
# Check if the package is actually used
grep -r "require('package-name')" src/
grep -r "import.*package-name" src/
# If not found, remove it
npm uninstall package-name
Is it maintained?
# Check last update
npm view package-name time
# If last update is 3+ years ago, investigate
# Can you write the functionality yourself in 50 lines?
# Consider doing so instead.
Who maintains it?
# Check the maintainer
npm view package-name maintainers
# Single maintainer? Higher risk.
# Unknown author? Much higher risk.
# Corporate maintainer (Google, Facebook, Microsoft)? Lower risk.
Step 4: Lock Versions Aggressively
{
"dependencies": {
"express": "4.18.2",
"uuid": "9.0.0"
}
}
Use exact versions (4.18.2) not ranges (^4.18.2). AI-generated package.json often uses caret (^) or tilde (~) ranges, which auto-upgrade. This is dangerous in CI/CD because a dependency update might inject malware.
Step 5: Regular Audits
Don't do this once. Set up automated scanning:
# .github/workflows/security-audit.yml
name: Security Audit
on:
schedule:
- cron: '0 0 * * 0' # Weekly
pull_request:
paths:
- 'package.json'
- 'package-lock.json'
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npm audit --audit-level=moderate
- run: snyk test --severity-threshold=high
The Dependency Hygiene Checklist
- [ ] Scanned for CVEs with
npm audit and snyk
- [ ] Verified every direct dependency is actually used
- [ ] Checked that maintainers are active (update in last 6 months)
- [ ] Removed unnecessary dependencies
- [ ] Locked versions to exact releases (no
^ or ~)
- [ ] Set up automated weekly audit scanning
- [ ] Documented why each dependency was chosen
- [ ] Have a plan for updating critical security patches
The Real Cost
Spending 2 hours auditing AI-generated dependencies prevents supply chain attacks that cost 6+ months of incident response. A single compromised package in a high-dependency project can affect thousands of applications.
Don't trust the AI's dependency choices. Don't trust npm's defaults. And definitely don't run npm install without understanding what you're installing.
The next supply chain attack is already in npm's registry. Make sure it's not in your node_modules.