thinkphp 3.2.1 请求参数过滤漏洞核心在于默认机制不处理数组参数、不校验控制器/方法名、不限制特殊键;审计需覆盖默认过滤生效性、路由参数合法性、模型层sql解析、日志缓存风险四方面。

ThinkPHP 3.2.1 请求参数过滤漏洞的核心在于框架默认的输入处理机制存在盲区——它不自动过滤数组型参数,也不校验控制器/方法名合法性,更未对特殊键(如 table、where、_method)做白名单约束。审计不是找“有没有过滤”,而是验证“过滤是否覆盖所有入口、是否可被绕过”。以下为实操导向的审计路径。
检查默认过滤是否生效且覆盖全部请求方法
ThinkPHP 3.2.1 默认使用 DEFAULT_FILTER => 'htmlspecialchars',但该配置仅作用于字符串型 GET/POST 参数,对数组参数完全无效。需确认两点:
- 在
Conf/config.php或模块级配置中,'DEFAULT_FILTER'是否被显式修改或清空;若为空或设为null,则所有字符串参数均无基础过滤 - 检查业务代码中是否大量使用
I('post.', '', 'htmlspecialchars')这类手动调用,若漏写或误用(如写成I('post.')无第三参数),对应参数即跳过过滤 - 特别关注
$_GET['_method']—— 该参数被框架用于模拟 PUT/DELETE 请求,但 3.2.1 中直接传入call_user_func_array,未做函数名白名单校验
验证路由参数是否可被恶意构造
3.2.1 支持多种 URL 模式(PATHINFO、兼容模式 ?s=、普通模式 ?m=...&c=...&a=...),所有模式下控制器(c)、方法(a)、路由变量(s)均参与动态调用,必须逐项验证:
- 访问
/index.php?s=index/\think\app/invokefunction,观察是否报错或返回异常信息;若响应中出现ReflectionMethod或call_user_func_array相关堆栈,说明路由解析未拦截非法命名空间 - 测试
?m=../etc/passwd或?c=Index;phpinfo(),检查是否触发路径遍历或代码执行;若服务器返回文件内容或 PHP 信息,说明m/c/a参数未做字符白名单(仅允许字母、下划线、斜杠) - 查看
Conf/convention.php中'URL_CASE_INSENSITIVE'是否为true;若开启,需额外测试大小写混用绕过(如C=Index)
审查模型层 where() 等方法的参数解析逻辑
SQL 注入高危点集中在 Model::find()、select()、delete() 接收数组参数时的解析流程。重点审计三处:
- 是否直接将用户输入作为
$options['table']或$options['alias']使用;若存在$map['table'] = I('get.table')类赋值,且未强制类型转换或正则校验,即可注入UNION SELECT - 检查
where键是否接受字符串型表达式(如array('where'=>'id=1 and 1=updatexml(1,concat(0x7e,(select user())),0)'));3.2.1 的_parseOptions对字符串 where 不做任何转义,直接拼入 SQL - 验证
EXP、IN等查询表达式是否被滥用:例如$map['id'] = array('in','1,2,3) and sleep(5)-- '),因框架仅在末尾加空格而不清理括号闭合,可导致语法逃逸
确认日志与缓存是否成为攻击跳板
参数过滤失效后,日志和缓存会固化攻击痕迹并可能反向触发 RCE:
- 检查
Runtime/Logs/是否可通过 HTTP 访问(如http://site/RunTime/Logs/24_10_15.log);若可读,攻击者能直接看到完整 SQL、POST 数据、错误路径等敏感信息 - 测试缓存写入点:若业务使用
S('key', I('get.payload')),尝试传入含%0d%0a的 payload(如?payload=%0d%0a<?php phpinfo();?>),观察Runtime/Temp/xxx.php缓存文件是否生成可执行代码 - 确认
APP_DEBUG是否为true;若开启,所有参数、SQL、堆栈均写入日志,等于主动提供攻击地图
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











