ThinkPHP 5.1.0–5.1.21 存在 ORDER BY 注入漏洞,因未校验排序字段白名单,直接拼接用户输入至 order() 方法所致;修复需严格限定字段与方向或升级至 5.1.40+。

ThinkPHP 5.1.21 存在的 ORDER BY 注入漏洞,本质是框架未对排序字段做白名单校验,当开发者直接将用户输入(如 URL 参数、POST 数据)拼入 order() 方法时,可能绕过过滤导致 SQL 注入。该问题在 5.1.x 系列中广泛存在,尤其在未启用严格参数绑定或手动拼接排序语句的场景下风险突出。
确认是否受影响
需同时满足两个条件:
- 使用了 ThinkPHP 5.1.0 至 5.1.21(含)版本
- 代码中存在类似
$model->order(input('sort'))或$model->order($_GET['sort'])这类未经校验直接传入order()的写法
注意:仅使用 ->order('id desc') 字符串常量、或通过数组键值对方式如 ->order(['id' => 'desc']) 是安全的,不触发该漏洞。
核心修复方式:强制白名单校验
不要依赖过滤函数(如 htmlspecialchars、addslashes),而应限定可接受的字段与方向:
$allowFields = ['id', 'name', 'create_time', 'status'];
$sort = input('sort', 'id');
$orderField = in_array($sort, $allowFields) ? $sort : 'id';
$direction = strtolower(input('dir', 'asc'));
$direction = in_array($direction, ['asc', 'desc']) ? $direction : 'asc';
$list = Db::name('user')->order($orderField . ' ' . $direction)->select();升级是最稳妥方案
官方已在 5.1.30+ 版本中增强 order() 方法的参数处理逻辑,对非法字符(如逗号、括号、空格、反引号)进行拦截。建议直接升级至 5.1.40 或更高维护分支版本(注意:5.1 系列已停止官方支持,生产环境应规划迁移到 ThinkPHP 6.3+ 或 8.x)。
临时加固(无法升级时)
- 禁用调试模式(
app_debug = false),避免错误信息泄露 SQL 结构 - 在 Nginx/Apache 层添加请求规则,拦截含
order by、asc%20、desc%20、反引号等特征的非法 GET/POST 参数 - 对所有涉及
order()的控制器方法,统一前置校验中间件,拒绝非白名单字段
该漏洞不依赖特定配置开启,只要业务代码存在动态传参行为即可能被利用。修复重点不在“怎么过滤”,而在“只允许什么”。
立即学习“PHP免费学习笔记(深入)”;



















