vendor目录必须只读,因为php运行时仅需读取类文件和autoload逻辑,写权限会放大安全风险并破坏部署一致性;正确做法是分层设权:归属部署用户、文件644、bin目录可执行、组权限g+rx,且ci/cd需避免uid/gid污染。

vendor 目录为什么必须只读?
因为 PHP 运行时(如 Nginx + PHP-FPM)只需读取 vendor 中的类文件和 autoload 逻辑,写权限既无必要,又直接放大安全风险:一旦应用存在任意代码执行漏洞,攻击者就能覆盖 vendor/composer/autoload_static.php 或注入恶意类;CI/CD 流水线若意外触发 composer dump-autoload 或 post-install 脚本,还会破坏部署一致性。Laravel、Symfony 等主流框架默认将 vendor/ 视为不可变资产,storage/ 和 bootstrap/cache/ 才是合法可写目录。
怎么设才真正安全?别用 chmod -R 755 或 555
粗暴执行 chmod -R 755 vendor/ 会让所有 PHP 类文件可执行,违反最小权限原则;chmod -R 555 vendor/ 则会阻断 PHP 进程进入子目录(缺少执行位),导致 opendir() 失败。正确做法是分层控制:
- 先确保归属正确:
chown -R deploy:deploy vendor/(deploy是部署用户) - 递归关闭所有文件的写权限:
find vendor/ -type f -exec chmod 644 {} \; - 仅对明确需执行的二进制放行:
chmod +x vendor/bin/* 2>/dev/null || true - 保留
vendor/composer/autoload_classmap.php可写(如项目依赖动态类映射),否则预生成后设为 644
web 服务器用户(如 www-data)没权限读 vendor 怎么办?
不要给 www-data 写权限,也不要把 www-data 设为 vendor/ 属主。标准解法是让 web 服务器用户加入部署用户组:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 执行:
usermod -a -G deploy www-data - 确保
vendor/目录组权限为r-x(即 755):chgrp -R deploy vendor/ && chmod -R g+rx vendor/ - 验证:
sudo -u www-data ls -l vendor/autoload.php应能成功列出
如果 ls -ld vendor/ 显示属组不是 deploy,或组权限不含 r-x,PHP-FPM 就会报错“Permission denied”。
CI/CD 部署后 vendor 权限异常,常见源头在哪?
问题往往不出在命令本身,而在 UID/GID 不一致或缓存继承:
- Docker 构建时用
USER root运行composer install→ 镜像里vendor/属主是root,但运行时 PHP-FPM 以www-data启动,读不到 - GitHub Actions 的
cache: composer解压后文件继承上一次构建的root属主 - WSL 用户挂载 NTFS 分区(如
/mnt/c)默认不支持chmod,需在/etc/wsl.conf中启用metadata=true
修复关键点不是反复 chmod,而是切断污染链:Dockerfile 里优先 USER appuser;CI 脚本开头加 chown -R $GITHUB_ACTOR:$GITHUB_ACTOR vendor/;本地开发避免用 sudo composer install。










