jdbc_012_使用jdbc操作实现登录操作并且演示SQL注入攻击

Posted 1024军团

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdbc_012_使用jdbc操作实现登录操作并且演示SQL注入攻击相关的知识,希望对你有一定的参考价值。

一、建库及表语句(简单测试)

drop database db_test;
create database db_test;
use db_test;
create table user(
    userId int(5) primary key comment \'用户id\',
    userName varchar(16) comment \'用户姓名\',
    userPw varchar(16) comment \'用户密码\'
);
insert into user(userId,userName,userPw) values(10001,\'user1\',\'user1\');
insert into user(userId,userName,userPw) values(10002,\'user2\',\'user2\');
insert into user(userId,userName,userPw) values(10003,\'user3\',\'user3\');
insert into user(userId,userName,userPw) values(10004,\'user4\',\'user4\');
insert into user(userId,userName,userPw) values(10005,\'user5\',\'user5\');

二、封装jdbc的工具类(同上集)

package edu.aeon.aeonutils;

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

/**
 * [说明]:jdbc工具类
 * 封装了jdbc里面的重复步骤:数据库的连接和数据库资源的释放
 * @author aeon
 * @version 1.2(该版本将连接数据库的各种数据库配置信息(用户名、密码、驱动及url)单独提取到配置文件中)
 */
public class AeonJdbcUtils {
    private static String username;
    private static String password;
    private static String driverClass;
    private static String url;
    /**
     * 静态代码块处理读取之前的数据
     */
    static{
        InputStream inputStream = AeonJdbcUtils.class.getClassLoader().getResourceAsStream("config/database/database.properties");
        Properties properties=new Properties();
        try {
            properties.load(inputStream);
            username = properties.getProperty("username");
            password = properties.getProperty("password");
            driverClass = properties.getProperty("driverClass");
            url = properties.getProperty("url");
        } catch (IOException e) {
            System.out.println("初始化读取数据库配置文件--->database.properties失败!");
            e.printStackTrace();
        }finally{
     //关闭流
    } }
/** * 连接数据库 * @return 数据库连接对象 * @throws ClassNotFoundException * @throws SQLException */ public static Connection getmysqlConnection() throws ClassNotFoundException, SQLException{ Class.forName(driverClass); return DriverManager.getConnection(url, username, password); } /** * 释放数据库资源 * @param resultSet 结果集 * @param statement 执行sql语句的对象 * @param connection 数据库连接对象 */ public static void closeDB(ResultSet resultSet,Statement statement,Connection connection){ if(null!=resultSet){ try { resultSet.close(); } catch (SQLException e) { System.out.println("释放数据库资源失败!--->resultSet"); e.printStackTrace(); } } if(null!=statement){ try { statement.close(); } catch (SQLException e) { System.out.println("释放数据库资源失败!--->statement"); e.printStackTrace(); } } if(null!=connection){ try { connection.close(); } catch (SQLException e) { System.out.println("释放数据库资源失败!--->connection"); e.printStackTrace(); } } } }

三、包视图截图:

  

四、数据库配置信息database.properties  

 username=root
 password=root
 driverClass=com.mysql.jdbc.Driver
 url=jdbc:mysql://localhost:3306/db_test

五、数据库截图信息:

  

 

六、用户登录

package edu.aeon.logon;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import edu.aeon.aeonutils.AeonJdbcUtils;
/**
 * [说明]:实现用户登录、并且演示sql注入攻击
 * 造成sql注入攻击的原因
 *     1.and和or的优先级(and(可以理解为并且)优先与or(可以理解为或者))其实是构造or的条件来无视and条件()
 *     2.sql语句的拼接
 * 如何解决sql注入攻击?
 *     数据库and 和 or的优先级天生的、我们无法改变
 *     唯一解决思路:改变sql语句的拼接、(详见下集)
 * @author aeon
 *
 */
public class UserLogon {
    /**
     * 封装键盘输入
     * @return
     */
    public static Map<String, String> ReadBoard(){
        /**
         * 键盘扫描器:扫描键盘输入的内容
         */
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username=scanner.nextLine();//以\\n作为一行的标识来读取一行
        System.out.println("请输入密码:");
        String password=scanner.nextLine();
        Map<String, String> userMap=new HashMap<String, String>();
        //将键盘输入的内容封装到map集合中、并且返回给调用者
        userMap.put("username", username);
        userMap.put("password", password);
        return userMap;
    }
    /**
     * 用户登录具体实现
     * @return 登录成功标志 true则登录成功、否则失败!
     */
    public static boolean userLogon(){
        boolean flag=false;
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            //连接数据库
            connection = AeonJdbcUtils.getMySqlConnection();
            //获得执行sql语句对象
            statement = connection.createStatement();
            //获取到用户输入的数据
            Map<String, String> userMap=ReadBoard();
            //登录sql
            String logonSql="select * from user where username=\'"+userMap.get("username")+"\' and userpw =\'"+userMap.get("password")+"\'";
            System.out.println("登录的sql语句为:"+logonSql);
            resultSet = statement.executeQuery(logonSql);
            if(resultSet.next()){ //如果数据库中有记录则将登录标志flag置为true
                flag = true;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
      AeonJdbcUtils.closeDB(resultSet, statement, connection);

   }

return flag;
    }
    /**
     * 用户登录测试
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(userLogon()?"用户登录成功!":"用户登录失败!");
    }
}

 执行结果截图(我们输入数据库中根本不存在的用户和密码):

  

 执行结果截图(我们输入数据库中存在的用户和其对应密码):

  

执行结果截图(构造sql注入攻击):

  

 用or来使的前面and条件无效、其实这条sql攻击语句最后执行等同于:select * from user where \'x\'=\'x\'

我们可以看出where条件永远为真。实则和select * from user;效果无疑!

以上是关于jdbc_012_使用jdbc操作实现登录操作并且演示SQL注入攻击的主要内容,如果未能解决你的问题,请参考以下文章

day14_DBUtils学习笔记

javaWeb_JDBC_面向对象编程在JDBC中的使用

Java oop第08章_JDBC01(入门)

阶段3 1.Mybatis_01.Mybatis课程介绍及环境搭建_03.jdbc操作数据库的问题分析

Web09_MySQL多表&JDBC

day06_JDBC学习笔记