当前使用版本(必填,否则不予处理)

3.5.2

该问题是如何引起的?(确定最新版也有问题再提!!!)

通过Mapper XML自定义SQL语句,其中通过 com.baomidou.mybatisplus.extension.plugins.pagination.Page 传入分页参数,分页参数中包括 com.baomidou.mybatisplus.core.metadata.OrderItem。 代码运行时,如果自定义 SQL 语句中有自己的 orderby 字句,那么: 在 3.4.2 版本中,通过分页参数传入的 OrderItem 在所有 orderby 子句的最后面; 但是在 3.5.2 版本中,通过分页参数传入的 OrderItem 在所有 orderby 子句的最前面。

重现步骤(如果有就写完整)

例如 自定义SQL语句:select * from tableA order by field_a desc; 通过 Page 分页参数传入 page.addOrder(OrderItem.asc("field_b")); 3.4.2 版本中在运行时生成的SQL语句为:select * from tableA order by field_a desc, field_b acs; 3.5.2 版本中在运行时生成的SQL语句为:select * from tableA order by field_b acs, field_a desc; 出现了版本不兼容的问题。

报错信息

🈚️

Comment From: CodePlayer

不只是顺序有问题,我们使用如下自定义排序

queryWrapper.orderByDesc("country = 'CN' DESC");

被 MyBatis 3.5.2 处理后的 SQL 变成了 ORDER BY countryCNDESC。 导致 MySQL 报错: Cause: java.sql.SQLSyntaxErrorException: Unknown column 'countryCNDESC' in 'order clause' 。 之前 MyBatis 3.5.1 就没有这个问题。

就是因为在 @DongBingTe 在提交中 https://github.com/baomidou/mybatis-plus/commit/5ca9ccc30061314e4bbc175bb987d0be83fd6b21 调整了SQL注入的过滤规则导致的。 我不建议直接在 ORM 底层对整个SQL进行全面暴力过滤,这样很多数据库支持的增强语法都无法使用。

Comment From: DongBingTe

不只是顺序有问题,我们使用如下自定义排序

java queryWrapper.orderByDesc("country = 'CN' DESC");

被 MyBatis 3.5.2 处理后的 SQL 变成了 ORDER BY countryCNDESC。 导致 MySQL 报错: Cause: java.sql.SQLSyntaxErrorException: Unknown column 'countryCNDESC' in 'order clause' 。 之前 MyBatis 3.5.1 就没有这个问题。

就是因为在 @DongBingTe 在提交中 5ca9ccc 调整了SQL注入的过滤规则导致的。 我不建议直接在 ORM 底层对整个SQL进行全面暴力过滤,这样很多数据库支持的增强语法都无法使用。

抱歉,我提交的pr对你的业务造成了影响,不过不得不使用暴力过滤的方式,因为在很多开源的项目中,很多会将orderBy的输入参数交给前端来传入,我想后续提交一个pr,重载orderBy的方法,使得不进行过滤。

Comment From: CodePlayer

@DongBingTe

当外部参数要参与SQL拼接的时候,我觉得这其实不应该是框架要强制暴力做的事情: 1. 全局暴力过滤,必然会带来更多的性能开销,但大多数情况下,我们并不需要从外部传入 orderBy; 2. 暴力过滤导致的后果就是,有些本来可以实现的功能,就完全没法实现了;比如我用 LIKE 模糊查询,我就是想搜索带有 % 的文本,不过这些特殊符号一旦被过滤掉,那这个功能就完全没法实现了。就像 有些网站通过过滤代码关键字 script 等来预防 XSS 注入,但是像 CSDN 这种网站,它就是需要展示用户提交的代码片段。 3. 当外部参数参与SQL拼接时,这其实也需要技术人员同步保持更高的安全意识,否则注入的SQL即使不带特殊符号,但它只需要变更传入的字段(比如预期只能传入A、B、C,但是用户传入了D)或传入一些不带特殊符号的合法的WHERE条件或函数,也能够让程序的执行结果违背预期。安全的功课光靠全局暴力过滤是不能够一劳永逸的。 4. 一个通用的 ORM 框架,更应该只做增强,不做变更。你们可以提供额外的工具方法、重载方法 或者 全局设置的开关(默认关闭,真有需要就打开),但是不应该全局暴力强制过滤,且不留下任何退路。

Comment From: DongBingTe

@DongBingTe

当外部参数要参与SQL拼接的时候,我觉得这其实不应该是框架要强制暴力做的事情:

  1. 全局暴力过滤,必然会带来更多的性能开销,但大多数情况下,我们并不需要从外部传入 orderBy;
  2. 暴力过滤导致的后果就是,有些本来可以实现的功能,就完全没法实现了;比如我用 LIKE 模糊查询,我就是想搜索带有 % 的文本,不过这些特殊符号一旦被过滤掉,那这个功能就完全没法实现了。就像 有些网站通过过滤代码关键字 script 等来预防 XSS 注入,但是像 CSDN 这种网站,它就是需要展示用户提交的代码片段。
  3. 当外部参数参与SQL拼接时,这其实也需要技术人员同步保持更高的安全意识,否则注入的SQL即使不带特殊符号,但它只需要变更传入的字段(比如预期只能传入A、B、C,但是用户传入了D)或传入一些不带特殊符号的合法的WHERE条件或函数,也能够让程序的执行结果违背预期。安全的功课光靠全局暴力过滤是不能够一劳永逸的。
  4. 一个通用的 ORM 框架,更应该只做增强,不做变更。你们可以提供额外的工具方法、重载方法 或者 全局设置的开关(默认关闭,真有需要就打开),但是不应该全局暴力强制过滤,且不留下任何退路。

我在gitee上提交了修改后的pr https://gitee.com/baomidou/mybatis-plus/pulls/270

Comment From: VampireAchao

@DongBingTe

当外部参数要参与SQL拼接的时候,我觉得这其实不应该是框架要强制暴力做的事情:

  1. 全局暴力过滤,必然会带来更多的性能开销,但大多数情况下,我们并不需要从外部传入 orderBy;
  2. 暴力过滤导致的后果就是,有些本来可以实现的功能,就完全没法实现了;比如我用 LIKE 模糊查询,我就是想搜索带有 % 的文本,不过这些特殊符号一旦被过滤掉,那这个功能就完全没法实现了。就像 有些网站通过过滤代码关键字 script 等来预防 XSS 注入,但是像 CSDN 这种网站,它就是需要展示用户提交的代码片段。
  3. 当外部参数参与SQL拼接时,这其实也需要技术人员同步保持更高的安全意识,否则注入的SQL即使不带特殊符号,但它只需要变更传入的字段(比如预期只能传入A、B、C,但是用户传入了D)或传入一些不带特殊符号的合法的WHERE条件或函数,也能够让程序的执行结果违背预期。安全的功课光靠全局暴力过滤是不能够一劳永逸的。
  4. 一个通用的 ORM 框架,更应该只做增强,不做变更。你们可以提供额外的工具方法、重载方法 或者 全局设置的开关(默认关闭,真有需要就打开),但是不应该全局暴力强制过滤,且不留下任何退路。

我非常赞同

Comment From: bbllmaster

感谢这个问题,找到临时解决办法,3.5.3.1 版本,queryWrapper.orderByDesc做了暴力过滤 page.addOrder 没做暴力过滤

Comment From: qmdx

@bbllmaster @DongBingTe 这个问题在新版本上调整为选择性过滤非默认必须,另外过滤的条件相对更加合理