ThinkPHP5漏洞分析之SQL注入(一)
字数 1093 2025-08-18 11:38:41
ThinkPHP5 SQL注入漏洞分析(insert方法注入)
漏洞概述
本漏洞存在于ThinkPHP框架的Builder类的parseData方法中,由于程序未对用户输入数据进行充分过滤,导致恶意数据被直接拼接进SQL语句,造成SQL注入漏洞。
影响版本:
- 5.0.13 ≤ ThinkPHP ≤ 5.0.15
- 5.1.0 ≤ ThinkPHP ≤ 5.1.5
环境搭建
- 创建测试项目:
composer create-project --prefer-dist topthink/think=5.0.15 tpdemo
- 修改composer.json:
"require": {
"php": ">=5.4.0",
"topthink/framework": "5.0.15"
}
- 执行更新:
composer update
- 创建控制器文件application/index/controller/Index.php:
<?php
namespace app\index\controller;
class Index
{
public function index()
{
$username = request()->get('username/a');
db('users')->insert(['username' => $username]);
return 'Update success';
}
}
-
配置数据库(application/database.php)并开启调试模式(application/config.php中设置app_debug和app_trace为true)
-
创建数据库:
create database tpdemo;
use tpdemo;
create table users(
id int primary key auto_increment,
username varchar(50) not null
);
漏洞复现
访问以下URL触发SQL注入:
http://yoursite/index/index/index?username[0]=inc&username[1]=updatexml(1,concat(0x7,user(),0x7e),1)&username[2]=1
注意:需要开启app_debug才能看到SQL报错信息。
漏洞分析
漏洞触发流程
- 用户提交的恶意参数通过
request()->get('username/a')获取,/a表示获取数组类型参数 - 数据传入
db('users')->insert()方法 - 最终调用Builder类的parseData方法处理数据
关键代码分析
漏洞核心在于parseData方法对用户数据的处理不充分。攻击者可以构造特殊数组参数:
$username = [
0 => 'inc', // 操作类型
1 => '恶意SQL', // 操作值
2 => '1' // 条件值
];
在Builder类的parseData方法中,当操作类型为'inc'时,代码会直接将用户提供的数据拼接到SQL语句中,没有进行充分的过滤。
三种可能触发注入的情况
-
inc操作:
$val[0] = 'inc'$result[$key] = $key . '+' . $val[1]; -
dec操作:
$val[0] = 'dec'$result[$key] = $key . '-' . $val[1]; -
exp操作:
$val[0] = 'exp'$result[$key] = $key . ' ' . $val[1];
虽然exp操作理论上也存在注入风险,但在实际中,ThinkPHP的内置过滤方法会将'exp'替换为'exp空格',从而阻止了注入。
漏洞修复
官方在5.0.16版本中修复了此漏洞,主要修改了Builder.php文件,对inc和dec操作进行了安全处理。
修复措施包括:
- 对inc/dec操作的值进行类型检查,确保是数字
- 对用户输入进行更严格的过滤
攻击流程图
用户提交恶意参数(username数组)
↓
框架接收参数(request()->get('username/a'))
↓
调用db('users')->insert()
↓
Builder::insert()方法处理
↓
调用parseData方法解析数据
↓
恶意数据直接拼接到SQL语句
↓
执行SQL,触发注入
防护建议
- 及时升级到安全版本
- 对用户输入进行严格过滤和类型检查
- 避免直接将用户输入拼接到SQL语句中
- 生产环境关闭调试模式(app_debug)
总结
该漏洞源于框架对数组参数处理不当,特别是在使用inc/dec操作时未充分过滤用户输入。开发人员在使用ORM框架时,仍需保持安全意识,不能完全依赖框架的防护机制。