pip-audit 是最准、最轻、最贴近真实运行态的依赖漏洞检测方式,因其直接扫描 site-packages 中实际安装的包版本,覆盖手动安装、git+、本地路径等场景,且对接 PyPI 和 GitHub 官方漏洞数据,响应更快。

直接用 pip-audit 扫当前环境,是最准、最轻、最贴近真实运行态的检测方式——它不看 requirements.txt 里写了什么,而是查 site-packages 里实际装了什么版本,连手动 pip install --force-reinstall 或 git+https 安装导致的偏差都能捕获。
为什么优先跑 pip-audit 而不是 safety
safety 只读 requirements.txt,且跳过 -e git+、本地路径、PEP 508 动态表达式(如 requests; platform_system == "Linux")等非标准声明;而 pip-audit 直接遍历已安装包,覆盖所有现场状态。更关键的是:safety 免费版依赖 PyUp 数据库,CVE 更新有数小时至一天延迟;pip-audit 默认对接 PyPI 官方漏洞 API 和 GitHub Advisory,响应更快。
- 如果你在 CI 中只扫
requirements.txt,但部署时用了--no-deps或手动升级过某个包,safety就完全漏掉了 -
pip-audit不支持跳过特定包,但你可以用--skip显式忽略(例如--skip urllib3),比safety --ignore更明确 -
pip-audit默认不递归查间接依赖,加--descend才会进子依赖层——多数场景不需要,开了反而慢、误报多
pip-audit -r requirements.txt 的适用场景和陷阱
这个命令适合“预发布检查”或“锁版本前验证”,但它本质是模拟安装行为,而非真实环境扫描。它会解析 requirements.txt 中的每个条目,尝试匹配 PyPI 上可安装的版本,再查 CVE —— 这意味着:
- 若某行是
-e ./mylocalpkg,pip-audit直接跳过,不会报错也不会警告 - 若某行带哈希(
--hash=sha256:...),它仍能识别包名和版本,但不会校验哈希本身是否被篡改 - 遇到
pip-tools生成的带注释的requirements.txt(如# via django),它照样能提取出包名,不影响扫描
CI/CD 中怎么集成才不掉坑
别只跑一次就完事。真实流水线里要分两层:先用 pip-audit -r requirements.txt --dry-run 检查声明是否安全,再在部署镜像构建阶段运行 pip-audit(无参数)确认最终环境干净。
立即学习“Python免费学习笔记(深入)”;
- 加
--require-hashes会让pip-audit拒绝扫描不含哈希的requirements.txt,强制你锁定依赖,适合高安全要求场景 - 输出 JSON 后别手写解析:用
jq '.vulnerabilities | length > 0'判断是否有漏洞,避免字符串匹配失效 - CI 中如果用多 Python 版本测试,每个环境都得单独跑
pip-audit—— CVE 可能只影响特定 Python 子版本(如 PYSEC-2024-192 仅限 3.11.7)
真正容易被忽略的点是:pip-audit 查不到你自己代码里对危险函数的误用(比如用 pickle.loads() 解析用户输入),也看不到包里硬编码的恶意域名或反调试逻辑。它只管“已知 CVE”,不管“行为异常”。所以它必须和 bandit 配合使用,一个守外(依赖),一个守内(代码)。


















