sql注入Mybatis中的#{参数}和${参数}

Posted 保护眼睛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql注入Mybatis中的#{参数}和${参数}相关的知识,希望对你有一定的参考价值。

sql注入概述:

针对SQL注入的攻击行为可描述为:在与用户交互的程序中(如web网页),非法用户通过可控参数注入SQL语法,将恶意sql语句输入拼接到原本设计好的SQL语句中,破坏原有SQL语法结构,执行了与原定计划不同的行为,达到程序编写时意料之外结果的攻击行为,其本质就是使用了字符串拼接方式构造sql语句,并且对于用户输入检查不充分,导致SQL语句将用户提交的非法数据当作语句的一部分来执行,从而造成了sql注入

有关sql注入产生的原理要满足以下条件:
1.程序编写者在处理程序和数据库交互时,使用了字符串拼接的方式构造SQL语句
2.不安全的数据库配置,比如对查询集不合理处理,对sql查询语句错误时不当的处理,导致其错误信息暴露在前端
3.过于信任用户在前端所输入的数值,没有过滤用户输入的恶意数据,且未对用户可控参数进行足够的过滤便将参数内容拼接进入到SQL语句中,直接把用户输入的数据当做SQL语句执行,从而影响数据库安全和平台安全。

mybatis中的#{参数} 和 ${参数}

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
动态 sql 是 mybatis 的主要特性之一,在mybatis中我们可以把参数传到xml文件,由mybatis对sql及其语法进行解析,mybatis支持使用$ {}和#{}、两中方式都是动态传输的标识。来看${}存在的sql注入的问题👇

这是配置文件中的sql

这是传入的参数

然后所执行的sql语句

得到结果

如果传入的参数是这样的呢?

我们可以看到会将数据库中的所有的结果的会得到

看对应的sql语句👇

就会得到所有的结果、发生了sql注入,如果注入的sql语句是这样的呢?

最终执行的sql语句

结果

😥
如果是删库的语句呢?

sql注入解决方案

1.开发人员可以手动排除掉系统的关键字

结果

生成的sql

2.使用系统提供的参数来进行SQL语句的拼接

结果

生成的sql

3.尽量使用#{参数}的方式替换参数

#{参数}和${参数}总结

#{参数}将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #{userid},如果传入的值是111,那么解析成sql时的值为order by “111”

$ {参数}将传入的数据直接显示生成在sql中。如:order by ${userid},如果传入的值是111,那么解析成sql时的值为order by 111

$ {参数}方式无法防止sql注入。#{参数}方式能够很大程度防止sql注入

#{参数} 为参数占位符 ?,即sql 预编译、${参数} 为字符串替换,即 sql 拼接

最终的解析结果都是

#{} 在预处理时,会把参数部分用一个占位符 ? 代替,变成如下的 sql 语句:

而 ${} 则只是简单的字符串替换,在动态解析阶段,该 sql 语句会被解析成

#{} 的参数替换是发生在 DBMS 中,而 ${} 则发生在动态解析过程中。

#{参数}:动态解析 -> 预编译 -> 执行
${参数}:动态解析 -> 编译 -> 执行

变量替换后,#{} 对应的变量自动加上单引号 ‘’
变量替换后,${} 对应的变量不会加上单引号 ‘’

以上是关于sql注入Mybatis中的#{参数}和${参数}的主要内容,如果未能解决你的问题,请参考以下文章

mybatis中的#{}和${}

关于mybatis中的#{},和${} 的区别

MyBatis如何防止SQL注入

mybatis #{}和${}区别

mybatis #{}和${}区别

MyBatis单表查询——参数占位符${}和#{}SQL注入like查询