sql注入Mybatis中的#{参数}和${参数}
Posted 保护眼睛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql注入Mybatis中的#{参数}和${参数}相关的知识,希望对你有一定的参考价值。
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中的#{参数}和${参数}的主要内容,如果未能解决你的问题,请参考以下文章