编程 Composer 2.10.3 修掉两条 CVE:Perforce 源地址可注入命令,bin 路径能穿出包目录

2026-10-16 21:03:41

Composer 2.10.3 修掉两条 CVE:Perforce 源地址可注入命令,bin 路径能穿出包目录

Composer 2.10.3(2026-08-27 发布,同步 2.2.30)修了三个安全问题和一批 bug。以下两条带 CVE。

一、恶意 Perforce source URL 导致任意命令执行

GHSA-rvx4-ffvw-m9q3,CVE-2026-84361。

  • Affected:>= 2.3.0, < 2.10.3;>= 1.0, < 2.2.30
  • Patched:2.10.3、2.2.30

装了 p4(Perforce CLI 客户端)时,一个来自「允许任意 perforce source URL 的包仓库」的恶意依赖包,能在 composer install 或 composer update 期间执行任意命令。原因是 Composer 把包的 Perforce source 地址原样交给 p4 CLI,没有校验;而 p4 客户端会把某些地址理解为「执行这个本地命令」,而不是「连接这个服务器」。结果是以运行 Composer 的用户/CI 账号权限执行命令。

同时满足以下条件才受影响:

  • p4 在 PATH 上;
  • 攻击者能控制某个包元数据的 source 段,且 type 为 perforce。packagist.org 不允许 perforce source,所以只有在使用其它 composer 类型仓库、inline package 条目,或来源不可信的 composer.lock 时才可被利用;
  • 包从 source 安装(没有 dist 产物,或选了 --prefer-source)。

明确不受影响:没装 p4 的大多数机器;只用 Packagist 的项目。

修复方式:Composer 在把 Perforce 源地址交给 p4 之前先做校验,只接受真正的网络端点(可选的 tcp/ssl 传输 + host + port),会 spawn 本地进程的地址被拒绝。包在 update 与 install 时都校验失败,且在运行任何 p4 命令之前就报错。注意:如果你的 P4PORT 不是纯 host:port 的合法用法,现在会被拒绝。

升级之外的替代缓解:把 p4 从运行 Composer 但不用 Perforce 的机器 PATH 中移除;把配置的仓库限制在自己控制或信任的来源;把不可信来源的 lock 文件当不可信输入。

二、包 bin 路径可逃出包目录,绕过早前修复

GHSA-96h3-5x6v-m776,CVE-2026-59944。受影响版本与修复版本同上。

恶意或被攻陷的 Composer 包被当作依赖安装时,能让 Composer 修改包自身目录之外某个文件的权限,并注册一个指向该外部文件的、可运行的 vendor/bin 命令。这是路径穿越加链接跟随。

它不是 RCE,攻击者不能直接读或收你的数据;风险是本只有 owner 可读、但 Composer 可改的文件被改成 world-readable 且可执行,在共享/多租户主机上足以泄露内容。它绕过了更早的 GHSA-gjfg-22fp-rrxx 加固——那次只拒绝字面量 .. 段,且只在依赖解析的一处应用。

可能受影响的情形:

  • 依赖包把它声明的某个 binary 以符号链接形式提供,且解析到包自身目录之外,普通 install/update 即可触发;
  • 已安装依赖的元数据 vendor/composer/installed.json 里声明了一个逃出包目录的 binary 路径。Composer 在 install 结尾会依据该元数据重新生成缺失的 binary,重装同一包时也用这份元数据。

第二种只在 vendor 目录不是由同一次(带校验的)install 填充时才可达:例如 vendor 从共享/不可信 CI 缓存恢复、从更早的容器构建阶段拷入、来自 2.10.2/2.2.29 之前的旧 Composer,或被更低信任的构建步骤可写。最现实的中招路径是:在 build/deploy 步骤跑 composer install 且复用了别处产出的 vendor 目录——权限修改是静默执行的,权限是运行 Composer 的用户。

修复方式:Composer 现在会在动文件之前校验每个声明的 binary 是否解析到正在安装的包自身目录内,否则跳过并给出警告。

替代缓解:升级是唯一完整修复。

三、同版本其它修复(2.10.3)

  • Security: 更多位置清理 URL 内嵌的用户名/token(#13044)
  • Security: 修正 gitlab URL 匹配,避免凭据泄露到错误域名(#12988)
  • 修 PHP 8.6 deprecation 警告(#12967、#13028)
  • 策略阻止某包版本时错误输出更清晰(#12993)
  • lock 文件 content-hash 带冲突标记导致运行时坏掉(#13048)
  • 并发跑多个 Composer 进程时创建 cache 目录等的竞态(#12977)
  • Forgejo 空仓库支持(#12968)
  • FilterListApiClient 不转发 transport options(#13040)
复制全文 生成海报 Composer PHP CVE 供应链安全

推荐文章

程序员茄子在线接单