Composer audit 命令仅从 Packagist 的 Advisory Database 检查已知 CVE,需 Composer 2.5.0+、完整 vendor/ 和 composer.lock,不支持第三方漏洞库、私有包及运行时环境判断,故“无输出”不等于安全。

Composer 自带的 audit 命令能快速发现已安装依赖中的已知安全漏洞,但默认不启用,且仅支持 Packagist 官方 CVE 数据源 —— 想靠它覆盖全部风险,必须配合其他手段。
为什么 composer audit 有时没输出或显示 “No vulnerabilities found”
这不是没漏洞,而是当前环境不满足审计触发条件:
-
composer audit从 Composer 2.5.0+ 才正式引入,旧版本运行会报Command "audit" is not defined - 项目必须已执行过
composer install或composer update,生成完整的vendor/和composer.lock,否则找不到已安装包版本 - 它只比对 Composer Advisory Database(由 Packagist 维护的公开 CVE 汇总),不连接 OSV、GitHub Security Advisories 等第三方库
- 若包未在该数据库中被收录(比如私有包、新披露未同步的漏洞),结果就是“无漏洞”—— 实际可能高危
composer audit 的常用参数和真实效果差异
它不是全量扫描工具,参数设计偏向 CI/CD 快速反馈,而非深度检测:
-
composer audit --format=json:输出结构化 JSON,适合脚本解析;但字段极简,只有advisory、package、version,不含 CVSS 分数或修复建议 -
composer audit --no-dev:跳过require-dev中的包,适合生产环境检查;但如果你的测试工具链(如phpunit)本身有反序列化漏洞,就会漏掉 -
composer audit --locked:强制只读composer.lock,不重新解析依赖树;速度快,但无法识别因版本约束宽松导致的“可升级但未升级”类风险(例如"monolog/monolog": "^2.0"锁在 2.3.5,而 2.10.0 才修复某漏洞)
如何让 composer audit 发挥更大作用
单靠它不够,但可以作为第一道轻量防线,关键在于补足盲区:
- 每天定时执行
composer audit --no-dev --format=json | jq 'length > 0'做 CI 失败门禁,比人工检查更可靠 - 用
composer show --outdated --direct手动查出可更新的直系依赖,再对照 Symfony Security Checker 或 Roave SecurityAdvisories(已归档,但数据仍可用)交叉验证 - 私有包必须自己维护 advisory 清单,并通过自定义脚本注入到审计流程中 ——
composer audit不支持本地 advisory 文件 - 注意 PHP 版本兼容性:某些漏洞只影响 PHP 8.1+,而
composer audit不做运行时环境判断,需人工核对
真正棘手的不是命令怎么跑,而是它查不到的那部分:未公开漏洞、配置型风险(如 symfony/framework-bundle 开启了不安全的 debug 模式)、以及你 fork 后改过的包 —— 这些得靠代码审计、运行时监控和最小权限原则来兜底。










