您的位置:首页 > 数据库

PrepareStatement防止sql注入漏洞分析

2016-12-29 14:05 513 查看
sql注入:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令

危害:数据库信息泄露

*恶意字符:1 or 1=’1’等

案例:

package com.zhiwei.database;
import java.sql.*;

public class PrepareStatementTest {

public static void main(String[] args) {

PreparedStatement ps =null;
ResultSet rs=null;
Connection ct=null;

try {
Class.forName("com.mysql.jdbc.Driver");
ct = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test","squirrel","xiaoyang");
ps=ct.prepareStatement("select *from user where name='zhangsan' and '1' or 1='1'");
rs=ps.executeQuery();
while(rs.next()){
int id =rs.getInt(1);
String name = rs.getString(2);
String passwd = rs.getString(3);
int age=rs.getInt(4);
String sex=rs.getString(5);
System.out.println(id+"--"+name+"--"+passwd+"--"+age+"--"+sex);
}

} catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(rs!=null){
rs.close();
}if(ps!=null){
ps.close();
}if(ct!=null){
ct.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}


控制台日志:

1–zhangsan–zhangsan–10–F

2–lisi–lisi–20–M

3–wangwu–wangwu–15–M

4–maliu–maliu–13–F

5–tianqi–tianqi–18–M

6–maba–maba–19–F

22–BBBB–BBBB–16–M

数据库记录:



结果:

sql语句没有查出我们想要的数据记录,而是将所有的表的记录都查询出来了,造成数据泄露(典型的sql注入漏洞)

分析:

select *from user where name=’zhangsan’ and ‘1’ or 1=’1’

语句分析:sql语句中and的优先级高于or的优先级,因此

select *from user where name=’zhangsan’ and ‘1’ or 1=’1’

等价于:

select *from user where (name=’zhangsan’ and ‘1’) or 1=’1’

因此name=’zhangsan’ and ‘1’ or 1=’1’的最终结果都是为真,where条件就失去作用,

整条sql的功能等价于:select *from user

优化后的sql语句:

select *from user where name=’zhangsan’ and (‘1’ or 1=’1’)

分析:

将恶意sql字符隔开,根据()的优先级大于and,因此整个sql语句的判断条件就变成name=’zhangsan’和(‘1’ or 1=’1’),而(‘1’ or 1=’1’)永久为真,因此整条语句就实现了对name的过滤作用,恶意sql则变得多余,但是这样的sql并没有实际的使用价值

sql注入的解决方案:

①:使用PrepareStatement类的set方法,它在sql预编译的时候对sql语句进行转义,

PrepareState过滤特定的字符将“干净”的二进制文件提交给数据库,因而就达不到欺骗数据库的效果

ps=ct.prepareStatement(“select *from user where name=?”);

ps.setString(1, “zhangsan and 1 or 1=’1’”);

rs=ps.executeQuery();

②:web项目中一般使用过滤器或者拦截器去过滤页面表单传过来的字符,自己拼接”干净”的sql语句再提交数据库执行

使用prepareStatement设置参数的效果:不能查询出有效数据,因此有效防止恶意sql的注入。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息