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注入攻击的主要内容,如果未能解决你的问题,请参考以下文章