Safety仅扫描requirements.txt中的直接依赖,不递归分析子依赖或锁定文件,也不检测逻辑漏洞;需加--full-report才显示CVE编号等完整信息。

Safety 能快速识别已知漏洞,但只扫描 requirements.txt 中的直接依赖,不会递归分析子依赖或锁定文件(如 Pipfile.lock 或 poetry.lock),也不检测逻辑类漏洞。
安装与基础扫描:别跳过 --full-report
直接运行 safety check 只会输出简略结果,漏掉关键信息(如受影响版本范围、CVE 编号)。必须加 --full-report 才能看到完整上下文:
-
pip install safety(建议用虚拟环境隔离) safety check -r requirements.txt --full-report- 若项目用
pyproject.toml但没生成requirements.txt,先用pipreqs . --force生成(注意:pipreqs不解析pyproject.toml的依赖声明,仅基于 import 推断)
理解输出里的“insecure”和“unpinned”区别
safety 报告中两类风险常被混淆:
-
insecure:该包版本明确在 CVE 数据库中标记为存在已知漏洞(如Django 存在 CVE-2023-43665) -
unpinned:版本未锁定(如requests而非requests==2.31.0),可能导致 CI/CD 环境拉取到含漏洞的新版 ——safety默认不报此问题,需额外加--ignore-unpinned开启检查 - 注意:
safety的 CVE 数据源是 safety-db,非 NVD 实时同步,更新有延迟;高危漏洞通常几小时内收录,低危可能滞后数天
CI/CD 中集成:避免因网络或缓存导致误报
在 GitHub Actions 或 GitLab CI 里调用 safety 时,常见失败不是因为漏洞,而是环境问题:
立即学习“Python免费学习笔记(深入)”;
- 默认使用在线数据库,CI 环境若无外网访问权限,会报
ConnectionError—— 改用离线模式:safety check -r requirements.txt --db https://raw.githubusercontent.com/pyupio/safety-db/master/data/insecure.json - 本地开发机缓存过期(
~/.cache/safety)可能让safety check返回旧结果,CI 中应加--cache-clear - 扫描结果为非零退出码(如发现漏洞)会中断 pipeline,需用
|| true捕获或配置fail-on-severity(如--fail-on=CRITICAL)精准控制中断条件
它不能替代什么:三个典型盲区
safety 是轻量级守门员,不是全能安全审计工具:
- 不分析源码 —— 无法发现你自定义的 SQL 拼接、硬编码密钥、反序列化滥用等
- 不处理动态加载的包 —— 如用
importlib.import_module(os.environ.get("PLUGIN"))加载的模块,不会出现在requirements.txt中,safety完全不可见 - 对可选依赖(extras)静默忽略 ——
requests[security]中的pyOpenSSL不会被展开扫描,需手动提取 extras 并单独检查
真正要覆盖完整依赖链,得配合 pipdeptree --reverse --packages xxx 手动展开,再逐个喂给 safety;或者换用支持 lockfile 解析的工具(如 pip-audit)。


















