Composer 2.2+ 的 allow-plugins 是精确包名白名单,禁用通配符;设为 true 或使用 "*": true 会彻底关闭安全机制;必须结合 --no-plugins、conflict 等多重措施保障构建安全。

allow-plugins 白名单必须显式写包名,不能用通配符
Composer 2.2+ 默认拒绝所有插件执行,allow-plugins 不是开关,而是白名单。设成 true 等同于完全关闭安全机制,任何依赖(包括间接依赖)都能执行任意代码。
常见错误是试图用 "*": true 或 "vendor/*": true 绕过限制——这些写法会被 Composer 忽略,不生效。白名单只接受精确的包名,例如:
"symfony/flex": true"laravel/pint": true"phpstan/extension-installer": true
没列进来的包,哪怕只是 dev-dependency,也会被静默禁用。运行 composer install 时若报错 “Plugin … is not allowed”,说明它不在白名单里,不是配置漏了,就是该插件根本不该存在。
加插件前必须验证来源和行为,不能只看是否报错
看到 Plugin … is not allowed 就往 allow-plugins 里加一行,是最危险的操作。插件在构建期拥有完整执行权:能改 autoload、劫持下载、写入任意路径、调用 exec()。
确认是否真要授权,得查三件事:
- 去 Packagist 页面看是否有 Verified 标识,LICENSE 是否为 MIT/Apache-2.0,GitHub stars ≥ 500 且近 6 个月有活跃提交
- 运行
composer show vendor/name,确认输出含Plugin字样;再翻源码,重点搜exec(、eval(、file_put_contents(和敏感路径如/etc/、/var/www - 检查它是否真的被项目需要:比如
symfony/flex是 Symfony 项目必需,但some-random-migration-tool可能只是某次临时调试引入,早该删了
--no-plugins 是生产环境硬性要求,不能靠“记得加”
--no-plugins 必须出现在每条生产命令末尾:composer install --no-plugins ✅,而 composer --no-plugins install ❌(等价于 composer --help)。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
CI/CD 脚本里绝不能写“开发者自行添加”,必须写死。哪怕用了封装脚本(如 bin/composer),也要确保它没偷偷注入 --plugins 或其他 flag。
它和 --no-scripts 不冲突,推荐组合使用:composer install --no-plugins --no-scripts --no-dev --prefer-dist。这个组合只解压依赖、生成 autoload,不执行任何第三方逻辑——这才是构建可信性的底线。
conflict 配合 allow-plugins 才算真正防混淆
仅靠 allow-plugins 白名单,防不住“合法插件干坏事”。比如某个被授权的插件悄悄 require 了一个恶意包,而那个包又带另一个未授权插件——allow-plugins 挡不住二级加载。
这时 conflict 就起作用了:在 composer.json 中声明:
"conflict": {
"malicious/package": "*",
"known-bad-plugin": ">=1.2.0"
}
它会在依赖解析阶段直接中断安装,比 runtime 报错更早、更彻底。注意:conflict 是全局生效的,哪怕你没 require 它,只要其他依赖拉进来就会触发。
容易忽略的是:conflict 不解决已安装的坏包。上线前必须跑一次 composer update --dry-run,确认没有被 conflict 拦截的包混进依赖树。

















