mybatis字符串转义问题

Posted Simple is Awesome

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis字符串转义问题相关的知识,希望对你有一定的参考价值。

问题描述

@Select("select * from account order by #{orderBy} #{orderRule} limit #{start},#{offset}")
public List<Account> getAccountList(@Param("orderBy") String orderBy, @Param("orderRule") String orderRule,
    @Param("start) int start, @Param("offset") int offset);

如上代码所示,在执行查询操作时,为了能够与前端联动进行排序,直接在SQL参数中传递排序字段和排序规则。
但是,在调试时偶然发现,当传递的“orderBy”值为不存在的字段时,竟然不会报错!!!
经过进一步调试发现,实际上并不会按照预期的排序规则返回数据列表!!!

原因追踪

设置log4j的日志级别为DEBUG后发现,最终执行的SQL语句是一个预编译操作,mybatis输出日志如下:

==>  Preparing: select * from account order by ? ? limit ?, ? 
==> Parameters: loginName(String), DESC(String), 0(Integer), 50(Integer)

很显然,传递的参数loginName和DESC是作为字符串处理的。
也就是说,很有可能mybatis对String类型的参数会进行转换。举个例子:传递的String参数为loginName,最终在SQL语句执行时为:\'loginName\'。
再进一步验证,如果在SQL语句中传递的排序字段不是字段名loginName,而是\'loginName\'时,是不会按照排序规则返回数据的,并且也不会报错!
追溯mybatis官方文档发现:默认情况下,使用#{}格式的语法会导致mybatis对字符串进行修改或转义!!!

详见:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#select

解决问题

将参数传递的语法格式#{}修改为${},即:

@Select("select * from account order by ${orderBy} ${orderRule} limit #{start},#{offset}")
public List<Account> getAccountList(@Param("orderBy") String orderBy, @Param("orderRule") String orderRule,
    @Param("start) int start, @Param("offset") int offset);

观察mybatis日志输出:

==>  Preparing: select * from account order by login_name DESC limit ?, ? 
==> Parameters: 0(Integer), 50(Integer)

此时,对于使用${}格式引用的参数,mybatis直接在SQL语句中插入一个不改变的字符串,而不再作为一个预编译参数处理。
注意: 以这种方式接收用户输入的内容并直接提供给SQL语句作为不变的字符串是不安全的,会导致潜在的SQL注入攻击,因此要么不允许用户输入这些字段,要么自行转义并检验。

总结

如果只是想直接在SQL语句中插入一个不改变的字符串,比如,像ORDER BY,可以使用${}引用参数:ORDER BY ${columnName},这里mybatis不会修改或转义字符串。

值得注意的是:简单地将“#”修改为“$”,很容易带来SQL注入的问题,应该在Java层面应该做好参数检查,假定用户输入均为恶意输入,防范潜在的攻击,重点关注在三个方面“like”,“in”和“order by”。

【参考】
https://mp.weixin.qq.com/s/OTw3rCDWKD5cLqFLbdu_cg 本以为用的MyBatis框架就万无一失了,没想到还是被黑客注入了,我真的无语了!

以上是关于mybatis字符串转义问题的主要内容,如果未能解决你的问题,请参考以下文章

mybatis字符串转义问题

Vscode在使用变量之前转义斜杠

在 Rails 上为连接、限制、选择等(不是条件)的 SQL 片段安全地转义字符串

MyBatis中特殊符号的转义

MyBatis踩坑之SQLProvider转义字符被删除问题

mybatis在xml文件中处理转义字符