ThinkPHP 5.0.22 RCE漏洞需三重手动修复:控制器名白名单正则校验、HTTP方法硬性限制、入口文件敏感词拦截,并关闭app_debug、auto_route等高危配置。

ThinkPHP 5.0.22 的 RCE 漏洞不能靠“打一个补丁”就解决,官方未发布独立热补丁,仅靠升级到 5.0.23 或更高版本也不保险——若配置未同步调整、入口未加固、参数未过滤,漏洞仍可被绕过。实际修复必须手动植入三类关键代码,并配套关闭高危配置。
控制器名白名单校验
在框架入口或路由解析关键路径(如 think\App::module() 方法中),获取 $controller 后立即加入严格正则校验:
- 检查控制器名是否只含字母开头、后续为字母/数字/下划线/点号
- 不符合则直接抛出 404 异常,阻断后续执行
if (!preg_match('/^[A-Za-z][A-Za-z0-9_.]*$/', $controller)) {
throw new HttpException(404, 'controller not exists: ' . $controller);
}HTTP 方法参数安全加固
修改 think\Request::method() 方法,对 $_POST[Config::get('var_method')](默认是 _method)的值做硬性限制:
- 只允许
GET、POST、PUT、DELETE、PATCH五种标准方法 - 其他任何输入(如
__construct、system)一律降级为POST,不执行反射调用
入口文件前置拦截高危请求
在 public/index.php 最顶部(require 框架前)插入检测逻辑:
- 扫描
$_GET['s']是否包含\think\、invokefunction、call_user_func等敏感关键词 - 一旦命中,立即
die('Access Denied'),不进入框架流程
必须关闭的危险配置项
以下配置需在 config/app.php 中显式设为安全值:
-
'app_debug' => false(禁用调试模式,防信息泄露) -
'url_route_on' => true且'route_complete_match' => true(启用完整匹配路由) -
'auto_route' => false(禁止自动搜索控制器) -
'var_method' => ''(清空 method 变量名,废掉_method利用链)
修复完成后,务必用原始 payload 测试响应:
-
?s=index/\think\app/invokefunction&function=system&vars[1][]=id→ 应返回 404 或空白页 -
POST _method=__construct&filter[]=system→ 应无法触发变量覆盖
不复杂但容易忽略



















