composer audit 在 ci 中不生效最常见原因是版本低于2.5.0或未启用experimental.audit;需确认版本、开启实验特性、使用完整版phar、严格按install→audit顺序执行,并注意dev版本、fork包及网络访问限制。

composer audit 在 CI 中为何不生效
最常见原因是 Composer 版本低于 2.5.0,或虽 ≥2.5.0 但未启用实验特性。执行 composer --version 确认版本;若达标,还需运行 composer config --global experimental.audit true 才能激活 audit 命令。部分 CI 镜像(如 composer:alpine)自带精简版 phar,不含审计模块——必须替换为官方完整版,例如 GitHub Actions 中改用 php-actions/composer@v6 或手动安装。
CI 流程中 audit 必须紧接 install 且带明确参数
composer install 和 composer audit 是两个独立阶段,不能合并或省略顺序。生产构建必须按以下顺序执行:
-
composer install --no-dev --optimize-autoloader --classmap-authoritative(缺一不可,否则 autoload 不稳定或 dev 包混入) -
composer audit --no-dev --format=json --severity=critical,high(--no-dev排除干扰,--severity控制中断粒度,避免 low/medium 漏洞阻断发布)
注意:--locked 参数无需添加,audit 默认只读 composer.lock;加了反而可能因锁文件格式异常导致跳过扫描。
audit 失效的隐蔽原因
即使命令执行成功、返回 0,也可能实际未扫描任何包——常见于:
-
composer.lock中含"dev-main"或其他非 Packagist 正式版本号:audit 直接跳过,因其不在官方漏洞数据库覆盖范围内 - 使用 fork 包(如
myorg/guzzlehttp-guzzle):advisories 只匹配原厂名guzzlehttp/guzzle,无法识别 fork 分支的 CVE - CI 环境无法访问
https://packagist.org/advisories:内网环境需配置可信 CA 或代理,COMPOSER_NO_SSL=1属临时妥协,不推荐长期使用
比 audit 更可靠的加固方式
composer audit 是事后检查,而 roave/security-advisories 是事前拦截。它把所有已知漏洞转为 Composer 的版本约束,让 install 阶段直接失败——只要在 composer.json 中声明为 require-dev,就能在 CI 安装时自动阻断含漏洞的依赖版本。这对 fork 包、私有包或 dev- 版本更有效,且不依赖网络连通性。
真正卡点的关键不是“能不能扫出漏洞”,而是“有没有机制让不安全的依赖根本装不上”。audit 报告再全,也挡不住人手动 --ignore 或删掉 CI 脚本里的那行命令。











