Audit a Python project's installed dependencies for known CVEs by wrapping pip-audit (PyPA's official vulnerability auditor) and emitting findings in the canonical penetration-tester schema. Detects vulnerable direct AND transitive packages, normalizes pip-audit's severity output via OSV severity bands, falls back to pip list --outdated when pip-audit isn't installed, and supports requirements.txt, pyproject.toml (PEP 621), Pipfile.lock, and poetry.lock as input sources. Use when: pre-merge g...
Scanned 9/2/2026
Install to Claude Code
npx -y skills add jeremylongshore/tons-of-skills-marketplace --skill auditing-python-dependencies --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Auditing Python Dependencies?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/jeremylongshore-auditing-python-dependencies)More formats (shields.io, HTML) on the badges page.
---
name: auditing-python-dependencies
description: |
Audit a Python project's installed dependencies for known CVEs by
wrapping pip-audit (PyPA's official vulnerability auditor) and
emitting findings in the canonical penetration-tester schema.
Detects vulnerable direct AND transitive packages, normalizes
pip-audit's severity output via OSV severity bands, falls back to
pip list --outdated when pip-audit isn't installed, and supports
requirements.txt, pyproject.toml (PEP 621), Pipfile.lock, and
poetry.lock as input sources.
Use when: pre-merge gate on a Python project, post-incident sweep
after a PyPI compromise (e.g. ctx, request-toolbelt typosquats,
ultralytics 8.3.42 compromise), SOC2 evidence collection, or
inheriting an unfamiliar Python codebase.
Threshold: any HIGH or CRITICAL CVE in the resolved dependency
tree. MODERATE / LOW reported informationally.
Trigger with: "audit python deps", "pip vulnerability scan",
"check pypi packages for CVEs", "pip-audit run".
allowed-tools:
- Read
- Bash(pip:*)
- Bash(pip-audit:*)
- Bash(python3:*)
- Glob
disallowed-tools:
- Bash(rm:*)
- Bash(curl:*)
- Bash(wget:*)
- Write(.env)
- Edit(.env)
- Bash(pip install:*)
- Bash(pip uninstall:*)
version: 3.30.0
author: Jeremy Longshore <jeremy@intentsolutions.io>
license: MIT
compatibility: Designed for Claude Code
tags:
- security
- dependency-audit
- python
- pypi
- cve
- pentest
---
# Auditing Python Dependencies
## Overview
PyPI hosts north of 500,000 packages, with several thousand new
releases every day. The package-install model is identical to npm in
the relevant ways: a `pip install` resolves a transitive graph,
runs each package's `setup.py` (which executes arbitrary Python at
install time), and writes the result to your site-packages. The CVE
attack surface is therefore the same shape: known vulnerabilities,
maintainer-account takeovers, typosquats, and protestware.
The PyPA-blessed auditor is `pip-audit`. It queries the Open Source
Vulnerabilities (OSV) database (which mirrors PyPA's advisory feed
plus aggregated CVE / GHSA records) and reports per-package
vulnerable versions. `pip-audit` integrates with `requirements.txt`,
`pyproject.toml`, `Pipfile.lock`, and `poetry.lock`, so most Python
project layouts are first-class.
This skill wraps `pip-audit`, normalizes its severity vocabulary to
the shared `Severity` enum, and emits Findings in the canonical
penetration-tester schema. If `pip-audit` isn't installed on the
host, the skill falls back to `pip list --outdated` and emits
INFO-level findings recommending the operator install pip-audit
for accurate vulnerability detection.
## When the skill produces findings
| Finding | Severity | Threshold | Affected control |
|---|---|---|---|
| Critical CVE in installed package | **CRITICAL** | OSV severity band corresponds to CVSS ≥ 9.0 | CWE-1104 |
| High CVE in installed package | **HIGH** | OSV severity band corresponds to CVSS 7.0–8.9 | CWE-1104 |
| Medium CVE in installed package | **MEDIUM** | OSV severity band corresponds to CVSS 4.0–6.9 | CWE-1104 |
| Low CVE in installed package | **LOW** | OSV severity band corresponds to CVSS 0.1–3.9 | CWE-1104 |
| Vulnerable package with no patch | **HIGH** | finding has no `fix_versions` and severity ≥ medium | CWE-1395 |
| Outdated package (no CVE) | **INFO** | pip list --outdated reports a newer version | (operational) |
| pip-audit not installed | **INFO** | binary not on PATH; scanner fell back to pip list | (operational) |
| Audit DB unreachable | **INFO** | pip-audit network error reaching OSV | (operational) |
OSV is the upstream of record. pip-audit also consults the PyPA
advisory database for Python-specific records that may not yet have
a CVE assigned.
## Prerequisites
- Python 3.9+
- `pip-audit` installed (`pip install pip-audit`); skill falls back
to `pip list --outdated` if absent
- Target project containing at minimum one of: `requirements.txt`,
`pyproject.toml`, `Pipfile.lock`, `poetry.lock`
- Network access to OSV (`api.osv.dev`) and PyPI (`pypi.org`)
## Instructions
### Step 1 — Identify the scan target
Locate the project directory. The scanner auto-detects requirement
files in order of preference:
1. `poetry.lock` (most precise — exact resolved tree)
2. `Pipfile.lock`
3. `requirements.txt` (and `requirements-*.txt` siblings)
4. `pyproject.toml` (PEP 621 dependencies)
5. Installed environment via `pip list` (last resort)
### Step 2 — Run the audit
```bash
python3 ./scripts/audit_python.py /path/to/python-project
```
Options:
```
Usage: audit_python.py PATH [OPTIONS]
Options:
--output FILE Write findings to FILE (default: stdout)
--format FMT json | jsonl | markdown (default: markdown)
--min-severity SEV (default: info)
--requirement FILE Override auto-detection; specify a particular
requirements file (repeatable)
--include-dev Include development dependencies (default: prod
only when project layout allows the distinction)
--strict Treat pip-audit warnings as errors
```
### Step 3 — Interpret findings
CRITICAL / HIGH = block release.
MEDIUM / LOW = track but don't block; many Python advisories report
edge-case theoretical issues that don't apply to your usage.
INFO = log only; e.g. "outdated but no known CVE" is information for
your release cadence, not a security action.
### Step 4 — Remediation
For a vulnerable package with `fix_versions`:
1. Bump the version pin in your requirements file:
```diff
- requests==2.20.0
+ requests==2.31.0
```
2. Run `pip install -r requirements.txt --upgrade` (or
`poetry lock --no-update && poetry update <pkg>`).
3. Run the test suite. CVE fixes occasionally include behavioral
changes you didn't expect.
4. Commit the lock file diff alongside the requirements bump.
For a vulnerable transitive dep (one you didn't declare directly):
1. Find the parent: `pip show <vulnerable-package>` lists the parents
in its "Required-by" line.
2. Check whether bumping the parent picks up the fix. `pip index
versions <parent>` lists available versions.
3. If parent doesn't have a newer release that floors the vulnerable
dep above the fix version, pin the transitive dep yourself in
your requirements file. pip will use the more specific pin.
For a vulnerable package with NO fix available:
1. Subscribe to PyPA advisory notifications for that package.
2. If the vulnerability is exploitable in your usage, either
replace the package or vendor + patch locally.
3. Document the exception in your security register with a
re-evaluation date.
## Examples
### Example 1 — Pre-merge gate
```bash
python3 ./scripts/audit_python.py . --min-severity high --format json --output audit.json
jq -e '. == []' audit.json || { echo "High/critical Python CVE — fix before merge"; exit 1; }
```
### Example 2 — CI scan on every push
```yaml
- name: pip-audit
run: pip install pip-audit
- name: Run audit
run: |
python3 plugins/security/penetration-tester/skills/auditing-python-dependencies/scripts/audit_python.py \
. --min-severity high --format markdown --output py-audit.md
```
### Example 3 — SOC2 evidence collection
```bash
mkdir -p evidence/CC7/
python3 ./scripts/audit_python.py . --include-dev --format json \
--output evidence/CC7/py-audit-$(date +%Y%m%d).json
```
`--include-dev` for SOC2: include dev/test deps so auditors see the
full surface, not just production.
## Output
JSON / JSONL / Markdown per `lib/report.py`. Exit codes: 0 clean, 1
high/critical, 2 error.
Each Finding includes:
- `id` — synthesized as `pypi-audit::<cve-id>` (or `pypi-audit::<ghsa>` / `pypi-audit::<pypa-id>` when no CVE)
- `severity` — CRITICAL / HIGH / MEDIUM / LOW / INFO
- `category` — `dependency-vulnerability`
- `summary` — short CVE / GHSA title
- `evidence` — affected package, affected version, fix versions, advisory ID
- `references` — OSV URL, CVE URL, PyPA advisory URL
## Error Handling
- **pip-audit not installed** → falls back to `pip list --outdated`,
emits an INFO Finding flagging the degraded scan, and proceeds.
- **No requirement file found** → emits an INFO Finding "no Python
project structure recognized" and exits 2.
- **OSV API unreachable** → emits an INFO Finding documenting the
outage and exits 0 (no actionable security finding).
- **pip-audit returns malformed JSON** → emits an INFO Finding with
the raw output truncated to 500 chars and exits 2.
## Resources
- `references/THEORY.md` — PyPI supply-chain history, OSV vs NVD vs
PyPA advisory scopes, why ecosystem-specific severity matters,
Python-specific install-time risks (setup.py execution, eager
dependency resolution), pip-audit vs Safety vs Snyk trade-offs
- `references/PLAYBOOK.md` — Per-toolchain remediation patterns
(pip + requirements.txt, poetry, pipenv, uv, conda), monorepo /
workspace scanning, override-equivalent patterns in Python
ecosystem, GitHub Dependabot ecosystem mapping, SOC2 evidence
retention
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!