当前使用版本(必填,否则不予处理)
3.4.0
该问题是如何引起的?(确定最新版也有问题再提!!!)
order by存在sql注入问题
重现步骤(如果有就写完整)
QueryWrapper
报错信息
表被清空了
Comment From: hnxljd
文档好像说过这个问题,还有 last 也是直接拼接的。所以orderby 我们用了白名单
Comment From: oday-xiexin
需要对orderby 的内容做黑/白名单过滤
Comment From: qmdx
https://github.com/baomidou/mybatis-plus/commit/5e6b1f4f35a4ec4a0f1db27031acadfb48bc5757
Comment From: WhiteBookMan1994
当前使用版本(必填,否则不予处理)
3.4.0
该问题是如何引起的?(确定最新版也有问题再提!!!)
order by存在sql注入问题
重现步骤(如果有就写完整)
QueryWrapper wrapper = new QueryWrapper<>(); wrapper.orderBy(true, true, "id;delete from test;");
报错信息
表被清空了
为什么我用3.4.0版本测试,没有复现呢?会报错: Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'delete from test_user; ASC' at line 5 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) a
Comment From: WhiteBookMan1994
@wormhole
Comment From: qmdx
当前使用版本(必填,否则不予处理)
3.4.0
该问题是如何引起的?(确定最新版也有问题再提!!!)
order by存在sql注入问题
重现步骤(如果有就写完整)
QueryWrapper wrapper = new QueryWrapper<>(); wrapper.orderBy(true, true, "id;delete from test;");
报错信息
表被清空了
为什么我用3.4.0版本测试,没有复现呢?会报错: Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'delete from test_user; ASC' at line 5 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) a
不建议前端直接把你需要的 order by 内容传入后端,你可以加一个映射处理,或者升级升级到最新版本, 最新版本会对常见的 sql 注入进行判断处理。(建议不让前端直接传入任意排序任何,允许传入也是后端要严格控制传入内容的)
Comment From: shanzhaozhen
@hnxljd @oday-xiexin 这个白名单的处理有没有demo啊,自己尝试弄了一下实在太不优雅了
Comment From: qmdx
@hnxljd @oday-xiexin 这个白名单的处理有没有demo啊,自己尝试弄了一下实在太不优雅了
TableInfoHelper 根据实体可以找到存在的字段,根据数据库字段做白名单过滤
Comment From: shanzhaozhen
@hnxljd @oday-xiexin 这个白名单的处理有没有demo啊,自己尝试弄了一下实在太不优雅了
TableInfoHelper 根据实体可以找到存在的字段,根据数据库字段做白名单过滤
十分感谢,按照自己需求感觉只需要获取实体类反射字段就可以,不用直接查数据库字段名
/**
* 检查字段是否在实体类中
* @param columns 字段列表
* @param clazz 实体类
*/
public static void checkColumnsInEntity(String[] columns, Class<?> clazz) {
List<Field> allFields = TableInfoHelper.getAllFields(clazz);
List<String> fieldName = allFields.stream().map(Field::getName).collect(Collectors.toList());
for (String column: columns) {
if (!fieldName.contains(column)) {
log.error("请注意,存在SQL注入关键词---> {}", column);
log.error("请注意,值可能存在SQL注入风险!---> {}", column);
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + column);
}
}
}
public static void checkColumnsInEntity(String column, Class<?> clazz) {
checkColumnsInEntity(new String[]{column}, clazz);
}
public static void checkColumnsInEntity(OrderItem orderItem, Class<?> clazz) {
checkColumnsInEntity(orderItem.getColumn(), clazz);
}
public static void checkColumnsInEntity(List<OrderItem> orderItemList, Class<?> clazz) {
String[] columns = orderItemList.stream().map(OrderItem::getColumn).toArray(String[] :: new);
checkColumnsInEntity(columns, clazz);
}