学习并理解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/jiudian?useUnicode=true&characterEncoding=utf-8", "root", "2020");
            //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语句原本规则的操作就是SQL注入,这个在实际生产中当然是危险的,攻击者可以把SQL命令插入到Web表单的输入域或页面请求的查询字符串中,欺骗服务器执行恶意的SQL命令。
以上的情况就属于sql注入攻击。

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

我们可以把sql语句的执行流程大致分为:

本地sql语句拼接 ------》发送sql语句给DBMS----->DBMS进行sql编译。

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

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

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

其实解决方法很简单:只要用户提供的信息不参与SQL语句的编译过程,问题就解决了。
要想让用户的信息不参与SQL语句的编译,那么就必须使用java.sql.PreparedStatement接口。
PreparedStatement是属于预编译的数据库操作对象,其原理是:预先对sql语句的框架进行编译,然后再给给sql赋值。预编译完成之后我们的DBMS只需要执行我们的sql语句,没必要再次编译。

使用PreparedStatement需要注意的几点
①:占位符

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

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

PreparedStatement statement = (PreparedStatement) connection.prepareStatement(sql);

在这个地方我们需要提前编译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/jiudian?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();
        } 
    }
    
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/399362.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【RN】为项目使用React Navigation中的navigator

简言 移动应用基本不会只由一个页面组成。管理多个页面的呈现、跳转的组件就是我们通常所说的导航器(navigator)。 React Navigation 提供了简单易用的跨平台导航方案,在 iOS 和 Android 上都可以进行翻页式、tab 选项卡式和抽屉式的导航布局…

防御第六次作业-防火墙综合实验(av、url过滤、dns过滤)

目录 拓扑图: 要求: 8 9 10 11 拓扑图 要求 前7个要求在上一篇博客; 8.分公司内部的客户端可以通过域名访问到内部的服务器 9.假设内网用户需要通过外网的web服务器和pop3邮件服务器下载文件和邮件,内网的FTP服务器也需要…

安装unget包 sqlsugar时报错,完整的报错解决

前置 .net6的开发环境 问题 ? 打开unget官网,搜索报错的依赖Oracle.ManagedDataAccess.Core unget官网 通过unget搜索Oracle.ManagedDataAccess.Core查看该依赖的依赖 发现应该是需要的依赖Oracle.ManagedDataAccess.Core(>3.21.100)不支持.net6的环境 解…

加载arcgis切片服务网络请求有大量404错误

需求: 前端访问arcgis切片服务时,在网络请求中出现大量404(Not Found)错误,切片时设置了感兴趣区域,在感兴趣范围内请求切片时能够正常返回切片。 问题分析: 设置感兴趣区域切片的目的是减少站…

基于Mapbox展示GDAL处理的3D行政区划展示实践

目录 前言 一、Gdal数据处理 1、数据展示 2、Java数据转换 二、Mapbox可视化 1、定义Mapbox地图 2、地图初始化 3、创建地图 三、界面优化 1、区域颜色设置 2、高度自适应和边界区分 3、中文标注 总结 前言 最近有遇到一个需求,用户想在地图上把行政区划…

IP地理位置查询定位:技术原理与实际应用

在互联网时代,IP地址是连接世界的桥梁,而了解IP地址的地理位置对于网络管理、个性化服务以及安全监控都至关重要。IP数据云将深入探讨IP地理位置查询定位的技术原理、实际应用场景以及相关的隐私保护问题,旨在为读者提供全面了解和应用该技术…

海外媒体发稿:提高用户留存率的7个链游媒体宣发推广策略-华媒舍

在当今数字化时代,移动链游已经成为人们生活中不可或缺的一部分。随着链游市场日益竞争激烈,如何提高用户留存率成为了游戏开发者和媒体宣发人员需要面对的重要问题。本文将为您介绍7个有效的链游媒体宣发推广策略,帮助您提高用户留存率。 1.…

Unity编辑器扩展之Text组件中字体替换工具

想要批量化替换项目预制体资源中Text组件引用的Font字体文件,可以采用以下步骤。 1、在项目的Editor文件中,新建一个名为FontToolEditor的C#脚本文件,然后把以下代码复制粘贴到新建的FontToolEditor的C#脚本文件中。 using System.Collect…

哪款护眼台灯适合孩子用?五大爆款选购指南分享

