composer audit能检测已知漏洞但不自动修复,仅比对composer.lock中精确版本与friendsofphp安全数据库;需满足三条件:composer≥2.5.0、experimental.audit全局启用、存在有效composer.lock。

composer audit 能检测已知漏洞,但不自动修复——它只比对 composer.lock 里锁死的版本和 FriendsOfPHP 安全数据库,发现匹配就报,其余一概不管。
怎么确认 composer audit 能不能用
不是命令写错了,是根本没这个功能。必须同时满足三个条件:
-
composer --version输出 ≥2.5.0(2.4.x 及更早版本会报Command "audit" is not defined) -
composer config --global experimental.audit返回true(某些企业镜像或旧配置会默认关闭) - 项目根目录存在有效的
composer.lock文件(空文件、哈希校验失败、缺失 vendor 目录都会导致跳过扫描)
CI 环境常见卡点:基础镜像自带 Composer 2.4,composer self-update 权限被禁,或代理拦截升级请求——此时直接换镜像或手动下载 composer.phar 更快。
composer audit 扫什么、不扫什么
它只读 composer.lock 中记录的**精确版本号 + 完整哈希值**,然后查 FriendsOfPHP/security-advisories 数据库。这意味着:
- ✅ 扫:你锁的是
symfony/http-foundation5.4.32,而数据库明确写了该版本含CVE-2023-45802 - ❌ 不扫:你
composer.json写了"monolog/monolog": "^2.0",但 lock 里是2.10.0—— audit 只认2.10.0,不推演约束范围 - ❌ 不扫:私有包(如
acme/internal-sdk)、fork 包(如myorg/guzzlehttp-guzzle)、带-dev后缀的版本(如dev-main) - ❌ 不扫:NVD 原始库、PHP 配置错误、代码逻辑漏洞、SQL 注入点 —— 它不是 SAST 工具,只是 CVE 映射器
新漏洞从爆出到入库通常有数小时延迟;内网 CI 若未同步镜像源的安全数据库,也会漏报。
CI 流水线里怎么跑才不误伤、不漏报
默认表格输出不适合自动化。关键参数组合如下:
-
composer audit --no-dev:跳过require-dev,避免 PHPUnit 插件类低危告警干扰发布 -
composer audit --severity=high --severity=critical:只触发高和严重级,--severity=medium无效,别加 -
composer audit --format=json | jq '.advisories[] | select(.severity == "critical")':结构化过滤,脚本可断言 -
composer audit --fail-on-security-violations:遇到 high/critical 直接非零退出,CI 可卡点 -
--no-interaction --timeout=30:防网络抖动卡住,尤其在受限内网环境
注意:--force 强制每次联网查最新数据库,适合本地首次验证;CI 中慎用,可能因 DNS 或超时失败。
发现漏洞后,为什么 composer update 不自动修复
Composer 不感知“安全”,只忠于版本约束。例如:
- 你
composer.json写着"guzzlehttp/guzzle": "^7.0",lock 里锁的是7.2.0,而CVE-2023-1234在7.5.0修复 -
composer update guzzlehttp/guzzle可能只升到7.4.9(仍在^7.0范围内),不会跨小版本跳到7.5.0
真正起作用的是:composer update guzzlehttp/guzzle --with-all-dependencies,或手动放宽约束再 update,或删掉 composer.lock 重装。补丁方案(如 cweagans/composer-patches)是临时手段,需额外引入插件且补丁必须是 git diff 格式——它不是 Composer 原生能力。
最容易忽略的一点:audit 报出来的漏洞,未必在你的运行路径中被触发。是否真被利用,得结合调用链、SAPI 类型、扩展启用状态综合判断,不能只看报告就 panic 升级。











