首先,对于sql注入是什么,我也不做多余的阐述了,有关sql注入,网上有很多独到的见解,可以自行百度。
1,就个人观点来看,JDBC,MyBatis条件下sql防止注入的方法有哪些。
对于jdbc来说,尽量使用PreparedStatement 来代替Statement,在PreparedStatement中会进行一些预编译的过程,什么是预编译了?就是存在sql注入的地方,肯定会有用户在sql语句中进行操作的参数,比如select,update的where条件,orderby条件等等,预编译就是在对数据+sql语句进行组合处理前,对之前的sql语句进行编译一次,参数用“ ?”代替。
例如:在很多用到的springboot的mapper中,有这么一个语句。
select userAccount ,userPassword from user where userAccount=#{userAccount},
在编译的过程中,就会先进行一次预编译,处理SQL语句为:
select userAccount ,userPassword from user where userAccount=?
所以当某些用户进行注入攻击的时候,会把注入语句转化为一个字符串,而不是一个命令,放到了“?”的地方,从而有效地防止了sql的注入问题。
2,MyBatis防止注入的原理。
其实似乎大部分的持久层框架都是依赖于jdbc的PreparedStatement的防注入原理,只是或多或少的有些改进。
在执行xml中或者其他dao中的sql语句的时候,MyBatis启用了预编译功能,数据库会进行一个预编译的过程,
执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题。
【底层实现原理】MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,
PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,
而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。
3,MyBatis的注入存在地方。
mybatis有两种参数,一种是#{},一种是${}。以下是对这两种的一些理解。
#{}:相当于JDBC中的PreparedStatement;
KaTeX parse error: Expected 'EOF', got '#' at position 15: {}:是输出变量的值; #̲{}作为sql中传参数在某些不…{xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。
简单说,#{}是经过预编译的,是安全的;
是
未
经
过
预
编
译
的
,
仅
仅
是
取
变
量
的
值
,
是
非
安
全
的
,
存
在
S
Q
L
注
入
。
如
果
我
们
o
r
d
e
r
b
y
语
句
后
用
了
{}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。 如果我们order by语句后用了
是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。如果我们orderby语句后用了{},那么不做任何处理的时候是存在SQL注入危险的。
怎么防止,手动处理过滤一下输入的内容。
如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中。
第一篇个人博客,写的可能比较片面,有什么想法请多指教,谢谢。