必须升级到6.3+,因其引入统一参数解析层、禁用动态类名反射、默认关闭__call自动映射,并增强Db::raw()和闭包查询的注入检测,彻底修复6.0.0–6.0.13中多语言模块、Zhl标签库等已知SQL注入与RCE漏洞。

直接升级到 ThinkPHP 6.3.x 或更高版本是当前最稳妥的修复方式;内置过滤机制(如 where 参数绑定)只在你不破坏它时才生效,一旦手动拼接 SQL 字符串,防护就形同虚设。
为什么必须升级到 6.3+?
ThinkPHP 6.0.0–6.0.13 存在多个已知 SQL 注入路径,比如多语言模块中 think_lang 参数触发的目录穿越+文件包含,进而调用 pearcmd 实现 RCE;又如模板标签库(Zhl.php)中硬编码拼接 $keywords 到 like 条件里。这些漏洞在 6.1.0 后陆续修复,但真正收敛是在 6.3.0 引入统一参数解析层和禁用动态类名反射之后。
关键点:
- 6.3+ 默认关闭
__call对控制器方法的自动映射,堵住?s=index/thinkpp/invokefunction类攻击入口 - 模板引擎中
Db::raw()和闭包查询的变量注入检测增强,对\think\前缀字符串做更早拦截 - 不再默认加载
topthink/think-template的扩展标签库(如Zhl),避免第三方标签中手写 SQL 的失控风险
where 方法防注入失效的典型场景
where 方法本身安全,但开发者常因“图快”主动破坏它。日志里出现 WHERE name = 'admin' OR 1=1 -- ' 就是典型信号。
立即学习“PHP免费学习笔记(深入)”;
常见错误写法:
-
$model->where("name = '$name'")->select()—— 单引号包裹 + 变量插值,PDO 绑定完全跳过 -
$model->where('name', 'like', '%' . input('keyword') . '%')->select()——input()未过滤,%放大恶意 payload -
Db::query("SELECT * FROM user WHERE status = $status")—— 原生 SQL 拼接,零防护
正确姿势:
- 固定字段:用
$model->where('name', $name)->select()或$model->where(['name' => $name])->select() - 模糊查询:优先用
whereLike,或显式绑定:$model->where('name', 'like', "%{$keyword}%")->select()(注意:%要由 PHP 拼,不是 SQL 里写) - 原生 SQL:只用
?占位符,且仅顺序绑定:Db::query("SELECT * FROM user WHERE status = ? AND type = ?", [$status, $type])
动态字段/排序/分组必须白名单校验
ORDER BY、GROUP BY、表名、字段名无法用 ? 占位,ThinkPHP 不处理这些位置的绑定,必须靠代码层兜底。
例如排序参数来自 URL:?sort=id&order=desc
- ❌ 错误:
$model->order($sort . ' ' . $order) - ✅ 正确:
in_array($sort, ['id', 'create_time', 'status']) && in_array($order, ['asc', 'desc']) ?: die('非法参数');再拼接
同样适用于 Db::raw() 中的字段引用:Db::raw("JSON_EXTRACT(data, '$.{$key}')") 必须先校验 $key 是否在 ['title', 'content', 'tags'] 白名单内。
别信“加个 addslashes 就安全了”
知识库中提到的 str_replace("'", "\'", $keywords) 是典型误区。MySQL 在宽字节、多字节编码(如 GBK)下,%A1%BF 可绕过单引号转义;且现代攻击常用 UNION SELECT、UPDATEXML 等不依赖引号的技巧。
真正有效的过滤只有两种:
- 白名单校验(字段、方法、路由标识等静态结构)
- 参数绑定(所有用户输入进 SQL 值的位置)
其余所谓“过滤函数”(addslashes、mysql_real_escape_string、正则替换)在复杂上下文里极易失效,且会干扰正常业务数据(比如用户真想搜 O'Reilly)。
最后提醒一句:whereLike 自动转义 % 和 _,但不会帮你校验字段是否合法——那个 extra 字段如果来自用户可控输入,依然得先过白名单。



















