composer audit不是修复工具,仅报告漏洞且依赖composer≥2.5.0、启用experimental.audit、存在有效composer.lock;它只比对lock文件中的精确版本与friendsofphp安全数据库,不分析代码、调用链、dev分支或私有包。

composer audit 不是修复工具,它只报漏洞,不改代码、不升版本、不分析调用链——你看到的每一条 HIGH 或 CRITICAL,都得手动处理。
composer audit 命令不存在?先查三件事
报错 Command "audit" is not defined,基本就卡在这三个地方:
- 运行
composer --version,确认 ≥ 2.5.0;低于则必须composer self-update - 即使版本够,也要检查是否启用了实验特性:执行
composer config --global experimental.audit true(该配置写入全局auth.json,缺了这步会静默无输出) - 某些精简版 Composer(如部分 Docker 镜像)直接剔除了 audit 模块,
composer list | grep audit完全无结果——只能换完整版
audit 扫的是 composer.lock,不是 vendor 也不是 composer.json
它只读取 composer.lock 中记录的**精确版本号和哈希值**,然后比对 FriendsOfPHP/security-advisories 数据库。这意味着:
-
composer.json里写了"guzzlehttp/guzzle": "^7.0",但 lock 文件锁在7.2.0,audit 就只看7.2.0是否有已知漏洞,不管7.5.0是否可用 - 没运行过
composer install或composer update,lock 文件缺失或未更新 → audit 报Could not find composer.lock或直接空输出 - 手动拷贝
vendor/、git clone 进来、或用--no-install跳过安装 → audit 失效,因为没锁文件可读
CI 流水线里 audit 总失败?参数要精控
默认表格输出 + 全量扫描,在 CI 里极易误中断。真正该加的参数只有这几个:
-
--no-dev:跳过require-dev,避免 PHPUnit、phpunit/php-code-coverage 这类开发依赖的低危告警污染生产判断 -
--severity=high --severity=critical:只让高危及以上中断流程;medium 和 low 不影响退出码,也不支持传medium -
--format=json:给 CI 解析用,比如配合jq '.advisories[] | select(.severity == "critical")'做精准断言 -
--force:仅在首次跑或怀疑缓存过期时用;CI 中慎用,网络超时会导致构建挂起
扫出来漏洞,但项目根本没调用相关代码?别急着升级
audit 不分析调用链,只认版本号是否在 advisory 列表里被标记。所以常见情况是:
- 报告了
CVE-2023-1234,但你的代码里从没用过VulnerableClass::doBadThing() - 漏洞需特定条件触发:比如开启
debug=true、启用openssl扩展、或配合用户输入的 SSRF 场景 - 私有 fork 包(如
myorg/guzzle)不匹配原厂guzzlehttp/guzzle的 advisory 条目 → 漏报,但你实际用的可能更危险
真正关键的一步常被跳过:拿到 fixed 字段建议的版本后,先写最小复现脚本验证漏洞是否能在你当前配置下触发,再决定是升级、打补丁,还是加运行时防护。











