composer install --dry-run仅校验vendor与composer.lock中记录的哈希是否一致,无法发现lock文件本身被篡改;真正暴露lock篡改的是实际执行composer install时的报错,如版本不满足、JSON格式损坏或content-hash mismatch。

composer install --dry-run 只能查 lock 和 vendor 是否一致,不能发现 lock 本身被篡改
很多人误以为 composer install --dry-run 能发现 composer.lock 被人手动改过,其实它只比对 vendor/ 目录里的文件是否匹配 lock 中记录的 dist.sha256,完全不校验 lock 文件自身是否被篡改。哪怕你把 lock 里某个包的版本号从 "2.1.0" 改成 "999.0.0",只要 vendor/ 里真有那个旧版本、且哈希没变,--dry-run 依然会输出 Nothing to install or update。
真正能暴露 lock 被篡改的,是 composer install 实际执行时的报错:
-
Root composer.json requires vendor/package ^2.0, but it is not satisfied by vendor/package 999.0.0—— lock 里写了非法版本,install 会拒绝用 -
Invalid argument supplied for foreach()—— JSON 格式损坏(比如多删了个逗号) -
content-hash mismatch——composer.json内容变了但 lock 没更新,或有人手改了 lock 的content-hash字段
verify-checksums --strict 是唯一校验 vendor 文件真实哈希的命令
composer verify-checksums --strict 才是真正打开 vendor/ 目录、逐个读文件、归并字节流再算 SHA256 的命令。但它默认不可用,必须启用实验模式:
- 运行前必须设环境变量:
COMPOSER_EXPERIMENTAL=1 - 必须加
--strict,否则不匹配也只警告、返回码仍是 0(CI 会误判成功) - 它跳过
type: "path"的包,也跳过没有dist.sha256字段的老包——这些地方容易漏检 - 不校验
vendor/composer/autoload_*.php这类生成文件,但会扫描到vendor/autoload.php并失败(因为它不在任何哈希记录中)
示例失败输出:vendor/symfony/console: checksum mismatch,但它不会告诉你哪个具体文件错了,得自己手动提取该包的 dist.sha256,再用 find vendor/symfony/console -type f -not -name "*.git*" -print0 | xargs -0 shasum -a 256 | shasum -a 256 逐层比对。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
为什么 dist.sha256 不等于你手动算的 src/ 目录哈希
composer.lock 里每个包的 dist.sha256 字段,是对原始 zip/tar 包的**完整二进制内容**计算的,不是对解压后目录算的。所以:
-
shasum -a 256 vendor/package/dist.zip能跟 lock 里字段对上 -
shasum -a 256 vendor/package/src/或find vendor/package/src -type f -exec shasum -a 256 {} \;完全没意义,结果必然不等 - 别手动去 vendor/ 里挨个算子目录哈希来“验证”——这既慢又无效,还可能漏掉隐藏文件或符号链接
这也是为什么 verify-checksums 必须归并所有文件字节流:它模拟的是“把整个包重新打包再哈希”的过程,而不是对某个路径做快照。
生产部署前最容易被忽略的三个盲点
即使 verify-checksums --strict 通过,也不代表安全。以下三点在 CI/CD 流水线里常被跳过,但恰恰是攻击入口:
-
vendor/autoload.php和vendor/composer/autoload_classmap.php等关键引导文件完全游离在校验体系外——它们由 Composer 动态生成,不参与任何哈希比对,一旦被注入恶意代码,verify-checksums无法感知 - 如果部署脚本执行了
cp -r vendor public/,会导致autoload.php可被 Web 直接访问,PHP 解析错误会泄漏绝对路径,甚至 dump 出类映射结构 -
composer.lock里dist.url字段若含临时 token(如https://token:xxx@repo.example.com/pkg.zip),就会随 lock 文件一起泄露——grep -A2 '"dist":' composer.lock | grep url 应纳入 CI 审计步骤

















