Composer本身不检查CVE或安全公告,因此“缺少安全更新”不是其原生报错;该提示来自第三方工具(如composer audit、roave/security-advisories或Dependabot),真正导致install失败的是roave将含漏洞版本设为conflict,引发“Your requirements could not be resolved”错误。

“缺少安全更新”不是 Composer 的原生报错,而是你看到的第三方扫描工具(如 composer audit、phpstan 插件、或 GitHub Dependabot 提示)给出的风险提示,不是 composer install 本身失败的原因。
为什么 composer install 不报“缺少安全更新”?
Composer 本身不检查 CVE 或安全公告,它只做依赖解析和安装。所谓“缺少安全更新”,通常来自:
- 你本地运行了
composer audit(需 Composer 2.5+ 且启用了 security-advisories 插件) - CI 流程中集成了
roave/security-advisories这类阻止已知漏洞包安装的约束包 - GitHub 或 GitLab 自动 PR(Dependabot / Renovate)在 diff 中标出某包存在已知 CVE
这些都不会让 composer install 报错,但会中断 CI 或发出警告。真正在 install 阶段失败的,往往是 roave/security-advisories 把有漏洞的版本直接列为 conflict,导致 Composer 解析器拒绝安装——此时报错其实是 Your requirements could not be resolved,根源是冲突而非“提醒”。
如何确认是不是 roave/security-advisories 在拦截?
查 composer.json 的 require 或 require-dev 里有没有这一行:
"roave/security-advisories": "dev-latest"
如果有,它会把所有已知含 CVE 的包版本(比如 monolog/monolog:1.25.0)硬性声明为 conflict。这时 Composer 就真的装不了——不是“缺更新”,是“被禁止安装”。
验证方法:
- 运行
composer show monolog/monolog,看列出的可用版本里是否完全跳过了低危版本(如 1.x 系列) - 运行
composer why-not monolog/monolog:1.25.0,输出末尾大概率出现(conflicted by roave/security-advisories)
该升版本还是该换包?先看 CVE 影响范围
别一看到“安全更新”就盲目升级。很多 CVE 只影响特定使用路径(比如仅当启用某个不常用的 handler 才触发),而升级可能引入 BC Break。
操作前务必:
- 去 roave/security-advisories 页面查对应包的 CVE 编号(如
CVE-2022-39227) - 点进 CVE 原文,确认
affected versions是否真包含你当前用的版本 - 检查你代码里是否实际调用了那个有风险的 API —— 很多项目只是间接依赖,根本不会触达漏洞路径
例如:guzzlehttp/guzzle 的某个 CVE 要求 v7.5.0+,但如果你只用 HttpClient 基础功能,且项目锁死在 ^6.5,那升级到 v7 可能要重写所有请求逻辑。
绕过安全拦截的临时方案(仅限开发/测试)
生产环境不该绕,但调试时想快速验证是否真是它导致 install 失败,可临时禁用:
- 删掉
roave/security-advisories行,再composer update --lock-only - 或加
--ignore-platform-reqs不起作用,因为它不涉及 PHP 版本,得用:composer update --no-plugins(跳过所有插件,包括 security-advisories)
注意:--no-plugins 会同时关掉 autoload 生成、脚本执行等,仅用于定位问题,不可提交到 CI。
真正难的不是知道该升级,而是判断升级后会不会让 hyperf/framework 或 laravel/octane 这类核心包连锁翻车。安全更新常卡在生态兼容层,不是单个包的事。


















