Mybatis 注入


Mybatis 注入

Mybatis 框架

Mybatis 是一个 java 持久层框架(Dao 层),用来连接 java 和关系型数据库,是执行 SQL 语句的帮手,不再需要使用 JDBC 连接

Mybatis 的使用有几个部分

  1. 核心配置 XML 文件:配置数据库地址、名字、密码等

  2. Mybatis 工具类

  3. java 实体类:普通的 java 对象,例如 User 类

  4. Mapper 接口:定义的接口,写明需要执行的方法

  5. XML 映射文件 Mapper.xml:这里会编写接口中方法对应的 SQL 语句,Mybatis 会自动解析这里的 SQL 语句,这里的语句需要在配置文件中注册

    java 调用接口中的方法时,会自动到 XML 文件中获取 SQL 语句,然后发给数据库执行,将返回的数据包装成实体类返回

参数符号

Mybatis 的 SQL 语句需要手动编写,编写 XML 文件时,Mybatis 支持两种参数符号

  • #{}​:使用预编译,将参数部分使用 ? 替代,后续放入的参数不会进行 SQL 编译,而是当作字符串处理,可以避免 SQL 注入漏洞
  • ${}:使用的是拼接字符串,容易导致 SQL 注入漏洞

Mybatis 注入

Mybatis 框架的预编译会避免产生 SQL 注入漏洞,容易产生的有以下几种情况

模糊查询

在模糊查询中使用 #{}​ 传入参数会报错,如果修改为 ${} 就会产生 SQL 注入漏洞

<select id="getUsersByIds" resultType="User">
	select * from users where username like '%${username}%'
</select>

修复的写法是使用 concat 连接

<select id="getUsersByIds" resultType="User">
	select * from users where username like concat('%',#{username},'%') 
</select>

动态多条件查询

查询多个 ID 时,可能会将一个用逗号分割的字符串传给 SQL,这里使用 in 语句,如果使用 #{},由于预编译机制,会导致将输入的当作一个字符串,不能满足需求,修改为了

<select id="getUsersByIds" resultType="User">
	select * from users where username in (${ID})
</select>

修复的写法是将传来的字符在 java 层转化为 List​ 或 Array​,使用 Mybatis 的 <foreach> 标签

<select id="getUsersByIds" resultType="User">
    SELECT * FROM users WHERE id IN
    <foreach collection="idList" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

动态排序

动态排序功能,需要在 order by 后面传入参数,这里的参数是列名,JDBC 的规定,表名和列名是不能预编译的

<select id="getUsersSorted" resultType="User">
    SELECT * FROM users ORDER BY ${column} limit 0,1
</select>

这里必须使用字符串拼接,所以 SQL 无法修改,需要在 Java 业务层添加白名单校验


文章作者: Marin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Marin !
  目录