Sql注入问题
学习JDBC的过程中学到了一个Sql的安全问题
一个login表
写一个登录程序:
package com.company.JDBC;
import javafx.scene.transform.Scale;
import java.sql.*;
import java.util.Scanner;
public class test {
private static String url = "jdbc:mysql://localhost:3306/test";
static String name = "root";
static String password = "root";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Connection connection = null;
Statement statement = null;
//JVM创建DriverManager
Class.forName("com.mysql.jdbc.Driver");
//创建连接
connection = DriverManager.getConnection(url, name, password);
//sql语句操作数据库
statement = connection.createStatement();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String userName = scanner.nextLine();
System.out.println("请输入密码:");
String pwd = scanner.nextLine();
String sql = "select * from login where name='"+userName+"'and password='"+pwd+"'";
//返回结果集ResultSet
ResultSet resultSet = statement.executeQuery(sql);
int result = -1;
if (resultSet.next()){
result = resultSet.getInt(1);
}
if (result > 0){
System.out.println("登录成功!");
}
else {
System.out.println("登录失败!");
}
}
}
很正常,登录成功、失败
但是,当用户名是这样的abc' or 1=1 --
登录也成功了!!
这是为什么??
我们的查询语句是这样的:
select * from login where name='"+userName+"'and password='"+pwd+"'
其中通过传入name和password查询
正常情况下是没问题的,但是当输入用户名abc' or 1=1 --
后
我们的select语句变成了
select * from login where name='abc' or 1=1 --'and password='"+pwd+"'
这个语句就变成了一定正确的了:or 1=1 ,前面name的查询正确,sql中 – 代表注释,它就将password的验证注释掉了
这样就导致了sql验证成功
当然这只是在JDBC中sql注入的一个简单的例子,
sql注入就是将客户输入的内容与开发人员输入的sql语句混为一体
具体的查看百度-sql注入
怎么解决?
如果在JDBC中,使用Statement就会存在Sql注入的安全问题,换成PreparedStatement就可以很好的防备Sql注入
package com.company.JDBC;
import javafx.scene.transform.Scale;
import java.sql.*;
import java.util.Scanner;
public class test {
private static String url = "jdbc:mysql://localhost:3306/test";
static String name = "root";
static String password = "root";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Connection connection = null;
PreparedStatement statement = null;
//JVM创建DriverManager
Class.forName("com.mysql.jdbc.Driver");
//创建连接
connection = DriverManager.getConnection(url, name, password);
//sql语句操作数据库
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String userName = scanner.nextLine();
System.out.println("请输入密码:");
String pwd = scanner.nextLine();
String sql = "select * from login where name=? and password=?";
statement = connection.prepareStatement(sql);
statement.setString(1,userName);
statement.setString(2,pwd);
//返回结果集ResultSet
ResultSet resultSet = statement.executeQuery();
int result = -1;
if (resultSet.next()){
result = resultSet.getInt(1);
}
if (result > 0){
System.out.println("登录成功!");
}
else {
System.out.println("登录失败!");
}
}
}
至于PreparedStatement为什么可以防备Sql注入,可以看JDBC详解
真的了解JDBC吗?- JDBC详解