之前在挖一些项目的时候,老是遇到参数置空导致信息泄露的问题。
为了一探究竟,我又去重新补了一下Mybatis 也算是水一篇文章了。
Mybatis中XML中的SQL规范可能产生的信息泄露
如果在Mybatis中的XML文件中如果是这么写的话。
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from blog where 1=1
<if test="title !=null">
and title = #{title}
if>
<if test="author !=null">
and author = #{author}
if>
select>
那么可能存在查询出其他用户的信息。
因为如果將title或者author参数置空的话那么他就会执行前面查询所有信息的操作。
但是在一般真实项目中或者一些政企中他是不会写where 1=1的。
他们会加上where标签 表示后面加上where。
例如:
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from blog
<where>
<if test="title !=null">
title = #{title}
if>
<if test="author !=null">
and author = #{author}
if>
where>
select>
这样的话如果我们不给title或者author参数的话,他就会直接执行select * from blog 将所有信息查询出来。
这就是为什么我们有时候去挖SRC或者一些其他网站的时候将参数置空他会查询出来所有的信息。
那么比如说我们拥有一个普通用户的话,在查看信息这个功能点击的时候,会查询SQL,我们将相关的参数置空是不是就可以查询出来其他的用户。
那么假设如果XML中的SQL是这么写的话。
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select * from blog
<where>
<choose>
<when test="title !=null">
title = #{title};
when>
<when test="author !=null">
and title = #{author}
when>
<otherwise>
and views = #{views}
otherwise>
choose>
where>
select>
这里的进行判断如果没有传递title author 的话,那么必须传递一个必要的参数views,如果不传递这个参数那么就会查询出来为空。
这里的blog的表是这样的。
+--------------------------------------+-----------------------+-----------+---------------------+-------+
| id | title | author | create_time | views |
+--------------------------------------+-----------------------+-----------+---------------------+-------+
| fced32e7-d0fc-4d89-8960-d4448e6aabc9 | Mybatis如此简单 | 南陈说 | 2023-05-18 15:49:36 | 9999 |
| 4a5b0d3c-8809-41bd-ad2b-b38da11a91cb | Spring如此简单 | 南陈说 | 2023-05-18 15:49:36 | 9999 |
| 6324972f-7cad-472d-be50-41760bec4dee | Java如此简单 | 南陈说 | 2023-05-18 15:49:36 | 9999 |
| 79bf219d-cee7-4361-99da-d68bc0c1fb9b | 微服务如此简单 | 南陈说 | 2023-05-18 15:49:36 | 9999 |
+--------------------------------------+-----------------------+-----------+---------------------+-------+
所以说必须传递views参数,所以有时候我们可以多fuzz一些参数可以一个一个参数fuzz。
Mybatis Like注入
有时候需要使用like进行模糊查询,但是在拼接 %%的时候会产生SQL注入。比如:
<select id="getUserByName" resultMap="result">
SELECT * FROM t_user WHERE name like "%"${name}"%"
select>
使用$符号他的底层是不会进行预编译的。所以会产生SQL注入。
使用CONCAT函数拼接避免SQL注入。
<select id="getUserByName" resultMap="result">
SELECT * FROM t_user WHERE name LIKE CONCAT('%',#{name},'%')
select>
也可以使用字符串进行拼接:
<select id="getUserByName" resultMap="result">
SELECT * FROM t_user WHERE name like "%"#{name}"%"
Mybatis in注入
正确使用的方式,而不是将#替换为$。
id in
<foreach collection="ids" item="item" open="("separatosr="," close=")">
#{ids}
foreach>
Mybatis orderby注入
order by #{orderBy} #{orderType}