在数据库中生成 一个用户表 有用户名 username 和密码password 字段 并插入两组数据
正常的sql查询结果
非正常查询途径返回的结果
下面用一段java代码 演示一下用户登录时的sql注入问题
package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Scanner; import com.mysql.jdbc.Driver; /* * Java程序实现用户登录,用户名和密码,数据库检查 * 演示被别人攻击 */ public class JDBCDemo2 { public static void main(String[] args) throws ClassNotFoundException, SQLException { //1.注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2.获取连接 String url="jdbc:mysql://localhost:3306/mybase"; String username="root"; String password="123456"; Connection conn=DriverManager.getConnection(url,username,password); //3.创建方法执行对象 Statement stat=conn.createStatement(); Scanner sc=new Scanner(System.in); System.out.print("请输入用户名:"); String user=sc.nextLine(); System.out.print("请输入密码:"); String pwd=sc.nextLine(); //执行SQL语句,数据表,查询用户名和密码,如果存在,登陆成功,不存在登陆失败 String sql="select * from users where username='"+user+"' and password='"+pwd+"'"; System.out.println(sql); ResultSet rs=stat.executeQuery(sql); while(rs.next()){ System.out.println(rs.getString("username")+" "+rs.getString("password")); } rs.close(); stat.close(); conn.close(); } }
控制台输入 输出
刚刚控制台输入的用户名是存在的
下面输入瞎写的用户名和密码同样可以得到所有用户名和对应的密码,此谓sql的注入攻击
解决方式,使用Statement的子类接口 PrepareStatement
该接口是由数据库厂商提供实现类方法,我们直接调用即可,使用这个子类接口,完美解决了上述问题,所以成为java 连接数据库执行的一个标准步骤
package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Scanner; /* * Java程序实现用户登录,用户名和密码,数据库检查 * 防止注入攻击 * Statement 接口实现类,作用执行SQL语句,返回结果集 * 有一个子接口PreparedStatement (SQL预编译存储,多次高效的执行SQL) * PreparedStatement prepareStatement(String sql) * */ public class JDBCDemo3 { public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); String url="jdbc:mysql://localhost:3306/mybase"; String username="root"; String password="123456"; Connection con=DriverManager.getConnection(url,username,password); Scanner sc=new Scanner(System.in); System.out.println("请输入用户名:"); String user=sc.nextLine(); System.out.println("请输入密码:"); String pwd=sc.nextLine(); String sql="select * from users where username=? and password=?"; PreparedStatement ps=con.prepareStatement(sql); ps.setObject(1, user); ps.setObject(2, pwd); ResultSet rs=ps.executeQuery(); while(rs.next()){ System.out.println(rs.getString("username")+" "+rs.getShort("password")); } rs.close(); ps.close(); con.close(); } }
正确输入后的输出
故技重施:来一次sql注入
发觉根本不行!