当前位置:   article > 正文

使用PreparedStatement避免sql注入_preparedstatement防止sql注入

preparedstatement防止sql注入

使用PreparedStatement避免sql注入

1.sql注入产生的原因

在前面我们对数据库增删改查时,我们使用的是Statement方法,但是他是不能防止sql注入的,我们先来了解一下sql注入:

给出如下表

create table users(
usename varchar(20) primary key ,
password varchar(20)
);

再往表中插入数据:

insert into users values('root','123456');

此时我们在设计登录系统时,是需要判断用户名和密码是否可以对上,使用效率高的方法就是查询设置条件 用户名为 xx and 密码为xxx 看是否能返回,能返回说明可以接收到,也就是用户名和密码对得上,如下图所示:

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws SQLException, IOException, ClassNotFoundException {
        /*这里我使用了方法,包含注册驱动 构建连接等,会放在在最后*/
        Connection connection = GetConnection.getConnection();
        Scanner sc = new Scanner(System.in);
        String name = sc.nextLine();//输入用户名
        String password = sc.nextLine();//输入密码
        /*创建发送sql对象*/
        Statement statement = connection.createStatement();
        String sql = "Select * from users where `usename`= '" + name + "' and password = '" + password + "';";
        /*使用resultSet接收查询到的结果*/
        ResultSet resultSet = statement.executeQuery(sql);
        if (resultSet.next()) {
            System.out.println("登录成功!");
        } else {
            System.out.println("登录失败!");
        }
        /*关闭资源,这是我定义的方法,会放在最后*/
        JdbcUtils.closeAll(connection,statement,resultSet);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

当我们随便输入时,会提示登录失败!

在这里插入图片描述

但我们输入如下代码,就会提示登录成功

dqwdqw’ or 1 = 1;#
在这里插入图片描述

这里产生这种情况的原因是,我们在定义sql语句时,是把我们输入的部分聚合成字符串,再去执行语句,当时输入的部分内容有关键字时,他并不会做特殊处理,只会一股脑执行

Select * from users where `usename`= '" + name + "' and password = '" + password + "';
  • 1

当我们输入 dqwdqw’ or 1 = 1;# 时,就变成了

Select * from users where usename= ‘dqwdqw’ or 1 = 1; # and password = ‘" + password + "’;

此时#后面的就变成了注释,而select查询时,判断的是哪条语句能使where后面为真,当输入or 1=1 时候,后面就永远为真,所有语句都会存入resultSet中,这时候就会有人说可以将判断设置成resultSet = 1;但是这样就会出现当数据库中真的只有一条语句时,就会登录成功,所以为了避免这种情况,我们使用PreparedStatement来避免sql注入。

2.使用PreparedStatemen避免sql注入

先看如下代码:

import java.io.IOException;
import java.sql.*;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws SQLException, IOException, ClassNotFoundException {
        /*这里我使用了方法,包含注册驱动 构建连接等,会放在在最后*/
        Connection connection = GetConnection.getConnection();
        Scanner sc = new Scanner(System.in);
        String name = sc.nextLine();//输入用户名
        String password = sc.nextLine();//输入密码
        /*创建发送sql对象*/
        //Statement statement = connection.createStatement();
        //connection.prepareStatement(sql);
        String sql = "Select * from users where `usename`= ? and password = ?;";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setString(1,name);
        preparedStatement.setString(2,password);
        /*使用resultSet接收查询到的结果*/
        ResultSet resultSet = preparedStatement.executeQuery();
        if (resultSet.next()) {
            System.out.println("登录成功!");
        } else {
            System.out.println("登录失败!");
        }
        /*关闭资源,这是我定义的方法,会放在最后*/
        JdbcUtils.closeAll(connection,preparedStatement,resultSet);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

此时再输入该代码就不会出现问题:

在这里插入图片描述

原因是我们在sql代码执行前对它进行了预编译,此时他缺失的部分是使用占位符替代,而preparedStatement 最大的不同就在这里,他在将输入或者你给定的参数传入sql语句前会将所有的sql关键字转义成非关键字的字符,这样即使你使用关键字也没办法起到关键字的作用。

所以在使用上PreparedStatement的流程也会多一点,首先会被connection方法定义一次,进行预编译,然后再将占位符赋予真实的数值。最后再执行execute更新或者查询操作。

3.使用的GetConnection 方法:

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class GetConnection {

    final static  Properties PROPERTIES = new Properties();
    public static Connection getConnection() throws IOException, ClassNotFoundException, SQLException {
        //使用
        InputStream is = GetConnection.class.getResourceAsStream("/db.properties");
        PROPERTIES.load(is);//将is这个输入流的文件读进 properties类对象当中

        String driver = PROPERTIES.getProperty("driver");

        Class.forName(driver);//注册驱动
        String url = PROPERTIES.getProperty("url");//获取 url
        String username = PROPERTIES.getProperty("username");//获取username
        String password = PROPERTIES.getProperty("password");//获取password
        return  DriverManager.getConnection(url,username,password);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

4. 使用的JdbcUtils方法:

import java.sql.*;

public class JdbcUtils {
    public static void closeAll(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) throws SQLException {

        if (resultSet != null) {
            resultSet.close();
        }

        if (preparedStatement != null) {
            preparedStatement.close();
        }

        if (connection != null) {
            connection.close();
        }
    }


    public static void closeAll(Connection connection,
                                Statement statement, ResultSet resultSet) throws SQLException {

        if (resultSet != null) {
            resultSet.close();
        }

        if (statement != null) {
            statement.close();
        }

        if (connection != null) {
            connection.close();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/617869
推荐阅读
相关标签
  

闽ICP备14008679号