Composer 不支持校验 VCS 包缓存完整性,因其直接 clone 源码、跳过 ZIP 缓存;verify-checksums 仅校验 dist.sha256 字段,而 VCS 包无此字段,故静默跳过;防篡改须依赖 Git 层控制,如固定完整 commit hash、远程校验、GPG 签名等。

Composer 不支持在拉取 VCS 代码前自动校验缓存完整性——因为 VCS 模式(--prefer-source)根本不用缓存。 它直接走 git clone 或 svn export,跳过 cache/files/ 下的 ZIP 包,也就不存在“校验缓存”的前提。你看到的所谓“缓存校验失败”,其实是误判了模式或混淆了校验目标。
为什么 verify-checksums 对 VCS 包完全无效
composer verify-checksums --strict 只校验 dist.sha256 字段存在的包,而 VCS 包在 composer.lock 中没有该字段(只有 source 块),因此会被静默跳过。即使你手动改了源码、删了 .git、甚至注入了恶意文件,这个命令也不会报错。
- 运行
composer show monolog/monolog查看输出:若含source: { type: git, url: ..., reference: ... },说明当前是 VCS 模式 - VCS 包的哈希校验只发生在
git clone后比对reference(即 commit hash),Composer 不计算或存储文件级 SHA256 -
COMPOSER_EXPERIMENTAL=1 composer verify-checksums --strict的日志里如果出现Skipping package xxx (no dist.sha256),就确认它没校验你关心的包
想真正防住 VCS 拉取时的篡改,只能靠 Git 层控制
Git 本身提供强一致性保障,但前提是信任 remote 和 reference。Composer 不介入这一层,所以必须人工加固:
- 确保
composer.lock中的source.reference是完整 40 字符 commit hash(不是 tag 或 short-hash),避免被远程移动指针绕过 - 在 CI 中加检查:
git ls-remote https://github.com/monolog/monolog.git abc123... | grep -q abc123...,确认 hash 确实存在且未被 force-push 覆盖 - 私有 Git 服务器启用 signed tag + GPG 验证,并在
git config --global gpg.program配置好密钥链 - 禁用
allow-plugins中非可信 Git 插件,防止第三方脚本劫持post-update-cmd修改工作区
缓存完整性校验只对 --prefer-dist 生效,且必须手动触发
如果你真需要缓存校验,唯一路径是强制走 ZIP 分发:
- 删掉
vendor/和composer.lock,重跑composer install --prefer-dist --no-dev - 确认
composer.lock中目标包含dist: { type: zip, url: ..., sha256: ... }字段 - 再执行
COMPOSER_EXPERIMENTAL=1 composer verify-checksums --strict——这时才会逐文件读 vendor/ 并比对sha256 - 注意:若用了镜像源但未同步原始哈希(如某些私有 Satis 未透传 dist.sha256),校验会失败,这不是缓存问题,而是元数据不一致
最常被忽略的一点:VCS 和 dist 是两种互斥的交付机制,不存在“VCS 缓存”这回事。你以为在优化缓存,实际可能一直在绕过它。











