vendor目录被篡改时,composer status是最快验证手段,但需配合--dry-run和verify-checksums --strict定位真实问题:status仅比对lock哈希与vendor状态,-v显示具体差异;verify-checksums --strict(需COMPOSER_EXPERIMENTAL=1)才真正校验文件字节流SHA256;--dry-run只确认lock可复现性,不校验内容完整性;autoload.php等关键生成文件在校验体系外,须设vendor为只读防范篡改。

vendor 目录被篡改时,composer status 是最快验证手段,但必须配合 --dry-run 和 verify-checksums --strict 才能定位真实问题。
composer status 显示 modified 不代表你动了代码
它只说明 vendor/ 下某个包的当前文件状态与 composer.lock 中记录的哈希不一致——可能是你手动改了,也可能是:
- 包自身 post-install-cmd 脚本写入了缓存(如 Symfony 的
var/cache/)或生成文件(如vendor/composer/autoload_static.php) - Git 忽略规则没覆盖
vendor/下某些临时目录,导致status把未跟踪文件也纳入比对 - 你之前用过
composer install --no-scripts,某些包没执行安装后逻辑,导致生成文件缺失,也被标为 “modified” - CI 环境里有人手改了
vendor/但没提交,status就是为此类误操作设的兜底检查
加 -v 参数能直接看到哪些文件被标为 modified:composer status -v。没有输出 ≠ 没运行,而是返回码为 0,表示 clean。
verify-checksums --strict 是唯一真校验磁盘文件哈希的方式
composer install 只校验下载压缩包的 dist.sha256,解压落地后就不管了;而 verify-checksums --strict 是真读 vendor 目录下每个文件的原始字节流,归并后算 SHA256,再跟 composer.lock 里的 dist.sha256 字段比对。
但它不是默认可用命令,必须显式启用实验模式:
- 不设环境变量:
COMPOSER_EXPERIMENTAL=1 composer verify-checksums --strict - 不加
--strict:即使发现 mismatch 也只警告,退出码仍是 0,CI 会误判成功 - 跳过
type: "path"本地依赖、无dist.sha256字段的老包、以及vendor/composer/autoload_*.php这类生成文件 - 若 CI 中用了
--prefer-source,走 git clone,那包根本没dist.sha256,此命令直接跳过
composer install --dry-run 是确认 lock 文件可复现的底线检查
它不碰 vendor/,只模拟安装流程,检查 composer.lock 是否仍能完整还原依赖树。输出 “Nothing to install or update” 才说明 lock 与当前 vendor 完全一致。
但要注意:
- 它不校验文件内容是否被篡改,只校验“能否按 lock 装”——如果 vendor 里某包被恶意替换成同名同版本但内容不同的 zip,
--dry-run依然会通过 - 更严格的做法是先清缓存再重拉:
composer clear-cache && composer install --no-cache --dry-run,强制排除本地缓存干扰 - CI 流水线中应把它作为三重验证之一,和
composer validate --strict、composer audit --dev --severity=critical,high串联执行
真正被忽略的校验盲区:autoload.php 和只读权限
verify-checksums --strict 会扫描 vendor/autoload.php,但它在 composer.lock 中没有哈希记录;你手动改它,校验就会失败——但没人会想到去动这个文件,所以它成了隐蔽篡改点。
生产部署前必须补这一步:
- 把整个
vendor/目录设为只读(Linux/macOS:chmod -R a-w vendor/),防止运行时写入篡改 -
vendor/autoload.php被修改后不会触发composer dump-autoload自动恢复,得靠只读权限硬拦 - 别指望
composer status或--dry-run能覆盖这个场景——它们都不校验 autoload.php 的完整性


















