pip-audit是ci中最实用的依赖扫描工具,因其由pypa官方维护、直连nvd和pypi safety db、原生支持多种依赖文件格式且输出适合ci解析。

直接在 CI 流水线里跑 pip-audit 就能捕获绝大多数已知 Python 依赖漏洞,但默认行为不阻断构建,必须显式配置失败策略。
为什么 pip-audit 是 CI 中最实用的依赖扫描工具
它由 PyPA 官方维护,数据源直连 NVD 和 PyPI Safety DB,不依赖第三方商业服务;支持 requirements.txt 和 pyproject.toml,无需额外解析逻辑;命令行输出结构清晰,适合 CI 环境解析。相比 safety,pip-audit 对锁文件(如 poetry.lock)支持更稳定,且不会因 pyup.io 数据库临时不可用而中断流水线。
常见错误现象:pip-audit -r requirements.txt 在本地报出多个 CVE,但在 CI 中静默通过——这是因为默认只打印警告,不返回非零退出码。
- 必须加
--exit-code参数才能让有漏洞时进程退出码为 1,触发 CI 阶段失败 - 若项目用
pip-tools生成requirements.txt,需确保生成时已锁定所有传递依赖(即使用--generate-hashes),否则pip-audit可能漏检间接依赖漏洞 - 不推荐在 CI 中使用
--fix自动升级:它只改requirements.txt,不更新 lock 文件或验证兼容性,容易导致后续构建失败
GitHub Actions 中嵌入扫描的最小可行配置
关键不是“能不能跑”,而是“怎么让失败真正生效”。以下片段来自生产环境验证过的 .github/workflows/security.yml:
name: Dependency Audit
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install pip-audit
run: pip install pip-audit
- name: Audit dependencies
run: pip-audit --require-hashes --exit-code 1 -r requirements.txt
# ⚠️ 注意:--require-hashes 强制校验哈希,防篡改;--exit-code 1 表示任意漏洞即失败
使用场景:该 job 可独立运行,也可合并在主 CI 流水线中作为早期 gate。若项目使用 Poetry,应替换为 poetry export -f requirements.txt --without-hashes | pip-audit --exit-code 1 --stdin,避免导出时丢失版本约束。
容易被忽略的三个兼容性细节
很多团队扫出漏洞却修不动,问题常卡在环境一致性上:
-
pip-audit检查的是已安装包的元数据,不是requirements.txt文本。如果 CI 中先pip install -r requirements.txt再扫描,可能因网络波动装了新版(比如requests装了 2.32.0 而非要求的 2.31.0),导致扫描结果和本地不一致 - Python 3.9+ 的
venv默认启用seed=True,会预装pip和setuptools,但这两个包自身也可能有 CVE。建议显式添加pip-audit -p pip -p setuptools单独检查 - 某些企业内网禁用外部数据库访问,
pip-audit会卡在连接 NVD。此时应提前下载离线数据库快照(用pip-audit --download-db),并在 CI 中通过--db指向本地路径
真正的难点不在扫描本身,而在于如何让“发现漏洞”和“修复落地”形成闭环:CI 报错后,开发者需要快速知道该升哪个包、升到哪版、是否破坏 API。这要求扫描工具输出必须能映射到具体依赖路径,而不是只给一个 CVE 编号。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











