SQL注入问题

一、什么是sql注入

public class TestSql {
	
    public static void main(String[] args) {
		Scanner inScanner = new Scanner(System.in);
		System.out.println("请输入用户名");
		String username = inScanner.nextLine();
		System.out.println("请输入密码");
		String password = inScanner.nextLine();
		String sql = "select * from user where username = '"+username+"' and password = '"+password+"'";
		search(sql);
	}

	public static void search(String sql) {
		try {
			Class.forName("com.mysql.jdbc.Driver"); // 1.加载驱动
			//2.建立连接
			Connection connection = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/login?useUnicode=true&characterEncoding=utf-8", "root", "");
			//3.创建执行的SQL语句
				
			Statement statement = (Statement) connection.createStatement();
			//4.执行sql语句
			ResultSet re = (ResultSet) statement.executeQuery(sql);
			//5.处理结果
			if(re.next()) {
				System.out.println("查询成功...");
			}else {
				System.out.println("查询失败...");
			}
	                 //6.释放资源
			if(re!=null) {
				re.close();
			}
			if(statement !=null) {
				statement.close();
			}
			if (connection !=null) {
				connection.close();
			}
				
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("找不到驱动类,加载失败");
			e.printStackTrace();
		} 
	}
	
}

以上的程序我们经过测试没什么问题,但是当输入如下数据的时候,一个可怕的问题出现了。

 

数据库中只有一个数据

那么为什么会产生这个现象呢?

我们将拼接好的sql语句拿出来

select * from user where username =' 111' and password = '1' or '1'='1';

我们将SQL语句拿到Navicat运行一下 

        这种通过传参就能改变SQL语句原本规则的操作就是SQL注入,这个在实际开发中当然是危险的,攻击者可以把SQL命令插入到Web表单的输入域或页面请求的查询字符串中,欺骗服务器执行恶意的SQL命令。

二、为什么会产生sql注入问题呢?

        我们可以把sql语句的执行流程大致分为一下几个步骤:

1.本地sql语句拼接

2.发送sql语句给DBMS

3.DBMS进行sql编译

        造成sql注入的原因在于我们在本地拼接了一条“有安全隐患的”sql语句。之后我们将拼接好的sql语句发送给DBMS,DBMS将“有安全隐患”的sql语句进行了编译执行。

这里的重点是:用户的信息参与到了编译过程,而这个信息出现了问题

三、如何解决sql注入问题呢?

        其实解决方法很简单:只要用户提供的信息不参与SQL语句的编译过程,问题就解决了。

要想让用户的信息不参与SQL语句的编译,那么就需要预先对sql语句的框架进行编译,然后再给给sql赋值。预编译完成之后我们的DBMS只需要执行我们的sql语句,没必要再次编译。可以使用java.sql.PreparedStatement接口完成预编译,PreparedStatement是属于预编译的数据库操作对象

使用PreparedStatement需要注意的几点

①:占位符

String sql = "select * from user where username = ? and password = ?";

我们拼写好的sql语句不在使用直接拼接赋值的方式,而是采用 ? 占位符进行代替

②:创建方式

statement.setString(1, usernanme);
statement.setString(2, password);

总体代码如下

public class TestSql {
	
	public static void main(String[] args) {
		Scanner inScanner = new Scanner(System.in);
		System.out.println("请输入用户名");
		String username = inScanner.nextLine();
		System.out.println("请输入密码");
		String password = inScanner.nextLine();
		String sql = "select * from user where username = ? and password = ?";
		search(sql,username,password);
	}

	public static void search(String sql,String usernanme,String password) {
		try {
			Class.forName("com.mysql.jdbc.Driver"); // 1.加载驱动
			//2.建立连接
			Connection connection = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/login?useUnicode=true&characterEncoding=utf-8", "root", "2020");
			//3.创建执行的SQL语句
			 PreparedStatement statement = (PreparedStatement) connection.prepareStatement(sql);
			// 给占位符赋值
			 statement.setString(1, usernanme);
			 statement.setString(2, password);
			
			//4.执行sql语句
			ResultSet re = (ResultSet) statement.executeQuery();
			//5.处理结果
			if(re.next()) {
				System.out.println("查询成功...");
			}else {
				System.out.println("查询失败...");
			}
	                //6.释放资源
			if(re!=null) {
				re.close();
			}
			if(statement !=null) {
				statement.close();
			}
			if (connection !=null) {
				connection.close();
			}
				
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("找不到驱动类,加载失败");
			e.printStackTrace();
		} 
	}
	
}

 

相关推荐

  1. SQL注入问题

    2024-07-17 02:06:02       27 阅读
  2. 关于SQL注入问题及解决--小记

    2024-07-17 02:06:02       46 阅读
  3. <span style='color:red;'>sql</span><span style='color:red;'>注入</span>

    sql注入

    2024-07-17 02:06:02      50 阅读
  4. <span style='color:red;'>SQL</span><span style='color:red;'>注入</span>

    SQL注入

    2024-07-17 02:06:02      49 阅读
  5. SQL注入

    2024-07-17 02:06:02       36 阅读
  6. <span style='color:red;'>SQL</span><span style='color:red;'>注入</span>

    SQL注入

    2024-07-17 02:06:02      34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 02:06:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 02:06:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 02:06:02       58 阅读
  4. Python语言-面向对象

    2024-07-17 02:06:02       69 阅读

热门阅读

  1. 记录第一次因为数据库事务产生的BUG

    2024-07-17 02:06:02       18 阅读
  2. 量化机器人如何提升交易透明度?

    2024-07-17 02:06:02       23 阅读
  3. Flutter基本概念&常用命名

    2024-07-17 02:06:02       23 阅读
  4. AI对开发者的影响:重塑技能、职业与生活

    2024-07-17 02:06:02       24 阅读
  5. CloudCone服务器2核1G一年只需15刀

    2024-07-17 02:06:02       19 阅读
  6. zookeeper+kafka消息队列群集部署

    2024-07-17 02:06:02       20 阅读
  7. Webflux中的订阅关系

    2024-07-17 02:06:02       20 阅读