1.什么是sql注入问题
以登录为例:
正常登录通过name(zc)和passwd(12345)登录
但是在name="sd or 1=1"和passwd=(错误信息)是可以完成登录的
此时的拼接信息为
select * from user where name =XXX or1=1 and passwd =XXX
来改变SQL的意义
public static String Login(String name,String passwd){
getConnection();
try {
Statement statement = connection.createStatement();
String sql="select * from user where name= "+name+"and passwd= "+passwd;
ResultSet resultSet = statement.executeQuery(sql);
if(resultSet.next()){
return "success!";
}else{
return "fail";
}
} catch (SQLException e) {
e.printStackTrace();
}
close();
return "fail";
}
//main函数中
String name="zc";
String passwd="12345";
String login=Login(name,passwd);
此时得到答案为success!
//main函数中
String name="sd or 1=1";
String passwd="1234";
String login=Login(name,passwd);
此时得到的答案仍然为success!
//main函数中
String name="sd or #";
String passwd="1234";
String login=Login(name,passwd);
select * from user where name =XXX # and passwd =XXX(在sql语句中#为注释符号)
故得到答案是success!
该现象为SQL注入问题。
2.如何解决SQL注入问题
public static String Login(String name,String passwd){
getConnection();
try {
//使用PreparedStatement来实现,其中SQL中参数利用"?"占位符实现
String sql="select * from user where name= ? and passwd= ? ";
PreparedStatement statement = connection.prepareStatement(sql);
//往SQL中的占位符给定数据 statement.setString的第一个参数是值占位符的位置,从1开始
statement.setString(1,name);
statement.setString(2,passwd);
ResultSet resultSet = statement.executeQuery(sql);
if(resultSet.next()){
return "success!";
}else{
return "fail";
}
} catch (SQLException e) {
e.printStackTrace();
}
close();
return "fail";
}
使用PreparedStatement来解决SQL的注入问题
将sql和参数分别传给数据库服务器端,会进行预编译,会先进行sql语法检查,在语法检查成功后才会进行执行,如果语法检查不过是无法执行的。
PreparedStatement和Statement的区别
1.SQL注入问题
Statement是将拼接的SQL在服务器端直接执行,无法避免sql注入问题。
PreparedStatement将sql和参数分别传给数据库服务器端,会进行预编译,会先进行sql语法检查,在语法检查成功后才会进行执行,如果语法检查不过是无法执行的,避免sql注入问题。
2.效率问题
PreparedStatement先进行预编译,再将编译结果拿来执行,Statement是在服务器端直接执行,PreparedStatement的效率高于Statement。