关于mybatis使用${}时sql注入的问题
程序员文章站
2022-03-07 21:57:07
目录mybatis使用${}时sql注入的问题区别解决方法mybatis sql注入问题之$与#在mybatis中使用$符号在mybatis中使用#符号mybatis使用${}时sql注入的问题最近在...
mybatis使用${}时sql注入的问题
最近在上线项目的时候,代码审查没有通过,提示有sql注入的风险。
order by ${orderby}
很简单的一个排序字段,但是因为使用 ${} 占位符的原因,有sql注入的风险,相信大家平时也经常会使用这个占位符,不知道有没有考虑sql注入的问题,下面简单介绍下 #{} 和 ${} 的区别以及为什么使用 ${} 会有sql注入的问题。
区别
- #{}是一个参数占位符,对于string类型会自动加上"",其他类型不加。由于mybatis采用预编译,其后的参数不会再进行sql编译,所以一定程度上防止sql注入。
- ${}是一个简单的string替换,字符串是什么,解析就是什么。
- 类如order by。假如前端传的参数是id(假设id是string类型),对于order by #{id},对应的sql语句就是 order by “id”;对于order by ${id},对应的sql语句则是order by id。这种情况,当用户传参为id && 1=1 的时候,就会产生难以预计的后果。
解决方法
- 在原实体类里加入一个map
public map<string,string> indexmap=new hashmap<string,string>(){ { put("spaceid","space_id"); // key为前端传的值,value为数据库对应的列值 put("opttime","opt_time"); } };
- 当传参时,判断参数是否在map的key中,如果存在的话,就把对应的value作为排序的依赖条件。
if(paramoptlog.getorderby()!=null &&strings.isnullorempty(paramoptlog.getorderby())){ optlog optlog=new optlog(); paramoptlog.setorderby(optlog.indexmap.getordefault(paramoptlog.getorderby(), "id")); } list<optlog> list = optlogmapper.query4page(paramoptlog); }
- 总结就是通过映射,由程序员来决定 ${} 传的参数,即将动态sql转成静态sql的方式可以解决这个问题,这样在实际调用的时候就不会有sql注入的风险了。
mybatis sql注入问题之$与#
在mybatis中使用$符号
不会进行预编译,会被sql注入
注入方式如下:
密码随便输一个就可以通过验证,只要用户名正确即可。
这样输入后查询语句在数据库中如下:
select id,username,password from userlogin where username='admin' or 1=1 and password='23'
sql解释:and优先级高于or 首先判断后面1=1 and password='23'为false,然后判断前面username='admin'为true中间
连接为or即最后为true or false 最后还是为true,就直接通过验证,能够正常登陆admin用户。
在mybatis中使用#符号
这样会进行预编译,能够防止sql注入。sql注入只有在编译时才有效,而预编译的时候是用个?代替参数,真正执行时才把参数替换?。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
推荐阅读
-
SQL Server使用Merge语句当源表数据集为空时,无法进行查询的问题
-
关于MyBatis 查询数据时属性中多对一的问题(多条数据对应一条数据)
-
关于mybatis使用map传参0和 " !='' " 的问题
-
关于使用PLSQL Developer时出现报错ora-12514的问题
-
Python关于使用subprocess.Popen时遇到的一个小问题记录
-
关于sql脚本导入Oracle时重复生成check约束的问题解决
-
关于SpringBoot使用Redis空指针的问题(不能成功注入的问题)
-
【软件系肖潇】解决使用DButils进行jdbc多表联合操作时抛出sql异常的问题
-
vue使用axios时关于this的指向问题详解
-
关于hql中使用本地sql函数的问题(问-答)