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();
        }
    }
    /**
     * 连接数据库
     * @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();
        }
        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条件永远为真。

原文地址:https://www.cnblogs.com/aeon/p/10073717.html

时间: 2024-07-29 19:52:34

jdbc_012_使用jdbc操作实现登录操作并且演示SQL注入攻击的相关文章

Java学习笔记47(JDBC、SQL注入攻击原理以及解决)

JDBC:java的数据库连接 JDBC本质是一套API,由开发公司定义的类和接口 这里使用mysql驱动,是一套类库,实现了接口 驱动程序类库,实现接口重写方法,由驱动程序操作数据库 JDBC操作步骤: 1.注册驱动 2.获得连接 3.获得语句执行平台 4.执行sql语句 5.处理结果 6.释放资源 1.导入jar包,可以在网上下载到,这里使用的是:mysql-connector-java-5.1.37-bin.jar 注册驱动: package demo; import java.sql.D

session标签实例:简单的系统登录代码(巧妙地避开SQL注入攻击)

提交用户名和密码到服务器,以用户为条件查询用户记录,然后判断用户是不是已经注册,若注册就判断密码是否正确,正确则成功登录,在会话中记录用户的相关信息.查询中只以用户名为条件,让数据库从单列索引中快速找出匹配的用户记录,速度远快于同时使用用户名和密码作为条件的查询,而且还巧妙地避开了SQL注入攻击. 登录页 表单代码 <FORM name=form1 action="" method=post onsubmit="return checkval();">

防止SQL注入攻击,数据库操作类

如果不规避,在黑窗口里面输入内容时利用拼接语句可以对数据进行攻击 如:输入Code值 p001' union select * from Info where '1'='1 //这样可以查询到所有数据 SQL数据库字符串注入攻击:需要使用cmd.Parameters这个集合占位符: @key 代表这个位置用这个占位符占住了 Parameters这个集合中将此占位符所代表的数据补全 cmd.Parameters.Clear(); --添加占位符数据之前,要清空此集合cmd.Parameters.A

JDBC学习笔记(6):PreparedStatement解决SQL注入问题

SQL注入问题:要求根据传入的name查询指定用户信息: 1 package com.xxyh.jdbc; 2 import java.sql.Connection; 3 import java.sql.ResultSet; 4 import java.sql.SQLException; 5 import java.sql.Statement; 6 7 public class SQLInject { 8 9 public static void main(String[] args) thro

数据库安全性操作——操作原则及SQL注入

今天在进行支付宝开发时,看到支付宝开发文档<开放平台第三方应用安全开发指南>中关于数据库操作的安全性.特此记录! 1.数据库操作 (1)原则:用户密码存储须加盐存储,各用户盐值不同. (2)原则:若涉及证件号等敏感信息的存储,须使用AES-128算法加密存储. (3)编写的SQL必须预编译,不允许通过字符串拼接的方式合成. 说明:1.部分特殊场景,必须通过拼接合成,则拼接的变量必须经过处理,只允许[a-zA-Z0-9_-.]+字符. 2.参考SQL注入漏洞. 2.SQL注入漏洞 SQL注入攻击

通过jdbc使用PreparedStatement,提升性能,防止sql注入

为什么要使用PreparedStatement? 一.通过PreparedStatement提升性能 Statement主要用于执行静态SQL语句,即内容固定不变的SQL语句.Statement每执行一次都要对传入的SQL语句编译一次,效率较差.     某些情况下,SQL语句只是其中的参数有所不同,其余子句完全相同,适用于PreparedStatement.PreparedStatement的另外一个好处就是预防sql注入攻击     PreparedStatement是接口,继承自State

【Java编程】JDBC注入攻击-Statement 与 PreparedStatement

在上一篇[Java编程]建立一个简单的JDBC连接-Drivers, Connection, Statement and PreparedStatement我们介绍了如何使用JDBC驱动建立一个简单的连接,并实现使用Statement和PreparedStatement进行数据库查询,本篇blog将接着上篇blog通过SQL注入攻击比较Statement和PreparedStatement.当然这两者还有很多其他方面的不同,在之后的blog中会继续更新. [Statement查询] 1.在DBH

jdbc mysql crud dao模型 sql注入漏洞 jdbc 操作大文件

day17总结 今日内容 l JDBC 1.1 上次课内容总结 SQL语句: 1.外键约束:foreign key * 维护多个表关系! * 用来保证数据完整性! 2.三种关系: * 一对多: * 一个客户可以对应多个订单,一个订单只属于一个客户! * 建表原则: * 在多的一方创建一个字段,作为外键指向一的一方的主键!!! * 多对多: * 一个学生可以选择多个课程,一个课程也可以被多个学生选择! * 建表原则: * 创建第三张表,第三张表中放入两个字段,作为外键分别指向多对多双方的主键! *

jdbc调用 oracle 存储过程操作

创建有参存储函数findEmpNameAndSal(编号),查询7902号员工的的姓名和月薪,[返回多个值,演示out的用法]当返回2个或多个值,必须使用out符号当返回1个值,就无需out符号 create or replace function findEmpNameAndSal(pempno in number,pename out varchar2) return numberas psal emp.sal%type;begin select ename,sal into pename,