thinkphp3.2.4的order注入漏洞源于parseorder方法仅校验asc/desc关键词而未过滤括号、注释符等sql元字符,导致攻击者可构造如updatexml()等恶意payload绕过检测并注入执行。

直接看 parseOrder 方法,它在 ./ThinkPHP/Library/Think/Db/Driver.class.php 里,是 order 注入的关键入口。
盯住 parseOrder 的过滤逻辑
这个方法本意是解析排序参数,比如 name ASC 或 id DESC。它先用 stripos 判断是否存在 ASC 或 DESC,再按逗号分割、逐段处理。问题出在这里——只检测关键词,不校验整体结构,也不过滤括号、注释符、逗号分隔符等 SQL 元字符。
- 只要字符串里含
ASC或DESC,就认为“合法”,后续直接拼进 SQL -
(、)、/*、%20等被绕过,因为它们不在检测范围内 - 例如传入
updatexml/*,*/(/*%20ASC,*/1,concat/*,*/(0x7e,user(),0x7e),1),能成功触发报错注入
顺藤摸瓜找调用链
从控制器中搜索 ->order( 调用,尤其是参数来自用户输入(如 I('sort')、input('order'))的地方:
- 定位到类似
$model->where(...)->order(I('id'))->select()这样的代码行 - 检查该参数是否经过白名单限制(如只允许
id、name、create_time) - 若直接透传未校验,且底层走的是
parseOrder,就存在风险
验证是否走 parseOrder 分支
ThinkPHP 3.2.4 中,order() 最终会调用 parseOrder(),但前提是传入的是字符串而非数组。需确认:
- 传参是字符串(如
order='name ASC')→ 触发parseOrder - 传参是数组(如
order=['name'=>'asc'])→ 走另一套解析,一般不受此漏洞影响 - 调试时可在
parseOrder开头加echo 'in parseOrder'; die;快速确认执行路径
对比修复前后的差异
官方所谓“修复”只是加了 ASC/DESC 检查,没做上下文隔离或语法解析。审计时重点看:
- 有没有对 order 参数做字段白名单控制(推荐做法)
- 有没有强制转换为预定义排序项(如
['id'=>'desc','name'=>'asc']) - 有没有禁用原始字符串传参,改用数组方式统一处理
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











