← Back to blog
2026-07-22 · VulnLedger

"Securing Your Python Dependencies: A Practical Guide"

Python dependencies are the #1 attack vector. Here's how to scan, fix, and prevent vulnerable packages in your Python projects. Covers pip, Poetry, pipenv, and conda.

Python Dependencies Security pip Poetry pipenv Vulnerability Scanning

Every pip install you run brings code you didn't write into your project. Some of that code has known security vulnerabilities. This guide shows you how to find and fix them — across every Python package manager.

Why Python Dependencies Are Risky

Python's package ecosystem is massive:

- 500,000+ packages on PyPI

- Average Python project: 50-200 direct dependencies, 200-500 transitive

- Vulnerability rate: ~5% of popular packages have at least one CVE

- Update lag: Many packages are updated months after vulnerabilities are disclosed

The numbers mean: if you have 100 dependencies, statistically 5 of them have known CVEs right now.

Scanning Dependencies

Method 1: VulnLedger (Recommended)

pip install vulnledger
vulnledger scan .

Checks all dependencies — direct and transitive — against OSV.dev. Works with pip, Poetry, pipenv, and conda.

Method 2: pip-audit

pip install pip-audit
pip-audit

Checks against the Python Packaging Advisory Database. Good for quick checks, but only checks direct dependencies well.

Method 3: Safety

pip install safety
safety check

Checks against the Safety database. Similar to pip-audit.

Why VulnLedger is better: It scans the full transitive tree, generates SBOMs, and provides CI/CD integration. The others are fine for quick checks but miss transitive vulnerabilities.

Fixing Vulnerable Dependencies

Step 1: Identify the Fix Version

vulnledger scan . | grep "fixed_version"

This shows which version to upgrade to.

Step 2: Check for Breaking Changes

Before upgrading, check the changelog:

# Check what changed
pip install --dry-run requests==2.31.0

# Read the changelog
# https://docs.python-requests.org/en/latest/changes/

Step 3: Upgrade

# Direct upgrade
pip install requests==2.31.0

# Upgrade all outdated packages
pip install --upgrade -r requirements.txt

# With Poetry
poetry update requests

# With pipenv
pipenv update requests

Step 4: Test

pytest

Always test after upgrading. Breaking changes can be subtle.

Step 5: Update Lock File

# Poetry
poetry lock

# Pip-tools
pip-compile requirements.in

Package Manager Specific Advice

pip + requirements.txt

# Pin exact versions
pip install requests==2.31.0 -r requirements.txt

# Use pip-tools for lock files
pip install pip-tools
pip-compile requirements.in  # Generates requirements.txt with hashes

Poetry

# Poetry automatically handles transitive deps
poetry update requests

# Lock file ensures reproducibility
poetry.lock  # Generated automatically

pipenv

# pipenv also handles transitive deps
pipenv update requests

# Lock file
Pipfile.lock  # Generated automatically

conda

# Update specific package
conda update requests -n myenv

# Update all
conda update --all -n myenv

Preventing Future Vulnerabilities

1. Pin Dependencies with Hashes

# requirements.txt
requests==2.31.0 --hash=sha256:abc123...

2. Use Lock Files

Lock files pin exact versions of ALL dependencies (direct + transitive). Never deploy without a lock file.

3. Add CI/CD Scanning

- name: Scan dependencies
  run: |
    pip install vulnledger
    vulnledger scan . --ci

4. Monitor for New CVEs

# Daily scan
vulnledger scan . --json --output daily.json

5. Review New Dependencies

Before adding a new dependency:

- Check its GitHub stars and last update date

- Scan it for CVEs: pip install vulnledger && vulnledger scan .

- Check its license

- Check its maintainer activity

Common Python Dependency Mistakes

Mistake 1: Not pinning versions

pip install requests installs the latest version, which may break tomorrow.

Mistake 2: Ignoring transitive dependencies

Your requirements.txt lists 10 packages. Those pull in 200+ transitive deps. Scan them all.

Mistake 3: Not using lock files

Without a lock file, different team members may install different versions.

Mistake 4: Running as root in Docker

Running pip as root in Docker containers can install malicious packages from compromised registries.

Mistake 5: Not scanning dev dependencies

Test frameworks and linters have CVEs too. Scan everything.

How VulnLedger Helps

VulnLedger provides complete Python dependency security:

1. Scans all package managers — pip, Poetry, pipenv, conda

2. Full transitive tree — not just direct dependencies

3. CI/CD integration — fails builds on critical CVEs

4. SBOM generation — compliance-ready dependency inventory

5. Continuous monitoring — catches new CVEs as they're published

pip install vulnledger
vulnledger scan .

Conclusion

Python dependency security is the most impactful thing you can do for your project's security. One scan catches dozens of vulnerabilities. One CI/CD gate prevents them from coming back. The tools are free, the process takes minutes.

Previous: Python Security Best Practices 2026

Next: Python Web App Security: Flask, FastAPI, Django

See also: Dependency Security: How to Scan and Fix Vulnerable Packages

Try VulnLedger

Generate SBOMs and scan for vulnerabilities in one command.

Start Free