composer install 仅校验 composer.lock 中 dist.shasum(SHA-256),且仅对 Packagist 下载的 zip/tar 包生效;Git 仓库、本地路径、自定义 repo 和缓存命中均跳过校验。

composer install 时到底校验了什么?
它只校验 composer.lock 里记录的 dist.shasum(SHA-256),且**仅对从 Packagist 下载的 zip/tar 包生效**;Git 仓库、本地路径、自定义 repo、缓存命中等情况统统跳过校验。
- 现象:删掉
vendor/后composer install没报错,但包内容实际被镜像源篡改过 → 因为镜像返回了“合法哈希”的假包,或你用了--prefer-dist却没清缓存 - 原因:Composer 默认信任缓存;
dist.shasum是压缩包原始哈希,不是解压后文件树的哈希,无法防解压时注入恶意文件 - 实操建议:
composer install --no-cache --prefer-dist强制跳过缓存并走 dist 流程,才能触发哈希比对 - 注意:
composer update会重新计算并写入新shasum,但不会回溯验证已安装包 —— 它只管“下次装”
怎么启用 Packagist 元数据 GPG 签名验证?
这是 Composer 生态中**唯一真正用到 GPG 的签名验证场景**,目标是防仓库投毒(比如攻击者把恶意包塞进 packages.json 搜索结果),但它不校验任何具体包的内容。
- 前提:必须
composer --version≥ 2.2.0,且未禁用 HTTPS(secure-http: true) - 命令:
composer config --global signing-key https://packagist.org/keys.json—— 不是导入公钥,而是告诉 Composer 去哪拉取可信密钥列表 - 验证是否生效:删掉
vendor/和composer.lock,运行composer install -v,日志中出现Verifying packages.json signature with key才算成功 - 坑点:如果 Packagist 更换主密钥,旧版 Composer 可能因找不到对应公钥而直接失败,且无降级提示;
keys.json是动态更新的,但 Composer 不自动轮换
想验证某个包的 Git tag 是否真被作者签名?Composer 不管这事
Composer 对 Git 仓库("type": "vcs")只做 git clone 和 git checkout,**完全不调用 git tag -v**。所谓“签名验证”,得你手动来。
- 查源地址:
composer show vendor/package或翻composer.lock里的source.url - 手动验证:
git clone <url> && cd <repo> && git verify-tag v2.5.0—— 若输出gpg: Signature made ... using RSA key ...且无 warning,才算可信 - 常见错误:
gpg: Can't check signature: No public key→ 需先gpg --import author.pub.asc,再确认指纹是否与作者官网公布的一致 - 注意:很多包虽打 tag,但根本没签名;签名了也不代表代码安全,只是证明“这 tag 是这个人推的”
PHAR 文件、自定义脚本、锁文件本身,怎么额外加固?
Composer 不处理这些,但它们恰恰是供应链攻击高发区 —— 比如 php-cs-fixer.phar 被中间人替换,或 composer.lock 被悄悄改掉 shasum 字段。
- PHAR:下载后必须校验官方发布的
.sha256或.asc文件,例如:curl -O https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases/download/v3.14.3/php-cs-fixer.phar && curl -O https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases/download/v3.14.3/php-cs-fixer.phar.sha256 && sha256sum -c php-cs-fixer.phar.sha256 - 锁文件完整性:
composer validate --lock只检查结构一致性,不防篡改;更可靠的是在 CI 中用git diff --exit-code composer.lock确保它没被意外修改 - 自定义校验:可用
roave/signature库对关键配置文件签名,但注意它签的是文件内容,不是 Composer 包 —— 属于项目层加固,和 Composer 自身机制无关
真正的难点不在“会不会做”,而在“每次都要做”——缓存、镜像、CI 权限、密钥轮换、Git 签名覆盖率,这些环节只要漏一环,前面所有校验都归零。










