composer如何查看status变更详情_composer lock与json差异对比【审计】

2次阅读

composer status 标记“modified”表示 vendor 中某包源码与 composer.lock 记录的原始压缩包哈希不一致,需用 composer status -v 定位包,再通过 git status 或 diff 对比具体修改;composer.lock 是依赖快照,决定实际安装版本,而 composer.json 仅为版本范围声明。

composer如何查看status变更详情_composer lock与json差异对比【审计】

composer status 显示“modified”但看不出改了哪行

直接跑 composer status 只会告诉你哪些包的源码被改过,不显示具体文件或 diff。它本质是比对 vendor/ 里已安装的代码和原始包发布时的压缩包哈希(来自 composer.lock),一旦有本地修改就标为 modified。

真正要看改了什么,得进对应目录手动对比:

  • 先用 composer status -v 确认是哪个包(比如输出 monolog/monolog modified (1 file)
  • 然后 cd vendor/monolog/monolog,再执行 git status(前提是该包带 .git,很多 packagist 包不带)
  • 更通用的办法:用 diff -r vendor/monolog/monolog ~/.composer/cache/files/monolog/monolog/<hash>.zip.extracted/</hash> —— 但这个路径得自己拼,<hash></hash> 要从 composer.lock 里找 "monolog/monolog" 下的 "dist": {"shasum": "..."}

composer.lock 和 composer.json 的差异不是“配置 vs 锁定”,而是“声明 vs 快照”

composer.json 是你写的依赖声明,比如 "php": "^8.1""guzzlehttp/guzzle": "^7.5",它只管范围,不管具体版本;composer.lock 是某次 composer installupdate 生成的完整快照,记录了每个包的确切版本、下载地址、哈希值、依赖树结构,甚至 autoloader 映射。

关键区别在于:删掉 composer.lock 再跑 composer install,结果可能和原来完全不同——因为 ^7.5 现在可能解析出 7.8.1 而不是之前的 7.5.0,尤其当上游发了新 patch 版本时。

  • composer.json 改了但没 run composer updatecomposer.lock 不变,vendor/ 不更新
  • composer.lock 手动改了(比如调了某个子依赖的 version 字段)→ 下次 composer install 会按新 lock 装,但可能和 composer.json 声明冲突,触发警告
  • CI 环境只跑 composer install(不带 –no-lock)→ 它只认 composer.lock,完全忽略 composer.json 里的 range 声明

审计时发现 lock 文件里有未声明的包,大概率是间接依赖升级带进来的

composer.lock 里出现 symfony/polyfill-mbstring 这种包,但在 composer.json 里找不到,不是误加,而是某个你直接声明的包(比如 symfony/console)在升级后悄悄把它的 require 列表里加了 polyfill —— Composer 会自动拉取整条依赖链,全部记进 lock。

想确认来源,用这个命令:

composer depends symfony/polyfill-mbstring

它会列出谁 require 了它。如果输出为空,说明是 root package 自己 require 的(即你项目里写了),否则就是透传下来的。

  • 这种“幽灵依赖”容易被忽略,但它参与 autoloading、影响攻击面,审计时不能跳过
  • 某些安全扫描工具(如 composer audit)只查 composer.lock,不看 composer.json,所以即使你没直接写,只要 lock 里有就得管
  • 想锁死间接依赖版本?不行。Composer 不支持 pin 二级依赖,只能靠 composer update foo/bar --with-dependencies 控制升级范围

composer update 后 lock 变了但 json 没动,怎么知道哪些包实际升级了

composer update 默认只更新 composer.json 里声明的包及其子依赖,变化全记在 composer.lock。但光看 lock 文件 diff 很难定位“哪个包升了主版本”。用这个组合更准:

  • 先备份旧 lock:cp composer.lock composer.lock.bak
  • composer update --dry-run 看计划升级哪些(但不真实执行)
  • 真实更新后,用 git diff composer.lock.bak composer.lock,重点搜 "version": 行,注意前后双引号里的值,比如 "version": "3.4.2""version": "4.0.0"
  • 更省事:用 composer show -l(list outdated),它只列那些有新版且满足 composer.json range 的包,但不反映实际是否已升级

别依赖 ide 或文本比较工具高亮 JSON 结构——lock 文件里字段顺序不固定,diff 容易误判。老老实实按 version 字段肉眼扫,或者写个简单脚本提取前后 version 对比。

lock 文件的哈希和 dist 信息才是可信锚点,json 里的 caret 或 tilde 版本只是建议。审计时盯着 lock,而不是相信 json 写了什么。

text=ZqhQzanResources