verify-checksums --strict 是唯一能真实校验 vendor 文件实际完整性哈希的命令,需启用 COMPOSER_EXPERIMENTAL=1 并加 --strict 才失败;它逐包扫描 vendor 目录(跳过 .git、tests/ 等),归并字节流计算 SHA256 并与 composer.lock 中 dist.sha256 比对,但不校验 autoload_*.php 等生成文件。

必须用 COMPOSER_EXPERIMENTAL=1 composer verify-checksums --strict 才能验证 HTTPS 下载后文件的实际完整性;仅靠 HTTPS 传输本身不保证 vendor 目录内容未被篡改。
verify-checksums --strict 是唯一真实校验 vendor 文件哈希的命令
HTTPS 只确保传输过程不被中间人劫持,但无法防止:缓存污染、磁盘损坏、手动修改 vendor 文件、镜像源替换 dist 包却未同步哈希值。真正校验落地文件是否与 composer.lock 一致,只能靠这个命令:
- 它逐包扫描
vendor/下每个包的全部源文件(跳过.git、tests/、examples/等非发布路径) - 归并所有字节流,计算 SHA256,并与
composer.lock中对应包的dist.sha256字段比对 - 不校验
vendor/composer/autoload_*.php等生成文件——它们完全游离在校验体系外 - 跳过
type: "path"的本地依赖,以及没有dist.sha256字段的老包(如部分私有源分发的包)
为什么 composer install 成功 ≠ vendor 完整
composer install 只在校验刚下载的 zip/tar 包(解压前)是否匹配 composer.lock 中的哈希;一旦解压完成,它就不再回头检查磁盘上实际文件。这意味着:
- CI 中用了
--prefer-source:走 git clone,没dist.sha256,verify-checksums直接跳过该包 - 本地缓存被污染后重装:install 阶段命中坏缓存、跳过校验,但
verify-checksums会暴露问题 - 镜像站替换了 dist 包但未同步原始哈希:install “匹配”,
verify-checksums却报 mismatch - 手动改了
vendor/autoload.php:它会被扫描到,但无哈希记录,直接失败
配置和执行必须同时满足三个硬性条件
漏掉任意一个,命令就静默无效或返回码为 0(即使出错):
- 必须启用实验模式:
COMPOSER_EXPERIMENTAL=1,否则命令不存在 - 必须加
--strict,否则只警告、不失败,CI 无法捕获 - 必须确保
composer.lock中存在dist.sha256字段——这要求包是从支持签名的源(如 packagist.org 或启用了 signature 的镜像)安装而来
最关键的盲区:autoload.php 和关键引导文件完全不受控
verify-checksums 不校验 vendor/autoload.php,也不校验 vendor/composer/autoload_classmap.php 等生成文件。这些文件一旦被注入恶意代码,Composer 无法感知。生产部署前必须人工兜底:
- 将
vendor/设为只读(防止运行时写入篡改) - 用
shasum -a 256 vendor/autoload.php与可信基线比对 - 禁用
eval()、create_function()等动态执行函数,阻断利用链


















