与传统的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
来源:CSDN
作者:__HelloWorld__
链接:https://blog.csdn.net/kangkanglou/article/details/93767693