composer audit 在生产环境默认不生效,因其依赖 composer.lock 和 PHP 环境,而生产机通常无 Composer 且不保留锁文件;安全审计必须前置到 CI/CD,通过校验 lock 文件、结构化解析 JSON 输出、严格管控 ignore 配置与 dev 包范围来真正落地。

composer audit 命令为什么在生产环境默认不生效
因为 composer audit 默认只检查 composer.lock 中已安装的包,但生产环境通常不装 Composer,更不会保留 composer.json 和 composer.lock 的可执行上下文。直接在生产机上跑 composer audit 不仅危险(需 PHP 环境 + Composer 二进制),还可能因缺少配置项(如 config.audit.ignore)导致误报泛滥。
如何让安全审计真正落地到生产发布流程
审计必须前置到 CI/CD 流水线,而非等代码上了生产才查。关键不是“能不能运行”,而是“谁在什么时候用什么配置运行”:
- CI 脚本中必须先确认
composer.lock存在且未被修改:用ls -la composer.lock+git status --porcelain composer.lock - 执行
composer audit --format=json并捕获退出码:非零即表示发现 CVE,应立即中断构建 - 若需忽略特定漏洞(如 CVE-2025-1234),必须在
composer.json的config.audit.ignore中显式声明,不能靠命令行参数临时跳过 - 避免在 CI 中用
composer update后再 audit——这等于用新依赖树覆盖旧 lock,审计对象已失真
audit 报警信息里哪些字段最值得监控
composer audit --format=json 输出是结构化数据,别只看终端红字。重点关注三个字段:
-
advisory.id:对应 CVE 编号,例如CVE-2025-7890,用于关联漏洞库和修复进度 -
advisory.package:出问题的包名,如monolog/monolog,确认是否为生产实际加载的包(有些 dev-only 包虽在 lock 里,但生产未启用) -
advisory.fixedIn:官方建议升级到的最小安全版本,注意它不一定兼容你当前约束(比如要求升到^3.0,而你锁在^2.10)
为什么 audit 有时“明明有漏洞却不报警”
常见静默失效场景:
-
composer.lock文件被 git 忽略或未提交——audit 没东西可查 - 项目用了
composer install --no-dev,但composer.json里require-dev下的包仍被写入 lock,audit 会一并扫描;若这些包含高危漏洞,而你又没在 CI 中禁用 dev 包审计,就会漏掉真实风险点 - 本地开发时手动改过
vendor/目录(如 patch 某个文件),audit 只校验 lock 记录,不校验实际文件内容,无法发现这种绕过 - PHP 运行时扩展缺失(如
ext-json),可能导致某些包功能降级,但 audit 不感知运行时能力,只管版本号
真正卡住风险的,从来不是 audit 跑不跑得通,而是 lock 文件有没有被当成契约来维护、CI 是否把 audit 当成门禁而非装饰。











