composer audit只查composer.lock中已安装包在friendsofphp/security-advisories库中的已知漏洞,不扫描源码、不分析运行时行为、默认不检查未lock的dev依赖(需加--dev),也不识别eol包或平台兼容性问题。

composer audit 能查什么、不能查什么
composer audit 只检查 composer.lock 中已安装包是否出现在 FriendsOfPHP/security-advisories 数据库里,不扫描源码、不分析运行时行为、不覆盖未 lock 的 dev 依赖(除非加 --dev)。它默认跳过 require-dev 下的包,比如 phpunit/phpunit 或 phpstan/phpstan —— 这些工具一旦有反序列化漏洞,攻击面反而更大。
常见误判现象:No security vulnerability detected 不代表安全,可能只是 composer.lock 没更新、用了私有包没配安全元数据、或镜像源没同步 advisory 数据。
- 必须先确保
composer install或composer update成功执行并生成/更新了composer.lock - 私有包需在
composer.json的repositories中显式声明,并提供兼容security-advisories格式的元数据 - CI 流水线中务必加
--dev和--no-interaction:即composer audit --dev --no-interaction - 想聚焦高危项,用
--severity=high,critical;想集成自动化,加--format=json并解析advisories_count字段
为什么只跑 audit 不够,还得搭配 --dry-run 和 outdated --all
composer audit 告诉你“哪里炸了”,但不告诉你“升完会不会更炸”。composer outdated --all 列出所有可升级项(含 require-dev 和传递依赖),而 composer update --dry-run -v 才真正模拟 Composer 解析器会怎么动:是否降级、是否触发 conflict、哪些间接依赖会被连带更新。
例如某行输出带 !(如 guzzlehttp/guzzle 7.4.5 → 7.5.0 !),说明该更新含已知 BC-breaking 更改,必须查 CHANGELOG;而 --dry-run 可能暴露出它会顺手把 psr/http-client 从 1.x 升到 2.x,进而导致你代码里所有 sendRequest() 调用报 ArgumentCountError。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
outdated --all是“地图”,update --dry-run是“推演”,audit是“雷区标记”——三者缺一不可 -
--dry-run输出里若出现Downgrading,基本意味着版本约束写得太宽(比如用了*或^1.0 || ^2.0),得收紧 - 对比
composer.lock变更行数:≤ 5 行较安全;上百行说明波及面过大,应改用composer update vendor/package-name --with-dependencies小步推进
容易被忽略的 EOL 和平台兼容性风险
Composer 本身完全不管某个包是否已 EOL(End-of-Life)——哪怕 monolog/monolog v1.x 官方早在 2023 年终止维护、且不兼容 PHP 8.2+ 的类型提示,只要版本约束允许,composer install 照装不误。同理,composer audit 也不会警告你 “这个包最新版只支持 PHP 8.3,而你锁死在 8.2”。
真正要兜住这类风险,得靠组合命令:
- 先跑
composer check-platform-reqs,验证当前环境是否满足config.platform和所有依赖声明的 PHP 版本、扩展要求 - 再跑
composer validate --strict,它会校验composer.json里platform配置是否合理、是否有冲突约束 - 对关键包(如
guzzlehttp/guzzle、symfony/*),人工查 Packagist 页面的 “abandoned” 标记、GitHub 上的 MAINTENANCE.md 或 SECURITY.md - CI 中建议直连
https://packagist.org,避免某些镜像站(如部分云厂商镜像)不提供 EOL 或安全元数据
删包前必须验证的三件事
用 composer-unused 找出“未使用依赖”只是第一步。很多包看似没被 use,却通过自动加载副作用悄悄起作用:比如 symfony/polyfill-php81 在加载时注册函数别名,monolog/monolog 的 handler 可能被配置文件字符串反射调用。
- 必须先跑
composer install,否则vendor/不全,composer-unused结果不准 - 若项目用了动态类名(如
new $className)、DI 容器配置、或 YAML/JSON 配置反射加载,composer-unused会误标为“未使用” - 删包后务必验证运行时行为:启动服务、跑完整测试套件、检查日志是否报
Class not found或Function not found
最危险的是那些只在 CI 脚本里用的 require-dev 包(比如 phpunit 出现在 .github/workflows/test.yml 中),composer-unused 完全检测不到,只能人工核对。










