Composer 默认不校验网络传输层完整性,仅在 install/update 时比对 lock 文件中的 dist.sha256 与解压后文件哈希,且仅限 dist 包(zip/tar),不覆盖 source 包(git clone)。

composer install 时怎么自动校验文件完整性
Composer 默认不校验下载包的文件哈希(如 SHA256),只比对 composer.lock 中记录的 dist.sha256 和实际解压后文件的哈希——但这个校验只在安装/更新时触发,且仅限于 dist 包(zip/tar),不覆盖 source 包(git clone)。关键在于:它不做网络传输层校验,也不验证包发布者签名。
实操建议:
- 确保项目启用
composer install --prefer-dist(默认行为),否则走 git clone 就完全绕过哈希校验 - 不要手动删掉
vendor/后用composer install --no-scripts --no-plugins跳过校验步骤——这会让 Composer 跳过哈希比对逻辑 - 检查
composer.lock是否包含"sha256": "..."字段:没有说明该包未发布 dist 包,或你正用着旧版 Composer(
composer verify-signature 能不能验包签名
composer verify-signature 这个命令根本不存在。Composer 官方至今(v2.7.x)不支持 PGP 或其他数字签名机制来验证包发布者身份。所谓“签名校验”是常见误解,源于混淆了 Packagist 的「签名 API」(仅供 packagist.org 内部使用)和用户端能力。
常见错误现象:
- 搜到第三方插件如
composer/composer-signature-checker,但已多年未维护,且依赖废弃的openssl_pkey_get_public方式,不兼容 PHP 8.1+ - 试图在
composer.json里写"signature": "..."字段——Composer 会直接忽略它 - 认为
composer update --lock会重新签名 lock 文件——它只会重写时间戳,不生成任何密码学签名
想真正确保包来源可信,只能靠这三件事
不是 Composer 不够好,而是 PHP 生态没把签名当基础设施。目前唯一可行路径是组合控制:
- 强制所有包走 Packagist 官方源(禁用
repositories自定义源),因为 Packagist 会对上传包做基础扫描和哈希存档 - 用
composer audit(Composer 2.5+)查已知漏洞,它会调 Packagist 的安全告警 API,虽不验签名,但能拦截已被标记为恶意的包版本 - 在 CI 中加一步:
composer show --locked --format=json | jq -r '.packages[] | select(.name | startswith("monolog/")) | .dist.sha256',再用shasum -a 256 vendor/monolog/monolog/CHANGELOG.md手动比对——适合高敏感项目,但得自己维护白名单和路径映射
为什么 vendor 目录里看不到 .sig 或 .asc 文件
因为 Packagist 从不下发签名文件。它只在 API 返回中附带 dist.sha256 和 dist.reference(git commit hash),而这两个值都写死在 composer.lock 里。你看到的每个包目录下都没有签名相关元数据,这不是漏了,是设计如此。
容易被忽略的点:
-
composer install的--dry-run模式不会触发哈希校验,它只模拟流程,别拿它测试完整性逻辑 - 私有 Packagist 镜像(如 Satis、Private Packagist)若没开启
enable-dist,会导致所有包退化为 git clone,彻底丢失哈希校验能力 - PHP 的
phar.readonly = On(默认)会影响某些包的运行时校验逻辑,但它和 Composer 下载阶段的完整性校验无关










