IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Mybatis在Java代码审计中的审计方法及修复方法 -> 正文阅读

[Java知识库]Mybatis在Java代码审计中的审计方法及修复方法

Java代码审计系列课程【共58课时】_Web安全课程-51CTO学堂Java代码审计系列课程,Web安全,学会改课程将更深刻的了解常见漏洞原理,审计发现代码中漏洞,开发人员不再编写“漏洞”,51CTO学堂为您提供全面的视频课程和专项解答,it人充电,就上51CTO学堂icon-default.png?t=M1L8https://edu.51cto.com/course/27875.html

前置知识:了解Mybatis框架映射关系

mapper定位java代码

id定位方法

List<User> findByUserNameVuln02(String username);
?
定位到UserMapper.xml中的id
?
  <select id="findByUserNameVuln02" parameterType="String" resultMap="User">
 ? ? ?  select * from users where username like '%${_parameter}%'
 ?  </select>

Mybatis中两种数据库拼接方法

${}是直接拼接

#{}预处理后拼接

mybatis有两种写法,一种是使用@Param 注解:

@Mapper
public interface CategoryMapper {
 ? ?@Select("select * from category_ where name= '${name}' ")
 ? ?public CategoryM getByName(@Param("name") String name);
}

1、${}直接拼接,类似jdbc中的直接拼接审计方法

http://localhost:8080/sqli/mybatis/vuln01?username=joychou
?
 ?/ * http://localhost:8080/sqli/mybatis/vuln01?username=joychou' or '1'='1
 ? ? */
 ? ?@GetMapping("/mybatis/vuln01")
public List<User> mybatisVuln01(@RequestParam("username") String username) {
 ? ? ? ?return userMapper.findByUserNameVuln01(username);
 ?  }
?
这里使用的是mybatis来进行SQL查询,获取参数username后使用userMapper.findByUserNameVuln01(username)来进行查询。
?
来看一下findByUserNameVuln01。MyBatis支持两种参数符号,一种是#,另一种是$。这里的参数获取使用的是${username},而不是#{username},而${username}是直接将参数拼接到了SQL查询语句中,就会造成SQL注入。
?
@Select("select * from users where username = '${username}'")
List<User> findByUserNameVuln01(@Param("username") String username);

注入语句:

http://localhost:8080/sqli/mybatis/vuln01?username=joychou' or '1'='1

${}修复方法

采用#{},也就是预处理的形式

http://localhost:8080/sqli/mybatis/sec01?username=joychou
@Select("select * from users where username = #{username}")
User findByUserName(@Param("username") String username);

2、Mybatis中like审计方法

访问路径:

http://localhost:8080/sqli/mybatis/vuln02?username=admin

这里使用的是findByUserNameVuln02(String username);来进行查询,来看一下UserMapper.xml,也就是他的XML映射文件。

List<User> findByUserNameVuln02(String username);
?
UserMapper.xml:
<select id="findByUserNameVuln02" parameterType="String" resultMap="User">
 ? ?select * from users where username like '%${_parameter}%'
</select>
 ? ?
 ? ? _parameter是Mybatis的内置参数,代表整个参数
?

这里传入未过滤的username后,插入到SQL语句中,就成了:select * from users where username like '%username%',${}直接拼接字符串,而且这里在like的后面不能使用#{}预编译,不然就会产生报错。

注入语句:

http://localhost:8080/sqli/mybatis/vuln02?username=admin' or '1'='1' %23

修复建议:

可以使用like concat('%',#{username}, '%')就可以避免注入了。

http://localhost:8080/sqli/mybatis/vsec02?username=joyc
?
java代码:
List<User> findByUserNameVsec02(String username);
?
Mybatis配置:
 ? ?<select id="findByUserNameVsec02" parameterType="String" resultMap="User">
 ? ? ? ?select * from users where username like concat('%',#{_parameter}, '%')
 ? ?</select>

验证:

http://localhost:8080/sqli/mybatis/vsec02?username=joychou' or '1'='1' %23

同理不同数据库的修复代码快:

Mysql数据库:

SELECT  * ?FROM  user ?WHERE  name like CONCAT('%',#{name},'%') ?

Oracle数据库:

SELECT  * ?FROM  user ?WHERE  name like CONCAT('%',#{name},'%') 
或
SELECT  * ?FROM  user ?WHERE  name like '%'||#{name}||'%' 

Sqlserver数据库:

 SELECT  * ?FROM  user ?WHERE  name like '%'+#{name}+'%' ?

DB2数据库:

SELECT  * ?FROM  user ?WHERE  name like '%'+#{name}+'%' ?
或
SELECT  * ?FROM  user ?WHERE  name like '%'||#{name}||'%' 

3、Mybatis中order by审计方法

访问链接:

http://localhost:8080/sqli/mybatis/orderby/vuln03?sort=1

这里使用的是findByUserNameVuln03(@Param("order") String order)来进行查询,同样也是去看UserMapper.xml。

<select id="findByUserNameVuln03" parameterType="String" resultMap="User">
 ? ?select * from users
 ? ?<if test="order != null">
 ? ? ? ?order by ${order} asc
 ? ?</if>
</select>

可以看到我们输入的参数在order by之后,也是${order}直接拼接起来了,与like相同,在这也是无法使用预编译,只能使用${}。由于没有过滤就直接拼接,很显然存在注入。

注入语句:

http://localhost:8080/sqli/mybatis/orderby/vuln03?sort=1 and (updatexml(1,concat(0x7e,(select version()),0x7e),1))

修复代码:

1、当order排序能不让用户输入就不让用户输入,后台直接写死,不传递参数到后端:

http://localhost:8080/sqli/mybatis/sec03
Java代码块:
User OrderByUsername();
?
Mysql配置:
 <select id="OrderByUsername" resultMap="User">
 ? ? ? ?select * from users order by id asc limit 1
 ? ?</select>

2、当order必须要从外界获取参数到后端代码进行拼接时候,那就先对参数进行过滤,过滤后再使用:

http://localhost:8080/sqli/mybatis/orderby/sec04?sort=1
Java代码块:
@GetMapping("/mybatis/orderby/sec04")
public List<User> mybatisOrderBySec04(@RequestParam("sort") String sort) {
 ? ?String filter_order = SecurityUtil.sqlFilter(sort);
 ? ?return userMapper.findByUserNameVuln03(filter_order);
}
?
//sqlFilter
private static final Pattern FILTER_PATTERN = Pattern.compile("^[a-zA-Z0-9_/\\.-]+$");
 
public static String sqlFilter(String sql) {
 ? ?if (!FILTER_PATTERN.matcher(sql).matches()) { ?//严格限制用户输入只能包含a-zA-Z0-9_-.
 ? ? ? ?return null;
 ?  }
 ? ?return sql;
}
?
Mysql配置:
 ? ?
<select id="findByUserNameVuln03" parameterType="String" resultMap="User">
 ? ?select * from users
 ? ?<if test="order != null">
 ? ? ? ?order by ${order} asc
 ? ?</if>
</select>
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:14:49  更:2022-02-28 15:16:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:00:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码