JavaWeb学习-JDBC系列-10-SQL注入问题和PreparedStatement对象

本文主要是介绍JavaWeb学习-JDBC系列-10-SQL注入问题和PreparedStatement对象,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前面我们用JDBC模拟了一个用户登录的问题,看起来很棒,没有什么问题,是不是。其实,知道sql注入问题的人就会发现这个代码这样写是不对的,百分百引发sql注入问题。本篇来学习什么是SQL注入问题和如何解决这个问题。

1.什么是SQL注入问题

现在代码还是前面一篇的代码,我们再次运行Login.java这个main方法,看看下面我是如何输入的

请输入用户名:
asdf
请输入密码:
asdf' or '1'='1欢迎回来,Lucy

这里我们明明输入了一个不存在的用户asdf,密码这个输入就有讲究,sql注入就出现在这里。这里看看我如何解释这个sql注入,为什么会打印 欢迎回来,Lucy.

先贴出我表的全部内容。

关键出问题代码

String sql = "SELECT * FROM student WHERE Name='"+ username +"' AND pwd='"+ password +"'";

在上面我们sql语句中使用了'变量名'的格式来表示这里有一个变量需要引用。这里我们用户名是asdf,密码是asdf' or '1'='1, 我们把这两个变量的值替代到sql语句中去,结果是这样的。

String sql = "SELECT * FROM student WHERE Name='asdf' AND pwd='asdf' or '1'='1'";

注意我密码为什么要写成asdf' or '1'='1,看起来前后都丢了一个单引号。没错,证书前后丢了单引号,导致上面这行sql语句其实变成了三个逻辑条件的语句:

String sql = "SELECT * FROM student WHERE Name='asdf'AND pwd='asdf'or '1'='1'";

上面三个表达式语句,前面两个查询的结果不存在。关键在于第三个表达式 or 表示或的逻辑关系,后面1=1这个肯定返回true,所以不管前面两个表达式结果返回false,加上了or后面的1=1,这个sql语句实际上返回结果是true。一旦返回为true,那么结果集对象rs就有next()方法,也就是这里查询的第一行数据,刚好我们表中第一行数据的用户名是Lucy,所以这个打印“欢迎回来,Lucy”, 就是这么来的。

这个过程就是SQL注入攻击,你看看随便输入一个用户名和密码,就查询到了我们数据表中的用户名这个信息。如果这个信息拿出来去做其他的分析和碰撞,黑客很可能拿到这个用户的密码。这样用户信息就泄露了,带来了安全问题。

 

2.使用PreparedStatement解决sql注入问题

既然这个sql注入问题大家都知道,那么肯定有解决办法。所以,这里学习一个新的对象PreparedStatement,看到这个对象名称,我们很容易想起Statement对象。没错,两个对象是有关系的,PreparedStatement是Statement的子类,而且PreparedStatement使用有下面特点:

1. 性能要比Statement高
2. 会把SQL语句先编译
3. SQL语句中的参数会发生变化,过滤掉用户输入的关键字,例如我们前面sql注入的or这个关键字

使用PreparedStatement修改DoLogin.java内容。

package com.anthony.login;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;import com.anthony.utils.DBUtils;public class DoLogin {public Student findUser(String username, String password) {Connection conn = null;PreparedStatement stmt = null;ResultSet rs = null;Student s = null;try {conn = DBUtils.getConnection();String sql = "SELECT * FROM student WHERE Name=? AND pwd=?";stmt = conn.prepareStatement(sql);//给SQL中的?赋值,有几个?就要写几个设置语句。 ?在这里是占位符的作用stmt.setString(1, username);stmt.setString(2, password);rs = stmt.executeQuery();if(rs.next()) {s = new Student();s.setName(rs.getString("Name"));s.setAge(rs.getInt("Age"));s.setGender(rs.getString("Gender"));s.setId(rs.getInt("ID"));s.setPassword(rs.getString("pwd"));}} catch (Exception e) {e.printStackTrace();}return s;}}

上面注意这几行代码,看看我写的注释也就明白了,这里问号是占位符的作用,SQL语句提前进行了编译和过滤。

String sql = "SELECT * FROM student WHERE Name=? AND pwd=?";
stmt = conn.prepareStatement(sql);
//给SQL中的?赋值,有几个?就要写几个设置语句。 ?在这里是占位符的作用
stmt.setString(1, username);
stmt.setString(2, password);
rs = stmt.executeQuery();

测试下效果

请输入用户名:
asdf
请输入密码:
asdf' or '1'='1用户名或密码错误!

我们本来还是想利用前面的sql注入写法,结果却是不行,使用了PreparedStatement对象之后,sql先进行了编译和过滤关键字,所以用户还是老老实实去写正确用户名和密码,别耽误时间去找这个sql注入攻击的漏洞。

这篇关于JavaWeb学习-JDBC系列-10-SQL注入问题和PreparedStatement对象的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1050994

相关文章

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq