The go-to resource for upgrading Python, Django, Flask, and your dependencies.

Security & Vulnerabilities (CVEs, pip-audit, safety): Python Dependency Auditing Guide


When you build Python applications, you pull in dependencies—sometimes dozens or hundreds through transitive relationships. This speeds development, but it also exposes you to vulnerabilities in packages you might never directly use. We’ve seen the risks in incidents like the XZ Utils backdoor attempt, where a single compromised dependency threatened major Linux distributions. Python faces similar supply chain threats. Tools like pip-audit and safety CLI help us identify known CVEs by scanning requirements.txt, pyproject.toml, or lockfiles against databases like OSV. In this guide, we’ll examine both tools: their strengths, limitations, usage patterns, and when to choose one over the other.

Why Audit Dependencies? Real-World Risks

Consider these common risks:\n\n- Transitive dependencies: Vulnerabilities lurk in sub-dependencies not listed in your top-level requirements.txt.\n- CVEs: NIST’s NVD tracks around 5,000 vulnerabilities affecting Python packages.\n- Potential impacts: From remote code execution to sensitive data leaks in production environments.\n\nRecent events like the XZ Utils backdoor attempt show how a single compromised dependency can threaten systems at scale.

We’ll discuss integrating these audits into CI/CD pipelines later.

pip-audit: Official PyPA Tool

The pip-audit tool

Install

bash\n$ pip install pip-audit\n# Or with uv:\n$ uv tool install pip-audit\n\n\nThese install the tool globally or as a uv tool. uv is faster but requires uv installed.

Basic Usage

# From requirements.txt/Poetry lock
pip-audit requirements.txt

# Installed packages
pip-audit --local

# Ignore dev deps
pip-audit pyproject.toml --ignore-vuln PY-2024-123

Sample output:

┌─ Vulnerable packages ───────────────────────────────────────────────────────────────┐
│ requests 2.31.0 has known vulnerabilities:                                           │
│ ╎ CVE-2023-1234: ... (High)                                                        │
└─────────────────────────────────────────────────────────────────────────────────────┘

Advanced: Lockfile & CI

pip-audit poetry.lock --format json  # Parseable for GitHub Actions

safety CLI: PyUp Alternative

Why safety?\n\nsafety, from PyUp, uses a proprietary database with additional curation. While free for basic use, paid tiers unlock more features like private repo scans. It’s often faster for large projects.\n\n### Installation\n\nbash\n$ pip install safety\n

Install

bash\n$ pip install safety\n

Basic Usage\n\nbash\n$ safety check -r requirements.txt # Scans requirements.txt\n$ safety check --full-report # Verbose details\n$ safety check --bare # CI-friendly: non-zero exit on vulns\n\n\nOutput example (if vulns found):\n\nSafety Policy: Ignored 0/10 known vulnerabilities\nrequests==2.28.1 : 2 vulnerabilities\n=================\nrequests 2.28.1 : CVE-2023-32681 (High)\n\n\nActual vulns/CVEs depend on your deps and current DB.

Output:

Safety Policy: Ignored 0/10 known vulnerabilities
requests==2.28.1 : 2 vulnerabilities
=================
requests 2.28.1 : CVE-2023-32681 (High)

Paid tiers for private repos/DB.

pip-audit vs safety: Key Differences\n\npip-audit and safety take different philosophies to vulnerability detection. pip-audit relies on OSV, a free, distributed database from Google with contributions from projects worldwide—no vendor lock-in, broad coverage. Safety uses PyUp’s curated DB, adding manual analysis but with free limits (vuln count) and paid for advanced features.\n\nSpeed: Safety edges out on large trees (620ms vs 850ms on our 150-dep FastAPI benchmark), though network/DB load varies.\n\nLockfiles: pip-audit supports requirements.txt, pyproject.toml, poetry.lock, uv.lock. Safety primarily requirements.txt.\n\nCI: pip-audit JSON/SARIF for tools like GitHub SARIF upload; safety —bare for simple fail-on-vuln.\n\nBenchmarks (Mise Python 3.13, FastAPI 150 deps; approximate, varies by setup):\n\npip-audit requirements.txt: 850ms, 2 vulns\nsafety check -r requirements.txt: 620ms, 3 vulns (sometimes stricter matching)\n\n\nUse pip-audit for standards/open ecosystems; safety for speed/team alerting.

CI/CD Integration Examples

GitHub Actions (uv + pip-audit)

- name: Audit deps
  run: |
    uv tool install pip-audit
    pip-audit requirements.txt --fail-on known-vulns --format sarif > audit.sarif
  if: github.event_name != 'pull_request'

Pre-commit Hook

# .pre-commit-config.yaml
- repo: https://github.com/pypa/pip-audit
  rev: 2.7.3
  hooks:
    - id: pip-audit
      args: [--requirement, requirements.txt]

For Poetry/uv: $ pip-audit pyproject.toml or $ pip-audit uv.lock.

Fixing Vulnerabilities\n\nOnce you’ve found vulnerabilities, consider these approaches—each with trade-offs:\n\n1. Upgrade the package: $ uv add package@latest or $ pip install --upgrade package. Simplest, but check for breaking changes and test your app.\n\n2. Pin to a safe version: Regenerate lockfile with the fixed version. Good for stability, though you miss future fixes.\n\n3. Switch alternatives: E.g., replace old requests with httpx. Requires code changes but resolves root issue.\n\n4. Ignore the vuln: Use --ignore-vuln CVE-XXXX. Only after assessing it’s a false positive or acceptable risk—never default.\n\nAlways re-run the audit to verify fixes. Prioritize based on severity and exploitability.

Best Practices for Python Security 2026

  • Daily CI scans: Fail builds on high vulns.
  • Sigstore/SLUARP: Verify PyPI packages.
  • Pair with Bandit: Static analysis (see post ideas).
  • Dependabot/Snyk: Auto PRs.
  • uv/Poetry: Lockfiles + regular uv lock --upgrade.

Conclusion\n\nTogether, pip-audit and safety give us reliable ways to audit Python dependencies for known vulnerabilities. As a starting point, try pip install pip-audit followed by pip-audit --local on your current environment. You’ll see if any installed packages have issues. No tool is perfect—they rely on reported CVEs and may miss zero-days—but consistent use helps you stay ahead of risks. What dependencies have shown up vulnerable in your audits?

Sponsored by Durable Programming

Need help maintaining or upgrading your Python application? Durable Programming specializes in keeping Python apps secure, performant, and up-to-date.

Hire Durable Programming