Mybatis Order by动态参数防注入方式

 更新时间:2024年04月19日 14:56:24   作者:偷代码的猫  
这篇文章主要介绍了Mybatis Order by动态参数防注入方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、先提及一下Mybatis动态参数

参数符号编译安全
#{}预编译安全处理后的值,字符类型都带双引号
${}未预编译不安全,存在SQL注入问题传进来啥就是啥

二、order by 动态参数

order by 后面参数值是表字段或者SQL关键字

所以使用#{} 是无效的,只能使用${}

那么SQL注入问题就来了

三、解决Order by动态参数注入问题

1、使用正则表达式规避

特殊字符 * + - / _ 等等

使用indexOf判断到了直接返回

有可能会存在其它情况,不能完全规避,但是可以逐步排查

2、技巧解决

  • 2.1 先从order by 动态参数思考

组合情况只有这两种

  • order by 字段名 (asc直接略掉得了) 
  • order by 字段名 desc

所以我们只要找到对应集合,判断我们动态排序条件是否在其中就可以了

  • 2.2 获取排序条件集合

有些勤劳的小伙伴可能就开始写了

userOrderSet = ['id','id desc','age','age desc',.......]
scoreOrderSet = ['yuwen','yuwen desc','shuxue','shuxue desc',.......]
.............

要是有n多表n多字段可是要急死人

我们使用注解+映射来获取

  • 2.3 动态获取集合
/**
首先改造实体类,有@Column注解映射,也有使用@JsonProperty,都行,没有用@Column映射,就加个@JsonProperty,不影响,我偷懒使用@JsonProperty
**/
@Data
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
public class ContentEntity {
 
    
    @JsonProperty("id")
    private Long id;//主键ID
    @JsonProperty("code")
    private String code;//编码
    @JsonProperty("content")
    private String content;//内容
    @JsonProperty("is_del")
    private Integer isDel;//是否删除,0未删除,1已删除
    @JsonProperty("creator")
    private String creator;//创建人
    @JsonProperty("creator_id")
    @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
    private Date createAt;//创建时间
    @JsonProperty("updater")
    private String updater;//更新人
    @JsonProperty("updater_id")
    @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
    private Date updateAt;//更新时间
 
}
/**工具类来了**/
 
public class MybatisDynamicOrderUtils {
 
    private static final String desc = " desc";
    /**
     * 获取对象 JsonProperty 值列表 使用Column替换一下
     * @param object
     * @return
     */
    public static Set<String> getParamJsonPropertyValue(Class<?> object){
        try {
            //获取filed数组
            Set<String> resultList =  new HashSet<>();
            Field[] fields = object.getDeclaredFields();
            for (Field field:fields){
                //获取JsonProperty注解
                if(field.getAnnotation(JsonProperty.class)!=null){
                    JsonProperty annotation = field.getAnnotation(JsonProperty.class);
                    if (annotation != null) {
                        //获取JsonProperty 的值
                        String jsonPropertyValue = annotation.value();
                        resultList.add(jsonPropertyValue);
                    }
                }
            }
            return resultList;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
 
    /**
     * 判断动态order是否是合理
     * @param order
     * @param object
     * @return
     */
    public static Boolean isDynamicOrderValue(String order,Class<?> object){
        //先获取JsonProperty 注解中的集合
        Set<String> set = getParamJsonPropertyValue(object);
        //属于直属字段 直接返回
        if(set.contains(order)){
            return true;
        }
        //多了倒序,先去除倒序字段再判断
        if(order.lastIndexOf(desc)>0){
            String temp = order.substring(0,order.lastIndexOf(desc));
            if(set.contains(temp)){
                return true;
            }
        }
        return false;
    }
}
//调用操作一下
 
//检验动态order是否合理,防止SQL注入
if(!MybatisDynamicOrderUtils.isDynamicOrderValue(sort,ContentEntity.class)){
            log.error("dynamic order is error:{}",sort);
            return null;
}
 
 
 
//mapper.class
 
@Select({"<script>select  * from content order by ${sort}</script>"})
List<ContentEntity> getList(@Param("sort") String sort);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 详解Java String中intern方法的原理与使用

    详解Java String中intern方法的原理与使用

    这篇文章主要为大家介绍了Java String中intern方法的原理以及使用。文中通过图片和示例代码进行了详细展示,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-05-05
  • Java中notify()和notifyAll()的使用区别

    Java中notify()和notifyAll()的使用区别

    本文主要介绍了Java中notify()和notifyAll()的使用区别,文中通过示例代码介绍的非常详细,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • idea下的工具栏中services不见了,如何调用出来

    idea下的工具栏中services不见了,如何调用出来

    这篇文章主要介绍了idea下的工具栏中services不见了,如何调用出来的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • SpringBoot + validation 接口参数校验的思路详解

    SpringBoot + validation 接口参数校验的思路详解

    这篇文章主要介绍了SpringBoot + validation 接口参数校验,本文通过项目实践+场景分析给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Java使用HttpUtils实现发送HTTP请求

    Java使用HttpUtils实现发送HTTP请求

    这篇文章主要介绍了Java使用HttpUtils实现发送HTTP请求,HTTP请求,在日常开发中,还是比较常见的,今天给大家分享HttpUtils如何使用,需要的朋友可以参考下
    2023-05-05
  • Java修改Integer变量值遇到的问题及解决

    Java修改Integer变量值遇到的问题及解决

    这篇文章主要介绍了Java修改Integer变量值遇到的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • SpringSecurity如何设置白名单策略

    SpringSecurity如何设置白名单策略

    这篇文章主要介绍了SpringSecurity如何设置白名单策略,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-07-07
  • Java中如何利用Set判断List集合中是否有重复元素

    Java中如何利用Set判断List集合中是否有重复元素

    在开发工作中,我们有时需要去判断List集合中是否含有重复的元素,这时候我们不需要找出重复的元素,我们只需要返回一个 Boolean 类型就可以了,下面通过本文给大家介绍Java中利用Set判断List集合中是否有重复元素,需要的朋友可以参考下
    2023-05-05
  • Springboot使用Security实现OAuth2授权验证完整过程

    Springboot使用Security实现OAuth2授权验证完整过程

    安全管理是软件系统必不可少的的功能。根据经典的“墨菲定律”——凡是可能,总会发生。如果系统存在安全隐患,最终必然会出现问题,这篇文章主要介绍了SpringBoot使用Security实现OAuth2授权验证完整过程
    2022-12-12
  • java观感示例分享

    java观感示例分享

    这篇文章主要介绍了java观感示例,该实例查询并生成了系统中存在观感对应的按钮并在用户点击相应按钮时将窗口的观感切换到指定的观感上
    2014-03-03

最新评论