Package: pip-audit
pip-auditpip-auditis a tool for scanning Python environments for packages
with known vulnerabilities. It uses the Python Packaging Advisory Database
(https://github.com/pypa/advisory-database) via thePyPI JSON APIas a source
of vulnerability reports.This project is maintained in part byTrail of Bitswith support from Google. This is not an official Google or Trail of Bits product.IndexFeaturesInstallationThird-party packagesGitHub Actionspre-commitsupportUsageExit codesDry runsExamplesTroubleshootingTips and TricksSecurity modelLicensingContributingCode of ConductFeaturesSupport for auditing local environments and requirements-style filesSupport for multiple vulnerability services
(PyPI,OSV)Support for emittingSBOMsinCycloneDXXML or JSONSupport for automatically fixing vulnerable dependencies (--fix)Human and machine-readable output formats (columnar, Markdown, JSON)Seamlessly reuses your existing localpipcachesInstallationpip-auditrequires Python 3.8 or newer, and can be installed directly viapip:python-mpipinstallpip-auditThird-party packagesThere are multiplethird-partypackages forpip-audit. The matrices and badges below
list some of them:In particular,pip-auditcan be installed viaconda:condainstall-cconda-forgepip-auditThird-party packages arenotdirectly supported by this project. Please consult your package manager's
documentation for more detailed installation guidance.GitHub Actionspip-audithasan official GitHub Action!You can install it from theGitHub Marketplace, or
add it to your CI manually:jobs:pip-audit:steps:-uses:pypa/gh-action-pip-audit@v1.0.0with:inputs:requirements.txtSee theaction documentationfor more details and usage examples.pre-commitsupportpip-audithaspre-commitsupport.For example, usingpip-auditviapre-committo audit a requirements file:-repo:https://github.com/pypa/pip-auditrev:v2.7.1hooks:-id:pip-auditargs:["-r","requirements.txt"]ci:# Leave pip-audit to only run locally and not in CI# pre-commit.ci does not allow network callsskip:[pip-audit]Anypip-auditarguments documented below can be passed.UsageYou can runpip-auditas a standalone program, or viapython -m:pip-audit--help
python-mpip_audit--helpusage: pip-audit [-h] [-V] [-l] [-r REQUIREMENT] [-f FORMAT] [-s SERVICE] [-d]
                 [-S] [--desc [{on,off,auto}]] [--aliases [{on,off,auto}]]
                 [--cache-dir CACHE_DIR] [--progress-spinner {on,off}]
                 [--timeout TIMEOUT] [--path PATH] [-v] [--fix]
                 [--require-hashes] [--index-url INDEX_URL]
                 [--extra-index-url URL] [--skip-editable] [--no-deps]
                 [-o FILE] [--ignore-vuln ID] [--disable-pip]
                 [project_path]

audit the Python environment for dependencies with known vulnerabilities

positional arguments:
  project_path          audit a local Python project at the given path
                        (default: None)

optional arguments:
  -h, --help            show this help message and exit
  -V, --version         show program's version number and exit
  -l, --local           show only results for dependencies in the local
                        environment (default: False)
  -r REQUIREMENT, --requirement REQUIREMENT
                        audit the given requirements file; this option can be
                        used multiple times (default: None)
  -f FORMAT, --format FORMAT
                        the format to emit audit results in (choices: columns,
                        json, cyclonedx-json, cyclonedx-xml, markdown)
                        (default: columns)
  -s SERVICE, --vulnerability-service SERVICE
                        the vulnerability service to audit dependencies
                        against (choices: osv, pypi) (default: pypi)
  -d, --dry-run         without `--fix`: collect all dependencies but do not
                        perform the auditing step; with `--fix`: perform the
                        auditing step but do not perform any fixes (default:
                        False)
  -S, --strict          fail the entire audit if dependency collection fails
                        on any dependency (default: False)
  --desc [{on,off,auto}]
                        include a description for each vulnerability; `auto`
                        defaults to `on` for the `json` format. This flag has
                        no effect on the `cyclonedx-json` or `cyclonedx-xml`
                        formats. (default: auto)
  --aliases [{on,off,auto}]
                        includes alias IDs for each vulnerability; `auto`
                        defaults to `on` for the `json` format. This flag has
                        no effect on the `cyclonedx-json` or `cyclonedx-xml`
                        formats. (default: auto)
  --cache-dir CACHE_DIR
                        the directory to use as an HTTP cache for PyPI; uses
                        the `pip` HTTP cache by default (default: None)
  --progress-spinner {on,off}
                        display a progress spinner (default: on)
  --timeout TIMEOUT     set the socket timeout (default: 15)
  --path PATH           restrict to the specified installation path for
                        auditing packages; this option can be used multiple
                        times (default: [])
  -v, --verbose         run with additional debug logging; supply multiple
                        times to increase verbosity (default: 0)
  --fix                 automatically upgrade dependencies with known
                        vulnerabilities (default: False)
  --require-hashes      require a hash to check each requirement against, for
                        repeatable audits; this option is implied when any
                        package in a requirements file has a `--hash` option.
                        (default: False)
  --index-url INDEX_URL
                        base URL of the Python Package Index; this should
                        point to a repository compliant with PEP 503 (the
                        simple repository API); this will be resolved by pip
                        if not specified (default: None)
  --extra-index-url URL
                        extra URLs of package indexes to use in addition to
                        `--index-url`; should follow the same rules as
                        `--index-url` (default: [])
  --skip-editable       don't audit packages that are marked as editable
                        (default: False)
  --no-deps             don't perform any dependency resolution; requires all
                        requirements are pinned to an exact version (default:
                        False)
  -o FILE, --output FILE
                        output results to the given file (default: stdout)
  --ignore-vuln ID      ignore a specific vulnerability by its vulnerability
                        ID; this option can be used multiple times (default:
                        [])
  --disable-pip         don't use `pip` for dependency resolution; this can
                        only be used with hashed requirements files or if the
                        `--no-deps` flag has been provided (default: False)Exit codesOn completion,pip-auditwill exit with a code indicating its status.The current codes are:0: No known vulnerabilities were detected.1: One or more known vulnerabilities were found.pip-audit's exit code cannot be suppressed.
SeeSuppressing exit codes frompip-auditfor supported alternatives.Dry runspip-auditsupports the--dry-runflag, which can be used to control whether
an audit (or fix) step is actually performed.On its own,pip-audit --dry-runskips the auditing step and prints
the number of dependencies thatwould have beenaudited.In fix mode,pip-audit --fix --dry-runperforms the auditing step and prints
out the fix behavior (i.e., which dependencies would be upgraded or skipped)
thatwould have been performed.ExamplesAudit dependencies for the current Python environment:$ pip-audit
No known vulnerabilities foundAudit dependencies for a given requirements file:$ pip-audit -r ./requirements.txt
No known vulnerabilities foundAudit dependencies for a requirements file, excluding system packages:$ pip-audit -r ./requirements.txt -l
No known vulnerabilities foundAudit dependencies for a local Python project:$ pip-audit .
No known vulnerabilities foundpip-auditsearches the provided path for various Python "project" files. At the moment, onlypyproject.tomlis supported.Audit dependencies when there are vulnerabilities present:$ pip-audit
Found 2 known vulnerabilities in 1 package
Name  Version ID             Fix Versions
----  ------- -------------- ------------
Flask 0.5     PYSEC-2019-179 1.0
Flask 0.5     PYSEC-2018-66  0.12.3Audit dependencies including aliases:$ pip-audit --aliases
Found 2 known vulnerabilities in 1 package
Name  Version ID             Fix Versions Aliases
----  ------- -------------- ------------ -------------------------------------
Flask 0.5     PYSEC-2019-179 1.0          CVE-2019-1010083, GHSA-5wv5-4vpf-pj6m
Flask 0.5     PYSEC-2018-66  0.12.3       CVE-2018-1000656, GHSA-562c-5r94-xh97Audit dependencies including descriptions:$ pip-audit --desc
Found 2 known vulnerabilities in 1 package
Name  Version ID             Fix Versions Description
----  ------- -------------- ------------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Flask 0.5     PYSEC-2019-179 1.0          The Pallets Project Flask before 1.0 is affected by: unexpected memory usage. The impact is: denial of service. The attack vector is: crafted encoded JSON data. The fixed version is: 1. NOTE: this may overlap CVE-2018-1000656.
Flask 0.5     PYSEC-2018-66  0.12.3       The Pallets Project flask version Before 0.12.3 contains a CWE-20: Improper Input Validation vulnerability in flask that can result in Large amount of memory usage possibly leading to denial of service. This attack appear to be exploitable via Attacker provides JSON data in incorrect encoding. This vulnerability appears to have been fixed in 0.12.3. NOTE: this may overlap CVE-2019-1010083.Audit dependencies in JSON format:$ pip-audit -f json | python -m json.tool
Found 2 known vulnerabilities in 1 package
[
  {
    "name": "flask",
    "version": "0.5",
    "vulns": [
      {
        "id": "PYSEC-2019-179",
        "fix_versions": [
          "1.0"
        ],
        "aliases": [
          "CVE-2019-1010083",
          "GHSA-5wv5-4vpf-pj6m"
        ],
        "description": "The Pallets Project Flask before 1.0 is affected by: unexpected memory usage. The impact is: denial of service. The attack vector is: crafted encoded JSON data. The fixed version is: 1. NOTE: this may overlap CVE-2018-1000656."
      },
      {
        "id": "PYSEC-2018-66",
        "fix_versions": [
          "0.12.3"
        ],
        "aliases": [
          "CVE-2018-1000656",
          "GHSA-562c-5r94-xh97"
        ],
        "description": "The Pallets Project flask version Before 0.12.3 contains a CWE-20: Improper Input Validation vulnerability in flask that can result in Large amount of memory usage possibly leading to denial of service. This attack appear to be exploitable via Attacker provides JSON data in incorrect encoding. This vulnerability appears to have been fixed in 0.12.3. NOTE: this may overlap CVE-2019-1010083."
      }
    ]
  },
  {
    "name": "jinja2",
    "version": "3.0.2",
    "vulns": []
  },
  {
    "name": "pip",
    "version": "21.3.1",
    "vulns": []
  },
  {
    "name": "setuptools",
    "version": "57.4.0",
    "vulns": []
  },
  {
    "name": "werkzeug",
    "version": "2.0.2",
    "vulns": []
  },
  {
    "name": "markupsafe",
    "version": "2.0.1",
    "vulns": []
  }
]Audit and attempt to automatically upgrade vulnerable dependencies:$ pip-audit --fix
Found 2 known vulnerabilities in 1 package and fixed 2 vulnerabilities in 1 package
Name  Version ID             Fix Versions Applied Fix
----- ------- -------------- ------------ ----------------------------------------
flask 0.5     PYSEC-2019-179 1.0          Successfully upgraded flask (0.5 => 1.0)
flask 0.5     PYSEC-2018-66  0.12.3       Successfully upgraded flask (0.5 => 1.0)TroubleshootingHave you resolved a problem withpip-audit? Help us by contributing to this
section!pip-auditshows irrelevant vulnerability reports!In a perfect world, vulnerability feeds would have an infinite signal-to-noise
ratio: every vulnerability report would be (1) correct, and (2) applicable to
every use of every dependency.Unfortunately, neither of these is guaranteed: vulnerability feeds are not
immune to extraneous or spam reports, and not all uses of a particular
dependency map to all potential classes of vulnerabilities.If yourpip-auditruns produce vulnerability reports that aren't actionable
for your particular application or use case, you can use the--ignore-vuln IDoption to ignore specific vulnerability reports.--ignore-vulnsupports
aliases, so you can use aGHSA-xxxorCVE-xxxID instead of aPYSEC-xxxID if the report in question does not have a PYSEC ID.For example, here is how you might ignore GHSA-w596-4wvx-j9j6, which is a
common source of noisy vulnerability reports and false positives for users ofpytest:#Runtheauditasnormal,butexcludeanyreportsthatmatchGHSA-w596-4wvx-j9j6$pip-audit--ignore-vulnGHSA-w596-4wvx-j9j6The--ignore-vuln IDoption works with all other dependency resolution
and auditing options, meaning that it should function correctly with
requirements-style inputs, alternative vulnerability feeds, and so forth.It can also be passed multiple times, to ignore multiple reports:#Runtheauditasnormal,butexcludeanyreportsthatmatchtheseIDs$pip-audit--ignore-vulnCVE-XXX-YYYY--ignore-vulnCVE-ZZZ-AAAApip-audittakes longer than I expect!Depending on how you're using it,pip-auditmay have to perform its
own dependency resolution, which can take roughly as long aspip installdoes for a project. See thesecurity modelfor an explanation.You have two options for avoiding dependency resolution:audit a pre-installed
environment, orensure that your dependencies are already fully resolved.If you know that you've already fully configured an environment equivalent
to the one thatpip-audit -r requirements.txtwould audit, you can simply
reuse it:#Notetheabsenceofany"input"arguments,indicatingthattheenvironmentisused.$pip-audit#Optionallyfilteroutnon-localpackages,forvirtualenvironments:$pip-audit--localAlternatively, if your input is fully pinned (and optionally hashed), you
can tellpip-auditto skip dependency resolution with either--no-deps(pinned without hashes) or--require-hashes(pinned including hashes).The latter is equivalent topip'shash-checking modeand is preferred, since it offers additional integrity.#failsifanydependencyisnotfullypinned$pip-audit--no-deps-rrequirements.txt#failsifanydependencyisnotfullypinned*or*ismissinghashes$pip-audit--require-hashes-rrequirements.txtTips and TricksRunning against apipenvprojectpipenvuses both aPipfileandPipfile.lockfile to track and freeze dependencies
instead of arequirements.txtfile.pip-auditcannot process thePipfile[.lock]files directly, however, these can be converted to a supportedrequirements.txtfile
thatpip-auditcan run against.pipenvhas a built-in command to convert dependencies
to arequirements.txtfile (as ofv2022.4.8):$pipenvrunpip-audit-r<(pipenvrequirements)Suppressing exit codes frompip-auditpip-auditintentionally does not support internally suppressing its own
exit codes.Users who need to suppress a failingpip-auditinvocation can use
one of the standard shell idioms for doing so:pip-audit||trueor, to exit entirely:pip-audit||exit0The exit code can also be captured and handled explicitly:pip-auditexitcode="${?}"# do something with ${exitcode}SeeExit codesfor a list of potential codes that need handling.Reporting only fixable vulnerabilitiesIn development workflows, you may want to ignore the vulnerabilities that haven't been remediated yet and only investigate them in your release process.pip-auditdoes not support ignoring unfixed vulnerabilities. However, you can export its output in JSON format and externally process it. For example, if you want to exit with a non-zero code only when the detected vulnerabilities have known fix versions, you can process the output usingjqas:test-z"$(pip-audit-rrequirements.txt--format=json2>/dev/null|jq'.dependencies[].vulns[].fix_versions[]')"A simple (and inefficient) example of using this method would be:test-z"$(pip-audit-rrequirements.txt--format=json2>/dev/null|jq'.dependencies[].vulns[].fix_versions[]')"||pip-audit-rrequirements.txtwhich runspip-auditas usual and exits with a non-zero code only if there are fixed versions for the known vulnerabilities.Security ModelThis section exists to describe the security assumptions youcanandmust notmake when usingpip-audit.TL;DR:If you wouldn'tpip installit, you should notpip auditit.pip-auditis a tool for auditing Python environments for packages withknown vulnerabilities. A "known vulnerability" is a publicly reported flaw in
a package that, if uncorrected,mightallow a malicious actor to perform
unintended actions.pip-auditcanprotect you against known vulnerabilities by telling
you when you have them, and how you should upgrade them. For example,
if you havesomepackage==1.2.3in your environment,pip-auditcantell
you that it needs to be upgraded to1.2.4.Youcanassume thatpip-auditwill make a best effort tofully resolveall of your Python dependencies andeitherfully audit eachorexplicitly
state which ones it has skipped, as well as why it has skipped them.pip-auditisnota static code analyzer. It analyzes dependency trees,
not code, and itcannotguarantee that arbitrary dependency resolutions
occur statically. To understand why this is, refer to Dustin Ingram'sexcellent post on dependency resolution in Python.As such: youmust notassume thatpip-auditwilldefendyou against
malicious packages. In particular, it isincorrectto treatpip-audit -r INPUTas a "more secure" variant ofpip-audit. For all intents
and purposes,pip-audit -r INPUTis functionally equivalent topip install -r INPUT, with a small amount ofnon-security isolationto
avoid conflicts with any of your local environments.pip-auditis first and foremost a auditing tool forPythonpackages.
Youmust notassume thatpip-auditwill detect or flag "transitive"
vulnerabilities that might be exposed through Python packages, but are not
actually part of the package itself. For example,pip-audit's vulnerability
information sources are unlikely to include an advisory for a vulnerable shared
library that a popular Python packagemightuse, since the Python package's
version is not strongly connected to the shared library's version.Licensingpip-auditis licensed under the Apache 2.0 License.pip-auditreuses and modifies examples fromresolvelib, which is licensed under
the ISC license.ContributingSeethe contributing docsfor details.Code of ConductEveryone interacting with this project is expected to follow thePSF Code of Conduct.