Composer 本身无白名单配置,所谓“白名单”实为外部系统对 Composer 行为的约束,常见于私有仓库、CI/CD 脚本和运行时拦截三类场景。

白名单不是 Composer 的配置项,它属于运行时环境或服务层控制
Composer 本身没有“白名单”这个配置概念。你在 composer.json 或 composer.lock 里找不到 whitelist、allowlist 这类字段,也不存在通过 Composer 命令设置包白名单的机制。所谓“Composer 白名单”,实际是外部系统对 Composer 行为的约束,常见于三类场景:
- 私有仓库(如 Satis、Private Packagist)在
packages.json中只发布被授权的包,未列名的包根本不会出现在元数据里 - CI/CD 流水线脚本在
composer install前用grep或jq检查composer.lock,拒绝含非白名单 vendor 的提交 - PHP 运行时拦截(如自定义 autoloader 或 opcache 预加载)限制只能加载指定路径下的类文件,和 Composer 自动加载顺序无关
新项目接入时,白名单逻辑必须早于 composer install 执行
如果你在项目初始化阶段就要 enforce 白名单策略,关键点在于:它不能依赖 Composer 加载完成后再生效。否则攻击者可能通过篡改 composer.json 注入恶意包,而你的检查已错过时机。
- 先写 CI 脚本或 pre-commit hook,用
jq '.packages[] | select(.name | startswith("malicious/"))' composer.lock快速扫描非法包名 - 在
composer create-project后、git add前,运行白名单校验脚本;失败则exit 1,阻断后续流程 - 若用私有源,确保
repositories数组顶部已设{"packagist.org": false},且私有源的packages.json确实不包含非授权包——否则 Composer 会跳过白名单直接从 packagist 下载
files 自动加载和白名单没关联,但容易被误用
有人试图把白名单逻辑塞进 "autoload": {"files": [...]},这是危险操作。因为 files 列表里的脚本会在 vendor/autoload.php 初始化时无条件执行,一旦其中某文件抛出 ParseError 或调用 die(),整个自动加载器崩溃,所有类都不可用。
-
files只适合加载全局函数、常量或简单引导逻辑,不适合做安全校验 - 白名单校验应放在 CLI 入口(如
bin/deploy)、CI 阶段或 Web Server 配置层(如 Nginx 的location ~ ^/(?!whitelist|api).*) - 若真要在 PHP 层做运行时白名单,应在
index.php开头手动 require 校验脚本,并用register_shutdown_function()捕获 fatal error,而不是依赖 autoload 机制
最容易被忽略的一点:白名单校验必须覆盖 lock 文件哈希
很多团队只校验 composer.json 中的 require 字段,却忽略 composer.lock 里的 content-hash 和具体包版本哈希值。攻击者可保留合法包名,但替换其 dist.shasum 指向恶意构建产物——这种篡改不会触发 JSON 格式校验,但会使 lock 文件失效。真正可靠的白名单,要解析 lock 文件中每个包的 dist.url 和 dist.shasum,比对可信源签名或预存哈希表。


















