composer audit 不是开箱即用命令,必须满足 Composer ≥2.5.0 且全局启用 experimental.audit,并依赖有效 composer.lock 中的精确版本与哈希比对 FriendsOfPHP 安全数据库;CI 中需加 --no-dev、--severity=high,critical 和 --format=json 避免误失败。

composer audit 不是“装完就自动扫”,它只在你明确运行时才查 composer.lock 里的精确版本,且必须满足版本 + 配置双条件;CI 里直接用它默认行为会频繁失败,不是漏洞太多,是你没调对参数。
composer audit 命令不存在?先确认版本和实验配置
报错 Command "audit" is not defined,99% 是 Composer 版本低于 2.5.0,不是权限、镜像或插件问题。
- 运行
composer --version,输出必须是2.5.x或更高(2026 年推荐用2.9.6) - 版本过低?执行
composer self-update;若失败,检查 PHP 是否 ≥ 7.4(2.5+ 最低要求) - 即使 ≥ 2.5.0,某些精简镜像仍不带 audit 模块:运行
composer list | grep audit确认命令存在 - 极少数情况需显式启用:
composer config --global experimental.audit true
为什么 audit 扫不出已知漏洞?锁文件、网络、分支三处最常漏
composer audit 只读 composer.lock,不看 composer.json,也不扫描 vendor/ 目录——它比对的是锁文件里记录的**精确版本号 + dist shasum**。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
-
composer.lock缺失、哈希损坏、或被手动编辑过 → 结果为空或漏报 - 私有包未在
composer.json的repositories中显式声明,或其元数据不含security-advisories字段 → 默认跳过,不提示“已跳过” - 用了
dev-main、dev-feature/x等开发分支 → audit 主动跳过(安全数据库不收录 dev 分支) - 企业内网连不上 Packagist 安全数据库?报错
Could not fetch advisories,可临时切源:composer config --global repo.packagist.org composer https://packagist.org
CI 流水线里 audit 总失败?别让它默认返回非零退出码毁构建
默认行为是:只要发现任意一条 advisory(哪怕是个 5 年前的 low 级 CVE),就返回非零退出码 —— 这不是 bug,但你不该照单全收。
- 加
--no-dev:排除phpunit/phpunit、phpstan/phpstan等工具链干扰 - 只卡真正要命的:
--severity=high --severity=critical(注意:--severity=medium无效) - 结构化判断是否通过:
composer audit --format=json --no-dev --severity=high --severity=critical,再用jq '.advisories | length == 0' - 防超时卡住:
--no-interaction --timeout=30
audit 发现漏洞后,为什么 composer update 不升级?
composer audit 只预警,不修复;它甚至不告诉你该升哪个版本——修复动作必须你手动触发。
- 报告里给出的
CVE-2023-12345或GHSA-xxxx,你要自己查对应包的 changelog 或安全公告,确认哪个版本修复了它 - 更新单个包:
composer update vendor/package-name(不是install) - 若需保持其他包不变,只更新锁文件:
composer update --lock,然后立刻git add composer.lock && git commit - 禁止手动改
composer.lock:它含content-hash和所有子依赖快照,改错一个逗号就会导致后续composer install报Invalid archive
真正容易被忽略的是:audit 的结果完全取决于 composer.lock 的状态,而这个文件的变更必须绑定到 Git 提交动作上——没人提交 lock,就等于没人确认过依赖变更,CI 里再严的扫描也拦不住环境漂移。

















