禁用高危函数有效但不充分;需结合模板引擎白名单、目录权限锁定(runtime 755 且禁执行、public 上传目录禁 php)、.env 文件 web 层屏蔽、关闭 debug/trace 并保护日志。

禁用 eval、assert、system 等高危函数是否有效?
禁用本身有效,但仅靠 disable_functions 不足以防御所有执行类攻击。ThinkPHP 的模板引擎(如 think-template)在开启 tpl_deny_func 时会主动拦截模板中调用的危险函数;而 PHP 自身的 disable_functions 是底层限制,对通过反射、动态类名、call_user_func 绕过的情况无能为力。
实操建议:
- 在
php.ini中设置:disable_functions = eval,assert,system,exec,passthru,shell_exec,proc_open,popen,dl,pcntl_exec - 确保 ThinkPHP 配置中启用模板函数白名单:
'tpl_deny_func' => ['eval', 'assert', 'system'](5.1+ 版本默认已设) - 重启 PHP-FPM 或 Apache 后,用
php -i | grep disable_functions验证生效 - 注意:禁用
dl会影响某些扩展加载,若使用 Swoole 或 Redis 模块需确认兼容性
如何锁定 runtime 和 public 目录的写入权限?
ThinkPHP 的 runtime 必须可写(日志、缓存、模板编译),但不应允许执行;public 是 Web 入口,应只读(除上传目录外)。常见错误是直接给整个 runtime 目录加 777,导致恶意文件被上传并执行。
实操建议:
-
runtime/目录保持755,属主为 Web 进程用户(如www-data或nginx),但禁止该用户执行其中任意文件:chmod -R a-x runtime/ -
public/整体设为755,上传目录(如public/uploads/)单独设为755并配置 Web 服务器禁止执行 PHP:location ~ ^/uploads/.*\.php$ { deny all; } - Linux 下用
chattr +a runtime/可防止误删,但不防写入;更严格可用chattr +a +i锁定关键子目录(如runtime/log/),但需运维手动解锁才能写日志
为什么 .env 文件被 Web 访问会导致密钥泄露?
ThinkPHP 5.1+ 默认从 .env 加载数据库密码、app_debug、app_key 等敏感配置。如果 Web 服务器未屏蔽该文件,攻击者直接请求 http://yoursite.com/.env 就能下载全部配置——这是真实发生过的批量入侵入口。
实操建议:
- Nginx 配置中必须包含:
location ~ /\.env { deny all; } - Apache 需确保
.htaccess生效,并在项目根目录添加:RedirectMatch 403 /\.env$ - 验证方式:curl -I http://localhost/.env,返回 403 即正常;返回 200 或 404(而非 403)都说明规则未命中
- 额外加固:将
.env移出 Web 根目录(如放到/data/config/app/.env),并在index.php中显式指定路径:DotEnv::load('/data/config/app/.env');
ThinkPHP 自带的 app_debug 关闭后还可能暴露信息吗?
关闭 app_debug = false 能隐藏堆栈、SQL 错误详情,但不等于零信息泄露。比如路由未定义时仍会返回 404 页面中的框架标识;开启 app_trace 或使用调试工具(如 think\facade\Debug)也可能输出上下文;更隐蔽的是,部分中间件或钩子在异常捕获阶段仍可能把变量 dump 到日志里。
实操建议:
- 生产环境必须确保
app_debug = false且app_trace = false,并在部署脚本中加入校验:grep -q "app_debug.*true" config/app.php && echo "ERROR: debug enabled!" - 检查
runtime/log/权限,避免日志文件被 Web 访问(Nginx 中加location ^~ /runtime/log/ { deny all; }) - 禁用开发专用服务:删除或重命名
server.php,移除think run命令依赖,防止被当作调试入口启动内置服务器
真正难处理的是混合场景:比如用了第三方 SDK,它内部调用 create_function 或 unserialize,而你既不能改 SDK 源码,又无法预知其行为。这时候函数禁用只是第一道门,目录隔离和 Web 层访问控制才是兜底手段。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











