根本原因是Composer依赖系统临时目录(如/tmp),当该目录全局可写且被恶意用户劫持时,插件或旧版本可能通过符号链接导致任意文件覆盖;应设TMPDIR为用户专属路径(如$HOME/.cache/composer/tmp)并chmod 700,禁用不安全插件。

为什么 Composer 会因临时目录引发权限提升?
根本不是 Composer 主程序本身有漏洞,而是它在某些场景下(尤其是旧版本或插件介入时)会把临时文件写到全局可写的路径(比如 /tmp),而这些路径若被恶意用户提前创建同名符号链接或劫持,就可能让后续的 file_put_contents() 或 rename() 操作覆盖任意位置的文件——典型如覆盖 vendor/bin/xxx 或写入 webroot 下的 PHP 文件。
这个问题在以下情况更易触发:
- 使用了过时的插件(如
hirak/prestissimo1.x 版本) - 系统
/tmp目录权限为1777(sticky bit + world-writable),但未启用noexec或nosuid - 在共享主机或容器中运行,且未隔离
TMPDIR - 调用
composer install --no-plugins成功,但默认执行失败 → 基本锁定是插件在/tmp创建 socket 或缓存后未清理权限
如何确认是否正在用不安全的临时目录?
直接查 Composer 实际使用的临时路径:
php -r "echo sys_get_temp_dir().PHP_EOL;"
再检查该路径归属和权限:
ls -ld $(php -r "echo sys_get_temp_dir();")
如果输出类似 drwxrwxrwt 1 root root 4096 ... /tmp,且你不是 root,那问题就在这里——Composer 默认信任系统临时目录,但没做路径校验。
常见风险信号:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 报错里出现
/tmp/composer_*、/tmp/pear/install等路径 -
strace -e trace=openat,open,creat composer install 2>&1 | grep tmp显示大量/tmp写入 - 插件文档明确提到“使用系统临时目录缓存下载”
怎么强制 Composer 使用安全临时目录?
不让它碰 /tmp,改用当前用户专属路径:
- 设置环境变量:
TMPDIR="$HOME/.cache/composer/tmp"(推荐) - 创建并授权:
mkdir -p "$HOME/.cache/composer/tmp" && chmod 700 "$HOME/.cache/composer/tmp" - 验证生效:
TMPDIR="$HOME/.cache/composer/tmp" composer install --dry-run,再用strace确认无/tmp调用 - 永久生效:加到 shell 配置(如
~/.bashrc):export TMPDIR="$HOME/.cache/composer/tmp"
注意:COMPOSER_CACHE_DIR 控制的是包缓存,不影响临时解压行为;只有 TMPDIR 才能接管 sys_get_temp_dir() 返回值。
哪些版本和插件需要特别注意?
Composer 自身从 2.2.0+ 起已默认规避部分符号链接攻击,但不等于完全免疫。真正高危的是:
-
hirak/prestissimo≤ v0.3.7:在/tmp创建 Unix socket,且未设umask(0077) -
composer/installers≤ v1.10.0:某些 post-install 脚本用tempnam()未指定目录 - 自定义脚本中调用
proc_open()或shell_exec("unzip ...")且未清理TMPDIR
修复建议:
- 升级插件:
composer global update hirak/prestissimo(新版已弃用 socket,改用内存缓存) - 禁用可疑插件测试:
composer install --no-plugins,成功则逐个启用排查 - CI/CD 中显式声明:
TMPDIR=/dev/shm(若支持)或TMPDIR=$(mktemp -d)+trap 'rm -rf $TMPDIR' EXIT
最麻烦的不是改配置,而是某些插件会在首次运行时静默创建 /tmp/composer-xxx 目录并留空权限位——删掉 /tmp/composer-* 后必须重启进程,否则旧句柄仍指向不安全路径。

















