MyBatis框架下防止SQL注入

100 篇文章 1 订阅
97 篇文章 1 订阅

与传统的ORM框架不同,MyBatis使用XML描述符将对象映射到SQL语句或者存储过程中,这种机制可以让我们更大的灵活度通过SQL来操作数据库对象,因此,我们必须小心这种便利下SQL注入的可能性。

安全用法

<select id="getPerson" parameterType="int" resultType="org.application.vo.Person">
SELECT * FROM PERSON WHERE ID = #{id}
</select>

这是我们推荐的一种用法,注意参数符号#{id},使用#{}语法,MyBatis会通过预编译机制生成PreparedStatement参数,然后在安全的给参数进行赋值操作,因此就避免了SQL注入:

/* Comparable JDBC code */
String selectPerson = "SELECT * FROM PERSON WHERE ID = ?"; 
PreparedStatement ps = conn.prepareStatement(selectPerson); 
ps.setInt(1, id);

更多安全用法示例:

<insert id="insertPerson" parameterType="org.application.vo.Person">
insert into Person (id, name, email, phone)
values (#{id}, #{name}, #{email}, #{phone})
</insert>
 
<update id="updatePerson" parameterType="org.application.vo.Person">
update Person set name = #{name}, email = #{email}, phone = #{phone}
where id = #{id}
</update>
 
 
<delete id="deletePerson" parameterType="int">
delete from Person where id = #{id}
</delete>

不安全用法

<select id="getPerson" parameterType="string" resultType="org.application.vo.Person">
SELECT * FROM PERSON WHERE NAME = #{name} AND PHONE LIKE '${phone}'; 
</select>

首先,这是一种不全的用法,注意上面的参数修符号${phone} ,使用${}参数占位修饰符,MyBatis不会对字符串做任何修改,而是直接插入到SQL语句中。这也就是说MyBatis在对参数进行替换操作时,不会对参数值进行任何修改或者转义操作。

假设,电话号码phone参数由用户进行输入,系统本身未对输入值进行任何校验或者转义,那么潜在攻击者可能通过输入类似:"1%' OR '1'='1"这样的电话号码值,那么用户查询语句就会变成下面的格式:

SELECT * FROM PERSON WHERE NAME = ? and PHONE LIKE '1%' OR '1' = '1'

另外,如果电话号码是这样的值:A%'; DELETE FROM PERSON; --,脚本执行的结果可能就是删除 PERSON 表中的所有记录:

SELECT * FROM PERSON WHERE NAME = ? and PHONE LIKE 'A%'; DELETE FROM PERSON; --'

像上面这种用法,后台直接接收用户输入,而不对输入进行任何校验都是非常危险的,这可能带来潜在的SQL注入攻击,因此,当我们在使用${}语法时,接受参数应不允许用户输入,或者允许用户输入,系统必须对用户输入进行必要的校验和转义。

下面是一些不安全的用法示例

<insert id="insertPerson" parameterType="org.application.vo.Person">
insert into Person (id, name, email, phone)
values (#{id}, #{name}, #{email}, ${phone})
</insert>
 
<update id="updatePerson" parameterType="org.application.vo.Person">
update Person set phone = ${phone}
where id = #{id}
</update>
 
 
<delete id="deletePerson" parameterType="int">
delete from Person where id = ${id}
</delete>

原文链接:
https://software-security.sans.org/developer-how-to/fix-sql-injection-in-java-mybatis

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值