thinkphp 3.2.4 sql注入漏洞源于order、find等方法对用户输入数组参数解析不严,修复需关闭调试模式、严格过滤高危参数、重写危险model方法、强化i()函数过滤规则。

ThinkPHP 3.2.4 的 SQL 注入漏洞主要集中在 order、find、select、delete 等方法对数组参数的解析逻辑上,尤其是当用户可控输入(如 I('xxx'))直接传入这些方法时,框架未严格校验键名与值类型,导致恶意 SQL 片段被拼入最终查询语句。修复不依赖升级框架,关键是堵住参数入口、约束解析行为、避免字符串直拼。
关闭调试模式并禁用错误回显
防止攻击者通过报错获取数据库结构或路径信息,这是所有加固的前提:
- 检查
ThinkPHP/Conf/convention.php或项目级Conf/config.php,确认以下配置为 false:'SHOW_ERROR_MSG' => false,'APP_DEBUG' => false, - 同时在
index.php入口文件顶部确保环境常量设为生产模式:define('APP_DEBUG', false);
严格过滤 order、where、table 等高危参数
漏洞常通过 order(I('id')) 或 find(I('id')) 触发,核心是禁止用户控制 SQL 结构关键词:
- 对排序字段:只允许白名单字段 + 明确方向
示例修复写法:$order = I('order', 'id');<br>$allowed = ['id', 'name', 'create_time', 'status'];<br>$field = in_array($order, $allowed) ? $order : 'id';<br>$direction = in_array(strtoupper(I('dir')), ['ASC', 'DESC']) ? strtoupper(I('dir')) : 'DESC';<br>$list = M('user')->order("{$field} {$direction}")->select(); - 对 where 条件:避免直接传数组,优先用字符串条件或显式构造
❌ 危险:M('user')->find(I('id'))
✅ 安全:$id = (int)I('id'); $user = M('user')->find($id);或$where['id'] = (int)I('id'); $user = M('user')->where($where)->find();
重写或拦截危险的 Model 方法调用
针对已知存在解析缺陷的 find()、select()、delete() 方法,可在基类 Model 中覆盖其行为:
- 在
Application/Common/Model/BaseModel.class.php(或对应路径)中定义: public function find($options = array()) {<br> if (is_array($options) && !empty($options)) {<br> // 拒绝 table/alias/union 等非法键<br> $forbidden_keys = ['table', 'alias', 'union', 'join', 'having'];<br> foreach ($forbidden_keys as $key) {<br> if (isset($options[$key])) {<br> E('Invalid parameter: ' . $key);<br> }<br> }<br> }<br> return parent::find($options);<br>}
统一强化 I() 函数的默认过滤规则
原生 I() 默认只做 htmlspecialchars,对 SQL 无防护。可在项目初始化阶段重置全局过滤器:
- 在
Application/Common/Conf/config.php中添加:'DEFAULT_FILTER' => 'htmlspecialchars,addslashes', - 更推荐方式:在
Application/Common/Behavior/CheckInputBehavior.class.php中编写行为,在run()方法里对 GET/POST/REQUEST 参数遍历检测,对疑似 SQL 关键字(union、select、updatexml、extractvalue、括号、注释符等)直接终止请求或记录告警。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











