mybatis与sql注入
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。通常来说ORM的框架应该是可以避免SQL注入的,但是如果mybatis使用不当也会造成sql注入。
The MyBatis data mapper framework makes it easier to use a relational database with object-oriented applications. Unlike traditional ORM solutions, MyBatis maps objects with SQL statements or stored procedures using a XML descriptor, rather than mapping objects to tables in a database; thus providing complete control over SQL, therefore susceptible to SQL injection if used incorrectly.
MyBatis has 2 substitution methods. The ${}
method does direct string replacement (i.e. property substitution) so it’s vulnerable to SQL injection. The #{}
method does parameter substitution on a PreparedStatement so it is not vulnerable.
<select id="getPerson" parameterType="int" resultType="org.application.vo.Person">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
使用#
标记参数,mybatis会使用预编译的方式来处理参数,这样子是安全的。相当于使用了如下的jdbc代码:
1 | String selectPerson = "SELECT * FROM PERSON WHERE ID = ?"; PreparedStatement ps = conn.prepareStatement(selectPerson); ps.setInt(1, id); |
<select id="getPerson" parameterType="string" resultType="org.application.vo.Person">
SELECT * FROM PERSON WHERE NAME = #{name} AND PHONE LIKE '${phone}';
</select>
Note the parameter notation, ${phone} in the above getPerson statement. By default, using the ${} syntax will cause MyBatis to directly inject a string, unmodified, into a SQL Statement. MyBatis does NOT modify or escape the string before substitution.
使用$
符号mybatis会直接将字符串注入到sql语句中,不进行任何修改和转移如果没有对phone变量进行验证的话就可能导致sql注入。
#安全开发建议
尽量使用#
符号,如果需要要对用户提交参数进行验证。
like的写法:
mysql:
select * from t_user where name like concat('%', #{name}, '%')
oracle:
select * from t_user where name like '%' || #{name} || '%'
sqlserver:
select * from t_user where name like '%' + #{name} + '%'
参考资料:
http://apollo89.com/wordpress/?p=2175
http://mybatis.org/mybatis-3/zh/
http://software-security.sans.org/developer-how-to/fix-sql-injection-in-java-mybatis