不能靠 composer install 自动过滤不安全包,它只按 composer.lock 精确还原依赖,不检查漏洞;真正起作用的是在 install 后、构建前强制执行 composer audit 并依结果控制流程。

不能靠 composer install 自动过滤不安全包 —— 它根本不检查漏洞,只按 composer.lock 精确还原依赖。 真正起作用的是在 install 之后、构建完成前,强制插入 composer audit 并根据结果控制流程走向。
确认 Composer 版本与 audit 功能已启用
很多 CI 流水线执行 composer audit 直接报错或静默退出,是因为:
• 当前 Composer 版本低于 2.5.0(composer --version 验证)
• 即使 ≥2.5.0,也未开启实验特性(composer config --global experimental.audit true 必须提前运行)
• 使用了精简版 phar(如某些 Docker 镜像自带的 composer:alpine),不含审计模块
CI 中建议统一用官方完整版:例如 GitHub Actions 中指定 php-actions/composer@v6 或手动 curl -sS https://getcomposer.org/installer | php 安装最新稳定版
在 CI 中串联 install + audit,并按严重性中断
composer install 和 composer audit 是两个独立阶段,必须显式组合。关键不是“安装安全的包”,而是“安装后立刻验证,失败则阻断交付”:
- 必须先运行
composer install --no-dev --optimize-autoloader --classmap-authoritative(生产构建底线参数,缺一不可) - 紧接着运行
composer audit --no-dev --format=json --severity=critical,high(只对 critical/high 级别中断,避免低风险干扰发布节奏) - 若返回非零退出码(即发现匹配的高危漏洞),CI 应立即失败;GitHub Actions 可直接靠 step 的
if: ${{ failure() }}捕获,无需额外脚本解析 JSON - 注意:不要加
--locked——audit默认就基于composer.lock,加了反而可能因锁文件格式异常导致跳过扫描
绕过 audit 的常见陷阱与替代加固点
即使 audit 配置正确,也可能漏报或失效:
- 公司内网无法访问
https://packagist.org/advisories→ 在 CI 环境中配置可信 CA 或设置COMPOSER_NO_SSL=1(不推荐)或代理环境变量 -
composer.lock中含dev-版本(如"dev-main")→audit会直接跳过这些条目,因其不在 Packagist 安全数据库覆盖范围内 - 用了 fork 包(如
myorg/guzzlehttp-guzzle)→ advisories 只认原厂名guzzlehttp/guzzle,需手动同步 CVE 信息或改用原厂包 - 更可靠的做法是叠加
roave/security-advisories:它把所有已知漏洞转为 Composer 的版本约束,在install阶段就阻止安装不安全版本,而非事后审计
真正难的不是命令怎么写,而是让 audit 结果和团队的风险接受策略对齐:比如是否允许 medium 漏洞临时上线、谁有权用 --ignore=CVE-XXXX 豁免、报告归档是否满足合规审计要求 —— 这些没法靠一条命令解决,得靠配置文件里的 "audit": { "ignore": [...] } 和明确的流程约定。











