日志文件被直接下载或读取是因Web服务器未屏蔽runtime目录所致,需通过Nginx/Apache配置禁止访问、迁移日志路径至Web根目录外并清理残留文件。

日志文件被直接下载或读取的典型表现
访问 /runtime/log/202405/xxx.log 能直接看到明文日志,甚至包含 SQL 语句、用户 token 或调试堆栈——这不是配置疏漏,是默认 Web 服务器未屏蔽日志目录导致的常见泄露。ThinkPHP 本身不提供 HTTP 层防护,靠的是 Web 服务(Nginx/Apache)和目录权限协同控制。
Nginx 下禁止访问 runtime 目录的必须配置
仅靠 deny all 不够,要覆盖所有可能入口路径(如带点的隐藏文件、无后缀日志、.log/.php 结尾等)。以下配置需放在站点 server 块内,且位置在 root 指令之后、location ~ \.php$ 之前:
location ^~ /runtime/ {
deny all;
}
location ~ ^/runtime/.*\.(log|txt|trace|swp|swo|lock)$ {
deny all;
}
注意:^~ 优先级高于正则,能避免被后续 location ~ \.php$ 意外匹配到;deny all 对空请求也生效,比 return 403 更稳妥。
Apache 的 .htaccess 防护与权限陷阱
ThinkPHP 官方推荐在 runtime 目录下放 .htaccess,但实际生效依赖 Apache 的 AllowOverride All 配置。若没开,该文件完全被忽略。更可靠的做法是直接在虚拟主机配置中限制:
立即学习“PHP免费学习笔记(深入)”;
- 确保
runtime目录不在 DocumentRoot 下(最佳实践是移到 Web 根目录之外) - 若必须放在 Web 可见路径下,用
<Directory "/path/to/runtime"> Require all denied </Directory> - 避免 chmod 777 ——
755对目录足够,日志文件应为644,且属主是 Web 进程用户(如 www-data),不是 root
ThinkPHP 自身日志路径可迁移,但别只改 config
修改 app/extra/log.php 中的 path 项只是第一步。如果新路径仍在 Web 可访问范围内(比如还放在 public/runtime),泄露风险照旧。真正安全的迁移方式是:
- 把日志目录设到
/var/log/thinkphp/或项目根目录外的独立路径 - 确认 Web 进程用户对该路径有写权限(
chown www-data:www-data /var/log/thinkphp) - 检查
log.php中type为File时,path值末尾带斜杠,否则可能写到错误位置 - 重启 PHP-FPM 或 Web 服务,否则缓存可能导致旧路径还在写日志
最常被忽略的一点:日志路径变更后,旧 runtime/log/ 目录可能仍残留敏感文件,得手动清空或加一层额外屏蔽。


















