thinkphp线上安全需严控app_debug、路由方法、输入过滤、文件上传四环节:关闭调试模式后须验证运行时值;路由必须显式限定http方法;数据库查询前强制类型转换和白名单校验;上传文件须重命名、多层类型校验并存至非web目录。

关闭调试模式后还要检查 APP_DEBUG 是否真被覆盖
线上环境只要 APP_DEBUG 是 true,就等于把路由、数据库错误、变量 dump 全部暴露给攻击者。很多人改了配置文件却没生效,是因为环境变量或命令行启动时被重新设定了。
实操建议:
- 在入口文件
public/index.php顶部加一行var_dump(\think\Env::get('app_debug'));,确认运行时值 - 检查是否在
.env文件里写了APP_DEBUG=true,它会优先于config/app.php - 用
php think run启动时,命令行参数如--debug也会强制开启调试,上线必须禁用
Route::rule() 要显式限制 HTTP 方法,别依赖默认行为
ThinkPHP 的路由规则如果不指定方法,默认允许所有请求方式,容易被绕过权限控制,比如把 POST 接口用 GET 直接访问导致数据泄露。
实操建议:
- 所有敏感路由必须写明方法,例如:
Route::rule('api/user', 'api.User/info', 'GET'); - 避免用
Route::any(),除非你明确需要多方法共用且已做内部校验 - 批量注册时,用
Route::resource()要注意它默认开放全部 REST 动作,删掉不用的,比如destroy或create
数据库查询前必须过滤 input(),不能只靠模型验证
模型的 validate 只在 save() 或 allowField() 场景起作用,而 where()、find() 等直接拼条件时,如果用了原始 input('id'),就可能触发 SQL 注入。
实操建议:
- 查单条记录时,优先用
find(input('id/d')),/d表示强制转整型,比字符串拼接安全 - 模糊搜索用
like时,手动过滤通配符:str_replace(['%', '_'], '', input('keyword')) - 禁止在
where()中直接拼接未处理的input('order'),排序字段必须白名单校验,例如:in_array(input('order'), ['id', 'create_time']) ? input('order') : 'id'
上传文件必须重命名 + 限制类型 + 独立目录,三者缺一不可
ThinkPHP 的 move() 默认保留原文件名,如果用户传个 shell.php.jpg,再配合 Nginx 解析漏洞或 .htaccess 绕过,就能直接执行代码。
实操建议:
- 上传后必须用
uniqid() . mt_rand(100, 999)生成新文件名,不要用getClientOriginalName() - 类型校验不能只看
getOriginalExtension(),要结合getMimeType()和finfo_file()检测真实内容 - 上传目录不能放在
public/下,必须设为runtime/upload/这类非 Web 可访问路径;若必须公开,Nginx 需加location ~ \.(php|exe|sh)$ { deny all; }
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










