示例SQL注入问题
先写一小段程序,根据mysql中的study1数据库的t_user表,写一个用户登录的代码,如果用户名和密码正确打印登陆成功,否则打印用户名或者密码错误
重写粘贴下之前javaBean包下的User类
package bean;
import java.util.Date;
public class User {
private int id;
private String name;
private String password;
private String email;
private Date birthday;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", password=" + password + ", email=" + email + ", birthday="
+ birthday + "]";
}
}
service包下新建LoginService类
package service;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mysql.cj.xdevapi.Result;
import bean.User;
import util.DBUtil;
public class loginService {
public User Login(String username,String password) {
User user=null;//声明User对象
String sql="select id,name,password,email,birthday from t_user where name='"+username+"' and password='"+password+"'";
System.out.println(sql);
try (
Connection conn = DBUtil.getConnection();
Statement stat=conn.createStatement();
ResultSet rs=stat.executeQuery(sql);
){
while(rs.next()) {
user=new User();//初始化user
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
user.setEmail(rs.getString("email"));
user.setBirthday(rs.getDate("birthday"));
}
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
}
Contrallor包下新建Login类
package controller;
import java.util.Scanner;
import bean.User;
import service.loginService;
public class Login {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入用户名");
String name=sc.nextLine();
System.out.println("请输入密码");
String password=sc.nextLine();
loginService ls=new loginService();
User u=ls.Login(name, password);
if (u==null) {
System.out.println("登录失败");
}else {
System.out.println("登陆成功");
}
}
}
注意: 随便输入一个用户名,在密码部分输入下面内容
123' or 1='1
就能登陆成功,这就是SQL注入问题,简单点说就是恶意拼接sql语句段
SQL注入
就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
解决sql注入的方法:
- 1过滤用户输入的数据中是否包含非法字符;
- 2分步交验,先使用用户名来查询用户,如果查找到了,再比较密码;
- 3使用PreparedStatement。
当然sql注入不仅仅指这一种情况,但咱们还是先解决这个问题吧
要想上述的sql注入问题,就要使用jdbc中PreparedStatement接口,该接口的介绍在我的博文中https://blog.csdn.net/sinat_41132860/article/details/84989573
修改service包下LoginService类,即可解决该sql注入问题
package service;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import bean.User;
import util.DBUtil;
public class loginService {
public User Login(String username,String password) {
User user=null;//声明User对象
String sql="select id,name,password,email,birthday from t_user where name=? and password=?";
System.out.println(sql);
try (
Connection conn = DBUtil.getConnection();
PreparedStatement stat=conn.prepareStatement(sql);
){
stat.setString(1, username);
stat.setString(2, password);
try (
//使用jdk7新写法,不用显示关闭ResultSet资源
ResultSet rs = stat.executeQuery();
){
while(rs.next()) {
user=new User();//初始化user
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
user.setEmail(rs.getString("email"));
user.setBirthday(rs.getDate("birthday"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
}