composer audit 是当前最直接、最轻量的依赖漏洞扫描方式,但需 Composer ≥ 2.5.0、启用实验配置、存在有效的 composer.lock 文件,并配合 --with-dev 等参数才能准确生效。

composer audit 是当前最直接、最轻量的依赖漏洞扫描方式,但它不是万能的——用错版本、缺 composer.lock、忽略 --with-dev,都会让扫描结果完全失效。
确认 Composer 版本并启用 audit 功能
命令 composer audit 仅在 Composer ≥ 2.5.0 中可用,且默认禁用。运行前必须验证两件事:
- 执行
composer --version,确保输出类似Composer version 2.5.12;若为2.4.x或更低,直接执行composer self-update - 即使版本达标,仍需手动开启实验特性:
composer config --global experimental.audit true,该配置写入~/.composer/auth.json,不干扰项目级设置 - 运行
composer list | grep audit,有输出才代表真正就绪;若无,别折腾插件或旧版安全检查器(如已废弃的roave/security-advisories)
必须有 composer.lock 才能扫描
composer audit 不读 composer.json,只校验 composer.lock 中记录的**实际安装版本**。常见失效场景包括:
- CI 流程中跳过
composer install,直接跑audit→ 报错Could not find composer.lock - 本地改了
composer.json但没执行composer install或没提交更新后的composer.lock→ 扫描结果和线上环境脱节 - 用了
--no-install或--dry-run后再执行audit→lock文件未生成或未更新 - 稳妥做法:CI 中先确保
composer install --no-interaction --no-progress成功,再执行audit
让 audit 输出真正可操作的结果
默认输出只有包名和严重等级,修复时还得查哪个版本修复了漏洞。加几个参数立刻提升实用性:
-
composer audit --fixed:显示每个漏洞对应的“最小修复版本”,例如"fixed":"5.4.22",直接指导升级目标 -
composer audit --format=json:结构化输出,适合 CI 中用脚本提取critical或high条目做门禁判断 -
composer audit --with-dev:默认不扫require-dev下的包,但 CI 构建环节可能加载测试工具链,漏掉它们等于留后门 -
composer audit --severity=critical,high:只对高危问题失败退出,避免low级别干扰发布节奏
audit 扫不到什么,你得心里有数
它不是静态分析工具,也不运行代码,所以这些它完全不管:
- 私有包(未收录进 Packagist 安全数据库)、零日漏洞(刚爆出还没同步)、
.env泄露、配置错误、应用层逻辑漏洞 - 某些漏洞需特定 PHP 版本或扩展(如
gd)才能触发,audit不检测运行时环境 - 它比对的是 Packagist 维护的
security-advisories列表,新漏洞通常几小时到一天后才入库,存在短暂盲区 - 别和
safety或deps.dev混用——前者是 Python 工具,后者依赖网络请求解析锁文件,稳定性不如audit的离线比对机制
最关键的其实是:audit 的结果永远只反映 vendor/ 当前状态,而这个状态是否真实,取决于你有没有让 composer install 真正跑完、composer.lock 是否被正确提交、以及 CI 中是否复现了相同的安装路径和参数。











