ThinkPHP 5.0.18存在表达式注入漏洞,核心是where/order/group/having等字符串型参数未严格校验,可导致SQL注入甚至RCE;修复需四层防御:改用数组传参、字段白名单校验、升级至5.0.24+/5.1.32+并重启服务、限制数据库权限及PHP底层版本。

ThinkPHP 5.0.18 的请求参数过滤绕过漏洞,核心在于框架对字符串型 where 条件、order/group/having 等动态参数未做严格校验,导致用户输入可直接进入 SQL 表达式解析流程,进而引发 SQL 注入甚至 RCE(在特定组合下)。修复不能只靠“别写错”,而要从调用方式、字段控制、版本升级和运行时防护四层入手。
统一改用数组传参,禁用字符串直传
框架对数组形式的条件会自动启用预处理机制,而字符串直传(如 where('status', 'in', '1,2,3'))则跳过参数化,直接拼接 SQL。
- 把所有
where('field', 'in', $user_input)改为where('field', 'in', explode(',', $user_input)),确保传入的是数组 - like 查询避免拼接:
where('name', 'like', '%' . input('q') . '%')→ 改为where('name', 'like', "%{input('q')}%"),并确认该用法依赖框架的参数绑定逻辑(5.0.18 中需配合模型或 Db::table()->param() 显式启用) - exp 类型必须人工过滤:
where('score', 'exp', input('expr'))属高危,应彻底禁用,或仅允许白名单内的表达式模板(如'AVG(score) > ?')
对动态字段名做白名单校验
order、group、field、having 等方法若接收用户输入,极易被注入恶意 SQL 片段(如 id ASC, (SELECT ...))。
- 禁止直接使用
order(input('sort')),改为映射校验:$allow = ['id', 'name', 'create_time', 'status']; $sort = input('sort', 'id'); $sort = in_array($sort, $allow) ? $sort : 'id'; order($sort . ' ' . (input('order') === 'desc' ? 'desc' : 'asc')) - 同理,
group()和having()中涉及的字段名、聚合函数名(如 COUNT、SUM)也需白名单限制,不接受任意字符串拼接 - 视图渲染中
fetch()或assign()若传入用户可控模板路径或变量名,也需校验,防止模板注入
升级到已修复版本并重启服务进程
官方已在 5.0.24+ 和 5.1.32+ 中修复多处表达式解析绕过问题,包括 where 字符串解析路径未关闭、闭包内 filterValue 调用未隔离等关键缺陷。
立即学习“PHP免费学习笔记(深入)”;
- 优先升级至 ThinkPHP 5.0.24 或更高稳定版;若项目已用 5.1.x,升至 5.1.32+
- 升级后必须重启 PHP-FPM 或 Web 服务器(如 Apache/mod_php、Nginx+php-fpm),否则旧进程仍加载着含漏洞的类文件
- 注意:仅替换 vendor/thinkphp 目录不够,需确认 composer autoload、opcache 是否清空,建议部署时执行
composer dump-autoload -o和opcache_reset()
数据库权限与底层环境加固
即使应用层有遗漏,限制数据库账号能力也能大幅降低危害面。
- 应用数据库账号禁用高危操作:撤销
FILE、LOAD FROM OUTFILE、SELECT ... INTO DUMPFILE、CREATE FUNCTION等权限 - 确认 PHP 运行环境本身安全:当前(2026年10月)PHP 官方已发布 8.2.35/8.3.36/8.4.27/8.5.12,修复了底层 CVE-2026-109618/109619(php2shell),该漏洞可绕过所有 PHP 应用代码直接触发 RCE。必须同步升级 PHP 并重启全部工作进程
- Web 服务器层面可临时增加 WAF 规则,拦截常见 payload 模式,如
exp%20.*select.*from、order%20by.*\(\s*select、having.*\)\s*--等,作为纵深防御补充



















