【Web】基于Mybatis的SQL注入漏洞利用点学习笔记

目录

MyBatis传参占位符区别

不能直接用#{}的情况

in多参数值查询

[like %%模糊查询](#like %%模糊查询)

[order by列名参数化](#order by列名参数化)


MyBatis传参占位符区别

在 MyBatis 中,#{}${} 都是用于传参的占位符,但它们之间有很大的区别,主要体现在两个方面:参数值的类型和 SQL 注入问题。

1.参数值的类型:

① #{} 是预编译参数,表示使用 PreparedStatement 时,使用 setXXX() 方法设置参数值,会对传入的参数进行类型处理,确保传递的参数类型正确。一般来说,我们在使用 MyBatis 进行 CRUD 操作时,都应该使用 #{} 来传递参数,这样可以有效地避免 SQL 注入问题。

{} 是字符串拼接,表示在 SQL 语句中直接插入传入的参数值,不会对传入的参数类型进行处理。如果传入的参数是字符串类型,那么在 SQL 语句中使用时,需要使用单引号将其括起来,否则会抛出 SQL 语法错误异常。因此,在使用 {} 时,需要特别注意避免 SQL 注入问题。

简而言之:

复制代码
如果传入Z3r'4y
# PrepareStatement ? 填充参数 类型化 转义处理 返回一个'Z3r\'4y'
$ Statement 拼接参数 返回一个Z3r'4y

2.SQL 注入问题:

① #{} 可以避免 SQL 注入问题,因为它会对传入的参数进行类型处理,并将参数值转义后再放到 SQL 语句中,保证了 SQL 语句的安全性。

② ${} 存在 SQL 注入问题,因为 SQL 语句中插入的是传入的参数值,如果参数值中包含 SQL 语句的关键字或特殊字符,可能会导致 SQL 注入攻击。

举个例子:

复制代码
<!-- 使用#,不存在漏洞;默认都是PREPARED-->
    <select id="findUserById" resultType="com.example.mybaits.entity.User" statementType="PREPARED">
        SELECT * FROM tbuser where id= #{id}
    </select>

<!-- 使用$,存在注入漏洞 -->
    <select id="findUserByName" resultType="com.example.mybaits.entity.User">
        SELECT * FROM tbuser where userName='${username}'
    </select>

总结一下:原则就是能用#{}就不要用${}

不能直接用#{}的情况

因为一些sql语言的性质,一些情况不能直接用#{}(传参强制被引号包裹导致sql语义错误)

比如下面这种情况:

如果直接SELECT * FROM tbuser where id in (#{ids})并传参ids=1,2,3就会拼接成:

SELECT * FROM tbuser where id in ('1,2,3');

从而出现只调出一行的谬误

解决方案如下:

in多参数值查询

复制代码
 <!-- in查询,错误写法 -->
    <select id="findUserInIds" resultType="com.example.mybaits.entity.User" >
        SELECT * FROM tbuser where id in (${ids})
    </select>

    <!-- in查询,正确写法 -->
    <select id="findUserInIdsRight" resultType="com.example.mybaits.entity.User" >
        SELECT * FROM tbuser where id in
        <foreach collection="list" item="ids" open="(" close=")" separator=",">
            #{ids}
        </foreach>
    </select>

like %%模糊查询

复制代码
 <!-- 模糊查询,错误写法 -->

<select id="findUserLikeName" resultType="com.example.mybaits.entity.User">
        SELECT * FROM tbuser where userName like '%${username}%'
    </select>

 <!-- 模糊查询,正确写法 -->

<select id="findUserLikeName" resultType="com.example.mybaits.entity.User">
        SELECT * FROM tbuser where userName like concat('%',#{username}, '%')
    </select>

order by列名参数化

复制代码
<!--动态指定列名排序,有注入漏洞-->

<select id="allUserSeq" resultType="com.example.mybaits.entity.User">
    SELECT *FROM tbuser order by ${colName}
</select>

基于MyBatis并不能很好解决这种注入漏洞

相关推荐
麦兜*13 小时前
Redis在Web3中的应用探索:作为链下状态缓存与索引层
java·spring boot·redis·spring cloud·缓存·docker·web3
百***349513 小时前
Python连接SQL SEVER数据库全流程
数据库·python·sql
迦蓝叶13 小时前
从繁琐到优雅:用 Project Panama 改变 Java 原生交互
java·jni·native·java新特性·原生接口·跨语言开发·projectpanama
Yue丶越14 小时前
【C语言】深入理解指针(四)
java·c语言·算法
豐儀麟阁贵14 小时前
6.3对象类型的转换
java·开发语言
四谎真好看14 小时前
Java 黑马程序员学习笔记(进阶篇27)
java·开发语言·笔记·学习·学习笔记
q***829114 小时前
Spring Boot 热部署
java·spring boot·后端
天途小编14 小时前
引领产业合规化进程:北方天途航空无人机安全操作能力评估系统与民航局UOM平台完成全面技术对接
安全·无人机
合作小小程序员小小店14 小时前
web开发,在线%农业产品销售管理%系统,基于idea,html,css,vue.js,layui,java,jdk,ssm
java·前端·jdk·intellij-idea·layui·数据库管理员
珹洺15 小时前
Java-Spring实战指南(三十四)Android Service实现后台音乐播放功能
android·java·spring