护眼台灯凭借各种好处让很多家长都为孩子选择。但是许多想要选择护眼台灯的家长们,各种台灯不能盲目入手,因为市面上存在各种生产实力不足,做工差,以及选材廉价等问题的劣质产品。那么护眼台灯要怎么选?关于这个问题&a…

2024牛客寒假算法基础集训营4(视频讲解题目)

2024牛客寒假算法基础集训营4&#xff08;视频讲解题目&#xff09; 视频链接ABCDEFG、H&#xff08;下面是hard版本的代码两个都可以过&#xff09; 视频链接 2024牛客寒假算法基础集训营4&#xff08;视频讲解题目&#xff09; A #include<bits/stdc.h> #define en…

在Win系统部署WampServer并实现公网访问本地服务【内网穿透】

目录 推荐 前言 1.WampServer下载安装 2.WampServer启动 3.安装cpolar内网穿透 3.1 注册账号 3.2 下载cpolar客户端 3.3 登录cpolar web ui管理界面 3.4 创建公网地址 4.固定公网地址访问 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0…

Windows系统安全策略设置之本地NTLM重放提权

经安全部门研究分析&#xff0c;近期利用NTLM重放机制入侵Windows 系统事件增多&#xff0c;入侵者主要通过Potato程序攻击拥有SYSTEM权限的端口伪造网络身份认证过程&#xff0c;利用NTLM重放机制骗取SYSTEM身份令牌&#xff0c;最终取得系统权限&#xff0c;该安全风险微软并…

vue3 用xlsx 解决 excel 低版本office无法打开问题

需求背景解决思路解决效果将json导出为excel将table导为excel导出样式 需求背景 原使用 vue3-json-excel &#xff0c;导致在笔记本office环境下&#xff0c;出现兼容性问题 <vue3-json-excel class"export-btn" :fetch"excelGetList" :fields"js…

国际贸易报关需要向海关提交哪些资料 | 全球数字贸易发展联盟 | 箱讯科技

1、进出口货物报关单。一般进口货物应填写一式二份;需要由海关核销的货物&#xff0c;如加工贸易货物和保税货物等&#xff0c;应填写专用报关单一式三份;货物出口后需国内退税的&#xff0c;应另填一份退税专用报关单。 2、货物发票。要求份数比报关单少一份&#xff0c;对货…

OpenProject 安装迁移

文章目录 1、概要2、备份3、新服务器安装OpenProject4、新服务器安装Postgresql5、旧服务器数据转移到新服务器5.1、转移attachments附件5.2、转移conf配置文件5.3、转移存储库5.4、导入Postgres数据库 6、openproject配置 1、概要 注意&#xff1a;本文仅适用于 DEB/RPM 包安…

高品质定制线缆厂家推荐:精工电联-打造智能智造的线缆解决方案(线缆定制流程)

高品质定制线缆厂家&#xff1a;精工电联-打造智能智造的线缆解决方案&#xff08;定制线缆定制流程&#xff09; 精工电联 在百年未有之大变局的当下&#xff0c;科技发展日新月异的今天&#xff0c;智能制造正在改变着各行各业的生产及人们的生活方式。作为线缆制造领域的领先…

0220作业

C语言实现LED1闪烁 led.h #ifndef __LED_H__ #define __LED_H__//RCC寄存器封装 #define RCC_MP_AHB4_ENSETR (*(volatile unsigned int*)0x50000A28) //寄存器封装//GPIO寄存器封装 typedef struct{volatile unsigned int MODER; //00volatile unsigned int OTYPER; //04vol…

c++:蓝桥杯中的基础算法1(枚举,双指针)

枚举 基础概念&#xff1a; 枚举&#xff08;Enum&#xff09;是一种用户定义的数据类型&#xff0c;用于定义一个有限集合的命名常量。在C中&#xff0c;枚举类型可以通过关键字enum来定义。 下面是一个简单的枚举类型的定义示例&#xff1a; #include <iostream>enum…

Spring Bean 的生命周期了解么?

Spring Bean 的生命周期基本流程 一个Spring的Bean从出生到销毁的全过程就是他的整个生命周期, 整个生命周期可以大致分为3个大的阶段 : 创建 使用 销毁 还可以分为5个小步骤 : 实例化(Bean的创建) , 初始化赋值, 注册Destruction回调 , Bean的正常使用 以及 Bean的销毁 …

leetcode 105. 从前序与中序遍历序列构造二叉树【构造二叉树】

原题链接&#xff1a;105. 从前序与中序遍历序列构造二叉树 题目描述&#xff1a; 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 输入输出描述&…