当前位置:   article > 正文

JDBC中使用preparedStatement防止SQL注入_jdbc中oracle驱动解析防注入

jdbc中oracle驱动解析防注入

一、SQL注入

SQL注入是一种比较常见的网路攻击方式,一些恶意人员在需要用户输入的地方,恶意输入SQL语句的片段,通过SQL语句,实现无账号登录,甚至篡改数据库。

二、SQL注入实例

登录场景:
在一个登录界面,要求用户输入账号和密码。

我们的代码中会有如下SQL语句:

String sql="select * from user where account='"+account+"' and password='"+password+"'";
  • 1

情形1:(免账号登录)

账号:' or 1=1----后面有一个空格)
密码:
当我们输入了这个账号和密码,那么SQL语句就变成:

String sql="select * from user where account='' or 1=1 -- ' and password=''";

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
这个查询条件就变成account=‘’ 或者1=1,这个条件是恒成立的。
后面的-- ,就是注释。
这样就可以实现免账号登录。

情形2:(删除数据库)

账号:';drop database test;----后面有一个空格)
密码:
当我们输入了这个账号和密码,那么SQL语句就变成:

String sql="select * from user where account='';drop database test;-- ' and password=''";
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述
这个查询条件就变成account=‘’ 或者1=1,这个条件是恒成立的。
后面的-- ,就是注释。
这样就能删除数据库。

三、防止SQL注入方法

使用PreparedStatement可以防止SQL注入。sql语句中的参数需要用?代替。PreparedStatement对sql预编译后,然后调用setXX()方法设置sql语句中的参数。这样再传入特殊值,也不会出现sql注入的问题了。

四、登录项目

1、用户表

用户的账号信息:

create table user(
id int primary key auto_increment,
account varchar(20),
password varchar(20),
nickname varchar(20)
);

insert into user(account,password,nickname) values('Jack','123456','杰克');
insert into user(account,password,nickname) values('Mary','888888','玛丽');

select*from user;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这里插入图片描述
2、项目结构

创建一个javaweb项目。Login类实现登录功能,用Junit进行单元测试,创建LoginTest类实现登录测试功能。
在这里插入图片描述
3、登录实现

Login.java

package net.jdbc.test;

import java.math.BigDecimal;
import java.sql.*;

public class Login {
    //数据库url、用户名和密码
    static final String DB_URL="jdbc:mysql://localhost:3306/test?";
    static final String USER="root";
    static final String PASS="root123";
    public static void login(String account,String password) {
        try {
            //1、注册JDBC驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2、获取数据库连接
            Connection connection = DriverManager.getConnection(DB_URL, USER, PASS);
            //3、操作数据库
            String sql="select * from user where account=? and password=?";

            //获取操作数据库的对象
            //用PreparedStatement可以预防SQL注入
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,account);//设置参数
            preparedStatement.setString(2,password);
            ResultSet resultSet = preparedStatement.executeQuery();//执行查询sql,获取结果集

            if (resultSet.next()){ //遍历结果集,取出数据
                String name = resultSet.getString("nickname");
                //输出数据
                System.out.println(name+"登录成功");
            }else{
                System.out.println("用户登录失败......");
            }
            //4、关闭结果集、数据库操作对象、数据库连接
            resultSet.close();
            preparedStatement.close();
            connection.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch(SQLException e){
            e.printStackTrace();
        } catch(Exception e){
            e.printStackTrace();
        }
    }

}
  • 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
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

4、登录测试

LoginTest.java

package net.jdbc.test;

import org.junit.Test;

import static org.junit.Assert.*;

public class LoginTest {

    @Test
    public void login() {
        Login.login("' or 1=1-- ","");//SQL注入测试
        Login.login("Jack","123");//正确账号,错误密码
        Login.login("Jack","123456");
        Login.login("Mary","888888");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

运行结果:
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/617863
推荐阅读
相关标签
  

闽ICP备14008679号