【JAVA】如何解决SQL注入?

                                         如何解决SQL注入?

面试中经常问到,SQL注入是什么?又怎么防止SQL注入?为了不再尴尬得只回答出使用PreparedStatement,我们还是有必要了解一下其他的方式。

一、什么是SQL注入?

说简单点,就是部分用户在表单中输入sql语句的片段,对没有输入检验的网站可能带来毁灭性的打击,轻则绕过登录,重则删库、泄露数据。


二、一个简单的SQL注入实例

假设某个网站没有输入参数检验,并且后台的sql语句为

 String sql = "select * from user where username='" + username + "' and password='" + password + "'";

那么如果我在表单中输入的用户名为

String username="' or 1=1 --";

并且任意输入一个密码后,会发生什么呢?组合后的sql语句为

String afterSql="select * from user where username='' or 1=1 -- and password='123'";

where中的子句username='' or 1=1永远为真,是因为使用了--,将后面的密码判断给注释了。这样子我可以绕过登录,去做一些危害网站的事情,比如删库。即使用下面的注入

String deleteDB="select * from user where username='';drop table user -- and password='123'";

可见,如果一个网站不对输入的参数进行检验的话,很可能会威胁到网站自身的安全。


三、怎么防范sql注入?

sql注入只会发生在sql编译的过程中,那么避免非法sql语句被编译,就是我们要做的事情。

【1】在JDBC中,使用Statement的子类PreparedStatement,这也是我们最先想到的方法

事先将sql语句传入PreparedStatement中,等会要传入的参数使用?代替,那么该sql语句会进行预编译,之后将前台获取的参数通过set方式传入编译后的sql语句中,那么此时被注入的sql语句无法得到编译,从而避免了sql注入的问题。而且使用PreparedStatement在一定程度上有助于数据库执行性能的提升。

 PreparedStatement preparedStatement = connection.prepareStatement(sql);
 preparedStatement.setString(1, username);
 preparedStatement.setString(2, password);

 

【2】Mybatis中尽量使用#{}而不是${},下面给出一个典型的查询写法

<select id="findByUserId" parameterType="edu.usts.sddb.entity.User"
            resultType="edu.usts.sddb.entity.User">
		select * from t_user where us_id=#{us_id}
</select>

#{}就像是JDBC中的?,mybatis通过使用#{}的方式,代表该语句在执行之前会经过预编译的过程,后来传入的参数通过占位符的方式填入到已经编译完的语句中。但使用${}的参数会直接参与编译,不能避免sql注入。如果需求中非要使用到${}的话,只能手动过滤了。

 

【3】手动过滤参数

声明一个危险参数数组danger,将前台传入的参数用“ ”分隔后,产生的参数数组与danger有交集时,终止该sql的执行,并反馈前台,提示禁止输入非法字符。

 

 

全部评论

相关推荐

01-30 09:45
燕山大学 Java
喵_coding:这种直接跑就完事了 哪有毕业了才签合同 任何offer和三方都没有的
点赞 评论 收藏
分享
在笔试的大西瓜很矫健:校招数分不用想了,这经历和学历都不够用,大厂更别想,初筛都过不了,说点不好听的小厂数分都进不去(小厂也是假数分),要两个对口实习+3个项目(或者3+2),而且要有含金量才能补一点你的学历劣势。 建议刷实习,社招找数分,校招看运气,能入行业就行,可以运营转数分
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务