composer audit默认检查composer.lock中已安装的包(含间接依赖),但不扫描未安装的潜在依赖;常见漏报原因包括lock文件缺失或过期、私有包被跳过、或漏洞未收录至PHP-SECADV数据库。

composer audit 默认检查所有已安装的包,包括间接依赖——但前提是它们已被解析并写入 composer.lock,且实际存在于 vendor/ 中。它不扫描“理论上可能被拉入但尚未安装”的子依赖。
为什么 indirect dependency 有时不被 audit 到
常见错误现象是运行 composer audit 后报告 “No vulnerabilities found”,但手动查某个间接包(比如 guzzlehttp/psr7)却发现它有 CVE。原因通常有三个:
-
composer.lock未生成或过期:audit 只读 lock 文件,不跑依赖求解器;必须先执行composer install或composer update - 该间接包被
conflict规则排除,或被replace替换,导致未进入 lock 文件 - 包来自私有源、fork 或
path类型仓库,audit 默认跳过,不查其 advisories
composer audit --with-dependencies 的真实作用
这个参数名容易误导——它**不是开启“深度递归扫描”**,而是显式启用对 require-dev 中声明的间接依赖的检查(默认只查 require 直接依赖及其传递依赖)。换句话说:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 不加该参数:查
require树下所有已安装包(含间接依赖),但忽略require-dev树 - 加
--with-dependencies:仍只查已安装包,但把require-dev树也纳入范围(等价于--dev) - 它不会让 audit 去“预测”某个未安装的间接依赖是否存在漏洞
如何确认某个间接包是否真被 audit 覆盖
最可靠的方式是直接从 composer.lock 提取目标包信息,并验证它是否在审计范围内:
- 运行
composer show --locked | grep "package-name",确认该包出现在输出中 - 用
composer show --locked --format=json | jq '.packages[] | select(.name == "vendor/package")'查看其完整元数据,重点看source.type和dist.shasum是否存在 - 若
source.type是git或package,且未在 Symfony Security Advisory Database 中注册,audit 就会静默跳过——此时你会看到Warning: No security advisories found for package vendor/package
补漏:对关键间接依赖做人工交叉验证
audit 的覆盖盲区集中在小众包、私有 fork、未提交到 PHP-SECADV 的 CVE。务实做法是锁定几个核心间接依赖(如 symfony/polyfill-*、psr/*、monolog/monolog),然后:
- 查 Packagist 页面的 “Advisories” 标签页(如有)
- 访问 FriendsOfPHP/security-advisories 手动搜索包名
- 用
snyk test --file=composer.lock --severity-threshold=high补扫,它比 audit 多覆盖 NVD 和 GitHub Advisories
别依赖 “没报错” 就等于安全——audit 的沉默,常常只是数据库没收录,不是漏洞不存在。

















