JDBC中碰到的SQL安全问题 - Sql注入

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详解

发布了109 篇原创文章 · 获赞 31 · 访问量 7369

猜你喜欢

转载自blog.csdn.net/key_768/article/details/105332272
今日推荐