启用包签名验证需设置composer_signature_verification=1或在composer.json中声明"require-signature": true;仅对packagist官方仓库或支持签名的私仓生效,php 7.2+才完整支持。

Composer install 时如何启用包签名验证
Composer 本身不默认校验包签名,必须手动开启 composer install 或 composer update 的签名检查,否则即使包被篡改也不会报错。
关键操作是设置 COMPOSER_SIGNATURE_VERIFICATION 环境变量为 1,或在 composer.json 中显式声明:"require-signature": true。两者等效,但后者更可靠——环境变量可能被 CI/CD 脚本覆盖或遗漏。
- 仅当使用 Packagist 官方仓库(或支持签名的私仓)时才生效;自建仓库需额外配置 signing key 和签名服务
- 一旦启用,所有依赖包的
.sig文件必须存在且可验证,缺失或校验失败会直接中止安装,并抛出类似Signature mismatch for package xxx的错误 - PHP 7.2+ 才支持完整签名验证逻辑;低版本会静默跳过,不报错也不校验
如何确认某个包是否真的被签名了
不是所有 Packagist 上的包都启用了签名,目前只有明确声明并完成密钥注册的维护者才能发布带签名的版本。
最直接的方式是查 Packagist 页面右上角的「Signed」徽章,或者用命令行快速验证:composer show vendor/package --all,观察输出中是否有 signature: sha256:... 字段。
- 没有
signature字段 ≠ 包不安全,但说明它没走签名流程,完全依赖仓库 HTTPS 传输和 Packagist 的人工审核机制 - 签名只覆盖
dist包(zip/tar),source(git clone)方式安装不参与签名校验 - 第三方镜像(如阿里云、腾讯云 Composer 镜像)通常不透传签名文件,启用
require-signature后可能直接失败
私有仓库怎么配签名验证(Satis / Private Packagist)
私仓要支持签名,不能只靠 Composer 客户端开关,服务端必须生成并托管 .sig 文件,且客户端需信任其公钥。
以 Satis 为例:需在构建时加 --sign 参数,并指定私钥路径;生成的 packages.json 里每个包条目会多出 signature 字段;客户端则要用 composer config --global repo.packagist.org.keys.public-key-path /path/to/public.key 注入公钥。
- 公钥必须是 PEM 格式,且不能带密码;私钥务必离线保管,切勿提交进 Git
- Private Packagist 商业版原生支持签名,但需在后台开启「Require signed packages」策略,且只对启用该策略后的新增版本生效
- 若私仓返回 404 给
xxx.zip.sig,Composer 会降级为不校验——这不是 bug,是设计行为,但容易被误认为“已校验通过”
为什么开了 require-signature 还可能漏掉恶意包
签名验证只管包文件完整性,不管代码逻辑是否恶意。一个包可以完全合法签名,但它的 autoload 脚本、scripts 钩子或 post-install-cmd 仍可能执行危险操作。
-
composer.json中的scripts字段不受签名保护,运行时才会执行,此时签名早已验证完毕 - 包内含
install.php或phar并在autoload中动态加载,这类行为完全绕过签名约束 - 依赖树里上游包未签名,下游包即使签名也无济于事——Composer 不做传递性验证
真正起作用的从来不是开关本身,而是你是否定期审查 composer.lock 的变更、是否限制 scripts 自动执行、以及是否把私钥管理当成生产密钥来对待。










