pypa/pip-audit
GitHub: pypa/pip-audit
PyPA 官方推出的 Python 依赖安全审计工具,用于扫描并自动修复环境与文件中的已知漏洞。
Stars: 1207 | Forks: 88
# pip-audit
[](https://github.com/pypa/pip-audit/actions/workflows/ci.yml)
[](https://pypi.org/project/pip-audit)
[](https://repology.org/project/python:pip-audit/versions)
[](https://api.securityscorecards.dev/projects/github.com/pypa/pip-audit)
[](https://github.com/pypa/pip-audit/blob/main/LICENSE)
`pip-audit` 是一个用于扫描 Python 环境中
已知漏洞包的工具。它通过
[PyPI JSON API](https://warehouse.pypa.io/api-reference/json.html) 使用
Python 包装咨询数据库
作为漏洞报告的来源。
本项目由 [Trail of Bits](https://www.trailofbits.com/) 在 Google 的支持下
维护。这不是 Google 或 Trail of Bits 的官方产品。
## 目录
* [功能](#features)
* [安装](#installation)
* [第三方包](#third-party-packages)
* [GitHub Actions](#github-actions)
* [`pre-commit` 支持](#pre-commit-support)
* [用法](#usage)
* [环境变量](#environment-variables)
* [退出代码](#exit-codes)
* [空运行](#dry-runs)
* [示例](#examples)
* [故障排除](#troubleshooting)
* [技巧与窍门](#tips-and-tricks)
* [安全模型](#security-model)
* [许可](#licensing)
* [贡献](#contributing)
* [行为准则](#code-of-conduct)
## 功能
* 支持审计本地环境和 requirements 风格的文件
* 支持多种漏洞服务
([PyPI](https://warehouse.pypa.io/api-reference/json.html#known-vulnerabilities),
[OSV](https://osv.dev/docs/))
* 支持以
[CycloneDX](https://cyclonedx.org/) XML 或 JSON 格式
生成 [SBOMs](https://en.wikipedia.org/wiki/Software_bill_of_materials)
* 支持自动修复有漏洞的依赖项 (`--fix`)
* 人类和机器可读的输出格式(列式、Markdown、JSON)
* 无缝复用现有的本地 `pip` 缓存
## 安装
`pip-audit` 需要 Python 3.10 或更高版本,可以直接通过 `pip` 安装:
```
python -m pip install pip-audit
```
### 第三方包
针对 `pip-audit` 有多种**第三方**包。下面的矩阵和徽章
列出了其中的一部分:
[](https://repology.org/project/python:pip-audit/versions)
[](https://repology.org/project/pip-audit/versions)
[][#conda-forge-package]
[][#conda-forge-package]
特别是,`pip-audit` 可以通过 `conda` 安装:
```
conda install -c conda-forge pip-audit
```
本项目**不**直接支持第三方包。请查阅您的包管理器
文档以获取更详细的安装指南。
### GitHub Actions
`pip-audit` 有[一个官方的 GitHub Action](https://github.com/pypa/gh-action-pip-audit)!
您可以从
[GitHub Marketplace](https://github.com/marketplace/actions/gh-action-pip-audit) 安装它,或者
手动将其添加到您的 CI 中:
```
jobs:
pip-audit:
steps:
- uses: pypa/gh-action-pip-audit@v1.1.0
with:
inputs: requirements.txt
```
有关更多详细信息和用法示例,请参阅
[action 文档](https://github.com/pypa/gh-action-pip-audit/blob/main/README.md)。
### `pre-commit` 支持
`pip-audit` 支持 [`pre-commit`](https://pre-commit.com/)。
例如,通过 `pre-commit` 使用 `pip-audit` 来审计 requirements 文件:
```
- repo: https://github.com/pypa/pip-audit
rev: v2.10.0
hooks:
- id: pip-audit
args: ["-r", "requirements.txt"]
ci:
# Leave pip-audit to only run locally and not in CI
# pre-commit.ci does not allow network calls
skip: [pip-audit]
```
可以传递下面记录的任何 `pip-audit` 参数。
## 用法
您可以将 `pip-audit` 作为独立程序运行,或通过 `python -m` 运行:
```
pip-audit --help
python -m pip_audit --help
```
```
usage: pip-audit [-h] [-V] [-l] [-r REQUIREMENT] [--locked] [-f FORMAT]
[-s SERVICE] [--osv-url OSV_URL] [-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)
options:
-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)
--locked audit lock files from the local Python project. This
flag only applies to auditing from project paths
(default: False)
-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, esms) (default: pypi)
--osv-url OSV_URL URL to use for the OSV API instead of the default
(default: https://api.osv.dev/v1/query)
-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)
```
### 环境变量
`pip-audit` 允许用户通过环境变量来配置某些
标志:
| 标志 | 环境变量等效项 | 示例 |
|---------------------------|-----------------------------------|---------------------------------------|
| `--format` | `PIP_AUDIT_FORMAT` | `PIP_AUDIT_FORMAT=markdown` |
| `--vulnerability-service` | `PIP_AUDIT_VULNERABILITY_SERVICE` | `PIP_AUDIT_VULNERABILITY_SERVICE=osv` |
| `--desc` | `PIP_AUDIT_DESC` | `PIP_AUDIT_DESC=off` |
| `--progress-spinner` | `PIP_AUDIT_PROGRESS_SPINNER` | `PIP_AUDIT_PROGRESS_SPINNER=off` |
| `--output` | `PIP_AUDIT_OUTPUT` | `PIP_AUDIT_OUTPUT=/tmp/example` |
### 退出代码
完成后,`pip-audit` 将以指示其状态的代码退出。
当前的代码有:
* `0`:未检测到已知漏洞。
* `1`:发现一个或多个已知漏洞。
`pip-audit` 的退出代码无法被抑制。
请参阅 [抑制 `pip-audit` 的退出代码](#suppressing-exit-codes-from-pip-audit)
以了解支持的替代方案。
### 空运行
`pip-audit` 支持 `--dry-run` 标志,可用于控制是否
实际执行审计(或修复)步骤。
* 单独使用时,`pip-audit --dry-run` 跳过审计步骤并打印
*本应被*审计的依赖项数量。
* 在修复模式下,`pip-audit --fix --dry-run` 执行审计步骤并
打印出*本应执行*的修复行为(即哪些依赖项会被升级或跳过)。
## 示例
审计当前 Python 环境的依赖项:
```
$ pip-audit
No known vulnerabilities found
```
审计给定 requirements 文件的依赖项:
```
$ pip-audit -r ./requirements.txt
No known vulnerabilities found
```
审计 requirements 文件的依赖项,排除系统包:
```
$ pip-audit -r ./requirements.txt -l
No known vulnerabilities found
```
审计本地 Python 项目的依赖项:
```
$ pip-audit .
No known vulnerabilities found
```
审计本地 Python 项目的 lockfiles:
```
$ pip-audit --locked .
No known vulnerabilities found
```
`pip-audit` 在提供的路径中搜索各种 Python “项目”文件。
目前,仅支持 `pyproject.toml` 和 `pylock.*.toml`。
审计存在漏洞时的依赖项:
```
$ 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.3
```
审计依赖项包括别名:
```
$ 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-xh97
```
审计依赖项包括描述:
```
$ 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.
```
以 JSON 格式审计依赖项:
```
$ 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": []
}
]
```
审计并尝试自动升级有漏洞的依赖项:
```
$ 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)
```
## 故障排除
您是否解决了 `pip-audit` 的问题?请帮助我们完善这一
部分!
### `pip-audit` 显示了不相关的漏洞报告!
在一个完美的世界里,漏洞源的信噪比将是无限的:每份漏洞报告都将 (1) 正确,且 (2) 适用于
每个依赖项的每次使用。
不幸的是,这两点都无法保证:漏洞源无法
免受无关或垃圾报告的影响,而且并非对特定
依赖项的所有使用都映射到所有潜在的漏洞类别。
如果您的 `pip-audit` 运行生成了对您的特定应用程序或用例
不可操作的漏洞报告,您可以使用 `--ignore-vuln ID`
选项来忽略特定的漏洞报告。`--ignore-vuln` 支持
别名,因此如果相关报告没有 PYSEC ID,
您可以使用 `GHSA-xxx` 或 `CVE-xxx` ID 代替 `PYSEC-xxx` ID。
例如,以下是您如何忽略 GHSA-w596-4wvx-j9j6,这是
[`pytest`](https://github.com/pytest-dev/pytest) 用户的常见噪音漏洞报告和误报来源:
```
# 正常运行 audit,但排除任何匹配 GHSA-w596-4wvx-j9j6 的报告
$ pip-audit --ignore-vuln GHSA-w596-4wvx-j9j6
```
`--ignore-vuln ID` 选项适用于所有其他依赖项解析
和审计选项,这意味着它应该在 requirements 风格的输入、
替代漏洞源等情况下正常工作。
它也可以多次传递,以忽略多个报告:
```
# 正常运行 audit,但排除任何匹配这些 ID 的报告
$ pip-audit --ignore-vuln CVE-XXX-YYYY --ignore-vuln CVE-ZZZ-AAAA
```
### `pip-audit` 花费的时间比预期的长!
根据您的使用方式,`pip-audit` 可能必须执行其
自己的依赖项解析,这可能需要大约与 `pip install`
对项目执行相同的时间。有关解释,请参阅[安全模型](#security-model)。
您有两个避免依赖项解析的选项:*审计预安装的
环境*,或*确保您的依赖项已完全解析*。
如果您知道您已经完全配置了一个等同于
`pip-audit -r requirements.txt` 将审计的环境,您可以简单地
复用它:
```
# 注意没有任何 "input" 参数,表明使用了环境。
$ pip-audit
# 可选择过滤掉非本地包,针对虚拟环境:
$ pip-audit --local
```
或者,如果您的输入已完全锁定(并且可选地经过哈希处理),您
可以使用 `--no-deps`
(无哈希锁定)或 `--require-hashes`(包括哈希锁定)告诉 `pip-audit` 跳过依赖项解析。
后者等效于 `pip` 的
[哈希检查模式](https://pip.pypa.io/en/stable/cli/pip_install/#hash-checking-mode)
并且是首选,因为它提供了额外的完整性。
```
# 如果任何 dependency 未完全固定,则失败
$ pip-audit --no-deps -r requirements.txt
# 如果任何 dependency 未完全固定 *或* 缺少 hashes,则失败
$ pip-audit --require-hashes -r requirements.txt
```
### `pip-audit` 无法验证我的第三方索引!
### 需要验证的第三方或私有索引
`pip-audit` 支持 `--index-url` 和 `--extra-index-url` 用于配置备用
或补充包索引,就像 `pip` 一样。
当*未经身份验证*时,这些索引应按预期工作。但是,当第三方
索引需要身份验证时,`pip-audit` 在普通
`pip` 之上有一些额外的限制:
* **不**支持交互式身份验证。换句话说:`pip-audit` **不会**
提示您输入索引的用户名/密码。
* **支持** [`pip` 的 `keyring` 身份验证](https://pip.pypa.io/en/stable/topics/authentication/#keyring-support),
但方式有限:`pip-audit` 使用 `subprocess` keyring 提供者,
因为审计发生在隔离的虚拟环境中。`subprocess` 提供者进而
受到额外的限制(例如必需的用户名);
[`pip` 的文档](https://pip.pypa.io/en/stable/topics/authentication/#using-keyring-as-a-command-line-application)
深入解释了这些内容。
除上述之外,某些第三方索引具有必需的硬编码用户名。
例如,对于 Google Artifact registry,硬编码用户名为 `oauth2accesstoken`。
有关更多背景信息,请参阅 [#742](https://github.com/pypa/pip-audit/issues/742) 和
[pip#11971](https://github.com/pypa/pip/issues/11971)。
## 技巧与窍门
### 针对 `pipenv` 项目运行
`pipenv` 使用 `Pipfile` 和 `Pipfile.lock` 文件来跟踪和冻结依赖项,
而不是 `requirements.txt` 文件。`pip-audit` 无法直接处理 `Pipfile[.lock]`
文件,但是,这些可以转换为 `pip-audit`
可以运行的受支持 `requirements.txt` 文件。`pipenv` 有一个内置命令将依赖项
转换为 `requirements.txt` 文件(自 [`v2022.4.8`](https://pipenv.pypa.io/en/latest/changelog/#id206) 起):
```
$ pipenv run pip-audit -r <(pipenv requirements)
```
### 抑制 `pip-audit` 的退出代码
`pip-audit` 故意不支持在内部抑制其自己的
退出代码。
需要抑制失败 `pip-audit` 调用的用户可以使用
标准的 shell 惯用语之一来这样做:
```
pip-audit || true
```
或者,完全退出:
```
pip-audit || exit 0
```
退出代码也可以被捕获并显式处理:
```
pip-audit
exitcode="${?}"
# 对 ${exitcode} 执行某些操作
```
有关需要处理的潜在代码列表,请参阅 [退出代码](#exit-codes)。
### 仅报告可修复的漏洞
在开发工作流中,您可能希望忽略尚未修复的漏洞,仅在发布流程中调查它们。`pip-audit` 不支持忽略未修复的漏洞。但是,您可以将其输出导出为 JSON 格式并进行外部处理。例如,如果您只想在检测到的漏洞具有已知修复版本时以非零代码退出,可以使用 [jq](https://github.com/jqlang/jq) 处理输出,如下所示:
```
test -z "$(pip-audit -r requirements.txt --format=json 2>/dev/null | jq '.dependencies[].vulns[].fix_versions[]')"
```
使用此方法的一个简单(且低效)示例是:
```
test -z "$(pip-audit -r requirements.txt --format=json 2>/dev/null | jq '.dependencies[].vulns[].fix_versions[]')" || pip-audit -r requirements.txt
```
它照常运行 `pip-audit`,并且仅在已知漏洞存在固定版本时才以非零代码退出。
## 安全模型
本节旨在描述您在使用 `pip-audit` 时**可以**和**绝不能**
做出的安全假设。
TL;DR:**如果您不会 `pip install` 它,您就不应该 `pip audit` 它。**
`pip-audit` 是一个用于审计 Python 环境中具有
*已知漏洞*包的工具。“已知漏洞”是包中公开报告的缺陷,
如果不加以纠正,*可能*允许恶意行为者执行
非预期的操作。
`pip-audit` **可以**通过告诉您何时存在已知漏洞以及应如何升级来保护您免受其害。例如,
如果您的环境中有 `somepackage==1.2.3`,`pip-audit` **可以**告诉
您需要将其升级到 `1.2.4`。
您**可以**假设 `pip-audit` 将尽最大努力*完全解析*
您的所有 Python 依赖项,并*要么*完全审计每一个,*要么*明确
说明跳过了哪些以及跳过的原由。
`pip-audit` **不是**静态代码分析器。它分析树,
而不是代码,并且它**无法**保证任意依赖项解析
静态发生。要理解为什么会这样,请参阅 Dustin Ingram 的
[关于 Python 依赖项解析的精彩文章](https://dustingram.com/articles/2018/03/05/why-pypi-doesnt-know-dependencies/)。
因此:您**绝不能**假设 `pip-audit` 会**防御**您免受
恶意包的侵害。特别是,将
`pip-audit -r INPUT` 视为 `pip-audit` 的“更安全”变体是**不正确的**。出于所有意图
和目的,`pip-audit -r INPUT` 在功能上等效于
`pip install -r INPUT`,只有少量的**非安全隔离**以
避免与您的任何本地环境发生冲突。
`pip-audit` 首先是 *Python* 包的审计工具。
您**绝不能**假设 `pip-audit` 将检测或标记可能
通过 Python 包暴露但实际
上不属于包本身的“传递”漏洞。例如,`pip-audit` 的漏洞
信息源不太可能包含对流行 Python 包*可能*
使用的易受攻击共享库的咨询,因为 Python 包的
版本与共享库的版本没有紧密联系。
## 许可
`pip-audit` 根据 Apache 2.0 许可证授权。
`pip-audit` 重用并修改了来自
[`resolvelib`](https://github.com/sarugaku/resolvelib) 的示例,后者根据
ISC 许可证授权。
## 贡献
有关详细信息,请参阅[贡献文档](CONTRIBUTING.md)。
## 行为准则
与本项目交互的每个人都应遵守
[PSF 行为准则](https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md)。
标签:DevSecOps, LLM防护, LNA, OSV, pip, PyPI, Python, requirements, Tremble, Vercel, 上游代理, 云安全监控, 依赖安全, 文档结构分析, 无后门, 自动修复, 软件开发工具包, 逆向工具, 静态分析