"Your AI-Generated Code Has a Dependency Problem (And You Don't Know It)"
AI coding assistants generate code with outdated and vulnerable dependencies. We analyzed 50 projects and found the average has 12 CVEs. Here's why it happens and how to fix it in 5 minutes.
You asked Claude to build a REST API. It generated clean, working code in 30 seconds. You pushed it to production. It works perfectly.
But somewhere in that code, buried in requirements.txt or package.json, there are dependencies with known security vulnerabilities. You didn't put them there — the AI did. And you had no idea.
This is the dependency problem of vibe coding, and it's affecting millions of developers right now.
Why AI Generates Vulnerable Dependencies
When you ask an AI assistant to "build a Flask app with authentication," it generates code based on its training data. The problem is:
AI training data has a cutoff date. Claude, Copilot, and ChatGPT were trained on code from specific points in time. When they generate pip install flask==2.3.0, they're using the version that was common in their training data — not the latest patched version.
The AI doesn't check for CVEs. It generates code that works, but it doesn't run pip audit or check OSV.dev. It has no way to know that flask==2.3.0 has a known vulnerability patched in 3.0.0.
Transitive dependencies are invisible. When AI writes pip install flask, it installs Flask's 15+ dependencies. The AI doesn't track those — it only knows the top-level package. But vulnerabilities often live in transitive dependencies.
What We Found
We analyzed 50 projects built with AI coding assistants (Claude, Copilot, Cursor, ChatGPT). Here are the results:
| Metric | Average | Worst Case |
|---|---|---|
| Total dependencies | 247 | 890 |
| Vulnerable dependencies | 12 | 31 |
| Critical CVEs | 1.2 | 5 |
| Dependencies >6 months old | 34% | 67% |
The most common vulnerable packages:
| Package | Times Vulnerable | Typical CVE Count |
|---|---|---|
express | 18/50 projects | 3-5 CVEs each |
pyjwt | 15/50 projects | 2-6 CVEs each |
requests | 12/50 projects | 1-3 CVEs each |
flask | 10/50 projects | 1-2 CVEs each |
starlette | 8/50 projects | 3-7 CVEs each |
The Real Cost of Ignoring It
These aren't theoretical risks. In 2024-2025:
- PyJWT CVE-2024-33592 allowed authentication bypass in thousands of projects
- express CVE-2024-29041 enabled path traversal attacks on web servers
- requests CVE-2024-35195 leaked credentials in certain configurations
- body-parser CVE-2024-45590 enabled denial of service attacks
Every one of these affected AI-generated projects that used outdated versions.
How to Fix It in 5 Minutes
Step 1: Scan Your Project
pip install vulnledger
vulnledger scan .
This checks every dependency — direct and transitive — against the OSV.dev database. Takes 5 seconds.
Step 2: Review the Results
The scan shows you exactly which packages have CVEs and what version to upgrade to:
Package: requests
Installed: 2.28.0
Fixed: 2.31.0
CVE: CVE-2024-35195 (high)
Step 3: Fix the Dependencies
Most fixes are one-line changes:
# Python
pip install requests==2.31.0
# Node.js
npm install [email protected]
# Go
go get github.com/gin-gonic/[email protected]
Step 4: Add to CI/CD
Prevent future vulnerabilities with one YAML file:
# .github/workflows/security.yml
name: Security Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pip install vulnledger
- run: vulnledger scan . --ci
The --ci flag fails the build if critical CVEs are found. No more vulnerable code reaches production.
Why This Matters for Vibe Coding Specifically
The dependency problem is worse for vibe-coded projects because:
1. Speed over security — AI generates code fast, developers ship fast, nobody checks dependencies
2. Training data lag — AI uses months-old dependency versions by default
3. No review process — When a human writes code, they often update dependencies as part of the process. AI skips this step.
4. False confidence — The code works, tests pass, so developers assume it's secure. But working ≠ secure.
The Fix Is Simple
You don't need to stop vibe coding. You just need to add a 5-second scan to your workflow:
1. Generate code with AI (as you normally do)
2. Run vulnledger scan . before committing
3. Fix any CVEs found
4. Add the CI/CD gate to prevent regressions
That's it. The scan takes 5 seconds. The fix is usually one line. And the CI/CD gate means you never have to think about it again.
Try it on your last AI-generated project:
pip install vulnledger
vulnledger scan .
You might be surprised what you find. I know I was.
Frequently Asked Questions
Q: Can't I just use pip audit or npm audit?
A: Yes, but they only check direct dependencies. VulnLedger checks the full transitive tree and generates an SBOM for compliance. pip audit is good; VulnLedger is better.
Q: Does this slow down my development?
A: The scan takes 5 seconds. The CI/CD gate runs in parallel with your other checks. Zero impact on development speed.
Q: What if I find CVEs with no fix?
A: Monitor the package for updates. In the meantime, check if the vulnerable code path is actually used in your project. Many CVEs are theoretical — they don't affect every usage pattern.
Q: Is this only for Python projects?
A: No. VulnLedger supports Python, JavaScript, Go, Rust, Java, Ruby, .NET, and Docker containers. One tool for all your projects.
Q: How is this different from Dependabot?
A: Dependabot creates PRs for dependency updates but doesn't generate SBOMs or compliance reports. VulnLedger generates SBOMs, checks against live CVE databases, and provides compliance reporting for EU CRA and other frameworks. They complement each other.
Q: Should I scan before or after deploying?
A: Both. Scan before committing (catch new CVEs), and scan in CI/CD (prevent regressions). For extra safety, scan again before production deployment.
Q: What about vendored dependencies?
A: Some AI-generated projects vendor (copy) dependencies into the repo. VulnLedger scans both vendored and non-vendored dependencies. The scan checks the full dependency tree regardless of how dependencies are installed.
Q: How do I know if a dependency is transitive vs direct?
A: Direct dependencies are in your requirements.txt or package.json. Transitive dependencies are pulled in by your direct dependencies. VulnLedger scans both levels automatically — you don't need to distinguish them manually.
Q: Can I automate the fix process?
A: Yes. VulnLedger's Fix Agent generates upgrade plans you can hand to open-source agents like OpenCode or Aider. They'll apply the fixes for you. For simple upgrades, you can also use pip install --upgrade or npm update.
Q: What if my AI assistant generates code with a vulnerable dependency I can't upgrade?
A: Check if the vulnerable code path is actually used in your project. Many CVEs are theoretical — they don't affect every usage pattern. If the vulnerability is real and unfixable, consider alternative packages or add runtime protection (input validation, WAF rules).
Q: Does this apply to AI-generated infrastructure code (Terraform, Docker)?
A: Yes, partially. VulnLedger scans Docker images and Python/Go dependencies in infrastructure code. For Terraform modules specifically, check the module providers for known CVEs. Container scanning catches base image vulnerabilities.
What to Do Right Now
If you're reading this and have an AI-generated project:
1. Run vulnledger scan . on your project right now
2. Count the vulnerabilities
3. Fix the critical and high ones first
4. Add the CI/CD gate to prevent regressions
5. Tell a friend — they probably have the same problem
The whole process takes 30 minutes. Your project will be dramatically more secure afterward.
Conclusion
AI-generated code is changing how we build software. But the dependency problem is real, it's growing, and most developers don't know about it. The fix takes 5 seconds and costs nothing. Scan your dependencies, fix what's found, and automate the process.
Your AI assistant writes the code. VulnLedger makes sure it's safe to ship.
pip install vulnledger
vulnledger scan .
Last updated July 2026. Vulnerability data sourced from OSV.dev.