thinkphp权限绕过漏洞本质是路由解析失控、控制器/方法名过滤不严、调试参数残留三者叠加导致访问控制失效,典型路径为s参数或_method参数绕过中间件直接调用高危方法,须通过入口过滤、request类加固、禁用自动路由三层拦截,并关闭app_debug、限制日志访问、禁用危险函数方可彻底修复。

ThinkPHP权限绕过漏洞本质不是单一缺陷,而是多个配置与逻辑短板叠加导致的访问控制失效。最常见的是路由解析失控、控制器/方法名过滤不严、调试参数残留三者共同作用,让攻击者跳过权限中间件直接调用高危方法。
典型绕过路径:从s参数到任意方法执行
在TP5.0.x(≤5.0.23)和TP3.2.x中,s参数(如 ?s=index/\think\app/invokefunction)可被解析为控制器路径。框架未严格校验反斜杠\是否属于合法命名空间分隔符,导致攻击者穿越类层级,直接调用think\App::invokeFunction等内部方法。该过程绕过了所有路由规则、中间件和权限检查,相当于“抄近道进后门”。
类似地,_method参数(如 _method=__construct&filter[]=system)可触发Request类方法覆写,再结合filter参数将用户输入送入system()执行——整个链路完全脱离权限系统管控。
关键修复动作:阻断入口 + 收紧解析
不能只靠升级,必须同步做三层拦截:
-
入口文件过滤:在
public/index.php中,于define('APP_PATH',...)之后加入参数拦截逻辑,直接拒绝含s、_method、filter、vars且值中含\think\或危险函数名的请求,返回403 -
Request类加固:修改
thinkphp/library/think/Request.php中的method()方法,对$_POST[Config::get('var_method')]值强制白名单校验(仅允许GET/POST/PUT/DELETE/PATCH),非法值一律设为POST并清空对应参数 -
禁用自动路由与空操作:TP3.2.3在
Conf/config.php中设置'URL_ROUTER_ON'=>true并关闭MODULE_ALLOW_LIST;TP5.0.24在route.php中关闭auto_route,所有接口必须显式定义路由,不响应任何动态拼接路径
常被忽略的配置雷区
很多团队修复后仍被攻破,问题出在“修代码却没关开关”:
- APP_DEBUG=true未关闭:调试模式下会输出完整错误堆栈,暴露路径、类名、数据库结构,为绕过提供线索
-
日志目录可Web访问:如
Runtime/Logs/或runtime/log/未通过Nginx/Apache限制(例如缺少location ~ ^/runtime/.*\.(log|php)$ { deny all; }),攻击者可直接下载日志获取密钥、SQL语句、临时token -
危险函数未禁用:生产环境应通过
disable_functionsPHP配置项禁用exec,passthru,shell_exec,system,proc_open,popen,eval,而非依赖框架层过滤
验证是否真正修复
修复完成后,务必手动测试以下三类请求是否全部返回403或空响应:
GET /index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfoPOST /index.php _method=__construct&filter[]=phpinfo&server[REQUEST_METHOD]=1-
GET /index.php?debug=1(检查是否仍输出调试信息)
同时确认Runtime/Logs/目录无法通过浏览器直接访问,且opcache_reset()已执行以清除旧字节码缓存。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











