ThinkPHP 的 runtime 和 vendor 目录必须移出 Web 根目录并配置服务器禁止访问,否则敏感信息可能泄露;推荐路径隔离优先,辅以 Nginx/Apache 显式拒绝规则,部署后须验证 403/404 响应。

ThinkPHP 的 runtime 和 vendor 目录绝不能被 Web 服务器直接访问,否则日志文件、缓存内容、数据库凭证、SQL 原文、Composer 依赖结构等敏感信息可能被下载或读取,造成严重安全风险。禁止访问不是“可选优化”,而是上线前必须完成的基础防护。
核心原则:路径隔离优先,Web 层拦截兜底
最可靠的方式是把 runtime 和 vendor 移出 Web 根目录(如 Nginx 的 root 或 Apache 的 DocumentRoot),从源头上消除可访问性。如果受环境限制无法移出(例如部分共享主机),再通过 Web 服务器配置显式拒绝访问。
确保 runtime 目录不在 Web 可访问路径下
- 不要放在
public/下,也不要放在网站根目录(如/htdocs/runtime、/www/runtime); - 推荐路径示例:
/data/www/myapp-runtime/(Linux)或D:\www\runtime\(Windows),确保该路径不在 Web 服务器任何root、alias或location配置范围内; - 在
public/index.php最顶部(早于requireautoload)定义:define('RUNTIME_PATH', '/data/www/myapp-runtime/'); - 定义后手动创建目录,并赋予 Web 进程用户(如
www-data、nginx、IIS_IUSRS)读写权限(Linux 建议755目录 +644文件;Windows 检查 ACL); - 删除旧
runtime/目录,让框架重建,避免路径残留导致缓存错乱。
用 Web 服务器配置彻底屏蔽 vendor 和 runtime 访问
Nginx 配置(推荐加在 server 块内)
location ^~ /runtime {
deny all;
}
location ^~ /vendor {
deny all;
}
# 如果项目根目录还包含其他敏感目录,一并禁止
location ^~ /application { deny all; }
location ^~ /config { deny all; }
location ^~ /route { deny all; }
location ^~ /extend { deny all; }⚠️ 注意:^~ 表示前缀匹配且优先级高于正则,比 location ~ /runtime 更稳妥,防止绕过。
Apache 配置(放入项目根目录 .htaccess,需开启 mod_rewrite)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^runtime - [F,L]
RewriteRule ^vendor - [F,L]
RewriteRule ^application - [F,L]
RewriteRule ^config - [F,L]
RewriteRule ^route - [F,L]
RewriteRule ^extend - [F,L]
# 常规重写规则放最后
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>✅ 确保 .htaccess 文件本身未被禁用(Apache 需设置 AllowOverride All)。
补充加固手段(非替代,但建议启用)
- 关闭调试模式:
config/app.php中设'app_debug' => false; - 禁用危险模块访问:在
config/app.php的deny_module_list中加入'runtime', 'vendor'(注意该配置仅对 ThinkPHP 路由层生效,不能替代 Web 层拦截); - 若使用 CLI 或 Swoole,确认
RUNTIME_PATH在所有运行模式下一致(入口文件定义最可靠); - 部署后主动测试:访问
https://yoursite.com/runtime/log/和https://yoursite.com/vendor/autoload.php,应返回 403 或 404,而非文件内容或目录列表。
不复杂但容易忽略。
立即学习“PHP免费学习笔记(深入)”;



















