All integrations

pip-audit Integration with DefectDojo

pip-audit Integration with DefectDojo

pip-audit is an open source tool that checks Python environments and requirements files for packages with known vulnerabilities. It was created by Trail of Bits with support from Google and is maintained under the Python Packaging Authority (PyPA). By default it queries the PyPI vulnerability data (backed by the Python Packaging Advisory Database), and it can use OSV instead. It prints a column view by default and can write JSON, CycloneDX, and Markdown output; DefectDojo imports the JSON.

pip-audit Integration with DefectDojo

We run pip-audit on every Python service because it is the PyPA-maintained answer to "which of our installed packages have known advisories," and it is easy to add to any pipeline. What it doesn't do is track anything. Importing its JSON into DefectDojo turns each advisory into a Finding on the service's Asset, with the package, version, and fix versions recorded. Rescans match existing Findings by advisory ID and package version, and a reimport after an upgrade closes what was fixed.

Why pip-audit Matters

Python applications often depend on dozens of packages directly and many more transitively, and advisories keep arriving against versions already in production.

  • It audits the environment you actually install, or a requirements file, so results reflect the resolved versions.
  • It is maintained by PyPA and uses PyPI's own vulnerability data by default, so coverage tracks the Python ecosystem closely.
  • Each result lists the versions that fix the advisory, which tells an engineer what to pin.
  • It runs anywhere Python runs, with no server or account.
  • A JSON file from last night's build can't say whether an advisory is new or overdue. That needs a system that keeps history.

Advantages of This Integration

What we get from routing pip-audit results through DefectDojo:

  • Precise deduplication. pip-audit findings hash on the advisory ID from the tool, component name, and component version, so each advisory on each package version is tracked once across rescans.
  • Fix versions in Mitigation. The parser writes pip-audit's fix_versions into the Mitigation field, so the assignee knows the target version without rerunning the tool.
  • Reimport lifecycle. Reimporting into the same Test mitigates advisories that disappeared after an upgrade, adds new ones, and reactivates any that return.
  • Ownership and SLAs. Findings can be assigned per service, risk-accepted with an expiration date when no fix is available, or pushed to Jira.
  • Searchable components. Package name and version are stored as component fields, so you can find every Asset running a given version across the Organization.

How This Integration Works

DefectDojo imports pip-audit results with the pip-audit Scan scan type. The parser accepts both the current JSON layout (with a top-level dependencies key) and the older layout (a plain list of packages), and detects which one it has.

1. Produce a JSON report. Audit a requirements file and write JSON to a file:

pip-audit -r requirements.txt -f json -o pip-audit.json

Or audit the current environment:

pip-audit -f json -o pip-audit.json

The JSON format includes vulnerability descriptions by default, which the parser uses for the Finding description. Leave --desc at its default (or set it to on) when producing reports for DefectDojo.

2. Import it. In the UI, open the Engagement, choose Import Scan Results, select pip-audit Scan, and upload the file. For automation, use the API, available in Community Edition and DefectDojo Pro:

curl "https://YOUR_INSTANCE/api/v2/import-scan/" \
  -H "Authorization: Token $DD_API_TOKEN" \
  -F "scan_type=pip-audit Scan" \
  -F "file=@pip-audit.json" \
  -F "product_name=data-pipeline" \
  -F "engagement_name=Dependency Scans" \
  -F "auto_create_context=true"

DefectDojo Pro users can run the same import with Universal Importer:

universal-importer import \
  --defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/" \
  --scan-type "pip-audit Scan" \
  --report-path "./pip-audit.json" \
  --product-name "data-pipeline" \
  --engagement-name "Dependency Scans" \
  --auto-create-context

3. Reimport on each build. Send later reports to /api/v2/reimport-scan/ against the same Test so the open list always reflects the current lock or requirements file.

Data Granularity: What Gets Imported

The parser creates one Finding per advisory per package. Packages with no vulnerabilities produce no Findings.

DefectDojo Field Source in pip-audit JSON Notes
Title Advisory id, package name, version Formatted as ID in package:version
Severity Not in report Every Finding is imported as Medium
Description Advisory description The advisory text
Mitigation Advisory fix_versions "Upgrade to version" followed by the fix versions; empty when none exist
Vulnerability IDs Advisory id Typically a PYSEC or GHSA ID; aliases such as CVE IDs aren't imported
Vuln ID from Tool Advisory id Used for deduplication
CWE Fixed at 1395 Dependency on Vulnerable Third-Party Component
Component Name / Version Package name and version As reported by pip-audit
Finding type Static All findings are static
Deduplication Hashcode Vuln ID from tool, component name, component version

pip-audit's skip reasons (for packages it couldn't audit) aren't imported as Findings.

Use Cases

In a CI/CD pipeline: Each build installs dependencies, runs pip-audit, and reimports the JSON into a Test per service. Developers see new advisories as soon as a dependency change lands, and older ones keep their original discovery date.

For data and ML platforms: Teams with many Python jobs and notebooks import each project's pip-audit report into its own Asset. Security leads get one view of vulnerable packages across the platform, grouped by owner.

When an advisory makes news: After a high-profile advisory in a widely used package, analysts search DefectDojo by component name to list every Asset on an affected version, then check Mitigation for the fixed release.

For release sign-off: Before a release, the team checks that no Findings on the service are past SLA, and that any advisories without a fix are risk-accepted with an expiration date.

Operational Tips

  • Set real severities during triage. Every pip-audit Finding arrives as Medium because the report carries no severity, so a Critical advisory and a minor one look the same until someone reviews them.
  • If you filter with minimum_severity, keep it at Medium or lower. A High threshold drops every pip-audit Finding.
  • Search by the PYSEC or GHSA ID shown in the title. CVE aliases aren't stored as vulnerability IDs, so a CVE search won't match unless the advisory ID is itself a CVE.
  • Audit the same input each time (one requirements or lock file per Test) and reimport into that Test, so mitigations reflect real upgrades and not a change of scope.
  • Risk-accept advisories with no fix_versions with an expiration date, so they return for review when a fix is likely.
  • Tag imports with the environment or requirements file (for example tags=prod-requirements) when one service has several dependency sets.