jdbc中预防SQL攻击

目录

展示SQL攻击

举一个出现sql 攻击的例子

SQL攻击的原因

 分析原因

阻止SQL攻击

PreparedStatement的含义

使用PreparedStatement的原因

步骤如下

注意

总结


展示SQL攻击

举一个出现sql 攻击的例子

假设我们在做登录业务时,思路是这样的

  1. 首先 收集用户输入的用户名,
  2. 其次密码和数据库中用户表中的信息逐个比对,如果相同则登录成功;否则登录失败 ,表示用户表中没有该用户信息,需要注册

用户名:tom , 密码 123 。 user 表中已存在该信息

测试代码如下

   login("tom", "123");

login方法代码如下

public static void login(String username1, String password1) {String url = "jdbc:mysql://localhost:3306/dj666";String username = "root";String password = "123456";Connection conn = null;Statement statement = null;try {conn = DriverManager.getConnection(url, username, password);statement = conn.createStatement();String sql = "select * from user where pwd='" + password1 + "' and username='" + username1 + "'";ResultSet resultSet = statement.executeQuery(sql);if (resultSet.next()) {System.out.println("登录成功");} else {System.out.println("登录失败");}} catch (SQLException e) {throw new RuntimeException(e);} finally {try {if (statement != null)statement.close();else if (conn != null)conn.close();} catch (SQLException e) {throw new RuntimeException(e);}}}

因为user表 有这条用户信息,所有肯定是登录成功的

但实际上,用户在设置个人信息,不会这么简单,或许会更加的复杂

如下面所示:

login("a' or '1'='1", "a' or '1'='1");

我们知道,上面的信息在user用户表中,是没有的。也因此会登录失败

但运行后发现,“登录成功” 这就有问题!!!!!!!!!!!!

SQL攻击的原因

 分析原因

一个不存在的信息,却可以登录成功这是为什么呢

我们把用户输入的信息和查询的sql语句连起来,发现变成了一条完成的SQL查询语句

select * from user where pwd='a' or '1'='1' and username='a' or '1'='1'

发现 在我们添加 个人信息时,使用or  但在数据库中, or会被视为 关键字,并且or关键字 把用户输入的信息连接为一条完成的sql语句片段 。因此 where条件,一直是true 。即使用户表中,没有这条信息,也会被识别并登录成功。

当然,还不止于此:具体原因如下

在需要用户输入的地方,用户输入的是SQL语句的片段,最终用户输入的SQL片段与我们DAO中写的SQL语句合成一个完整的SQL语句!例如用户在登录时输入的用户名和密码都是为SQL语句的片段!

但我们应该如何避免,既可以使用像or 这样容易被数据库看作关键字的 单词,又不会被数据库识别成关键字

阻止SQL攻击

PreparedStatement的含义

PreparedStatement叫预编译声明!

PreparedStatement是Statement的子接口,你可以使用PreparedStatement来替换Statement。

使用PreparedStatement的原因

  • 防止SQL攻击
  • 提高代码的可读性,以可维护性
  • PreparedStatement的使用

步骤如下

1 使用Connection 对象调用 PreparedStatement(String sql) 方法 参数为 我们使用的sql语句模板。变量用?表示

  String sql = "update student set stuName=?,stuAge=?,stuSex=? where stuId=?";//获取执行sql语句的对象preparedStatement = conn.prepareStatement(sql);

2 调用PreparedStatement的setXXX()系列方法为问号 “?”设置值 。占位符 从1 开始

   preparedStatement.setString(1, password1);preparedStatement.setString(2, username1);

3 调用executeUpdate()或executeQuery()方法,但要注意,调用没有参数的方法;

修改上面的代码如下

    //sql语句模板String sql = "select * from user where pwd=? and username=?";//获取执行sql语句的对象preparedStatement = conn.prepareStatement(sql);// 1 表示占位符的索引,从1开始preparedStatement.setString(1, password1);preparedStatement.setString(2, username1);// 调用executeQuery方法,执行sql语句ResultSet resultSet = preparedStatement.executeQuery();

注意

  • 1 SQL语句中的问号,表示参数,后面使用setxx(占位符索引,传递的实参),为参数赋值,变成一条完整的SQL语句。
  • 2 PreparedStatement 的executeQuery()方法 是没有参数的,这是PreparedStatement 独有的;而Statement的executeQuery()是需要参数(SQL语句)的

疑问,为什么PreparedStatement 的executeQuery()方法 是没有参数的?

理由如下:

因为在创建PreparedStatement对象时已经让它与一条SQL模板绑定在一起了。所以在调用它的executeQuery()和executeUpdate()方法时就不再需要参数了。

修改后login方法代码如下

  public static void login(String username1, String password1) {String url = "jdbc:mysql://localhost:3306/dj666";String username = "root";String password = "123456";Connection conn = null;PreparedStatement preparedStatement=null;try {conn = DriverManager.getConnection(url, username, password);//sql语句模板String sql = "select * from user where pwd=? and username=?";//获取执行sql语句的对象preparedStatement = conn.prepareStatement(sql);// 1 表示占位符的索引,从1开始preparedStatement.setString(1, password1);preparedStatement.setString(2, username1);// 调用executeQuery方法,执行sql语句ResultSet resultSet = preparedStatement.executeQuery();if (resultSet.next()) {System.out.println("登录成功");} else {System.out.println("登录失败");}} catch (SQLException e) {throw new RuntimeException(e);} finally {try {if (preparedStatement != null)preparedStatement.close();else if (conn != null)conn.close();} catch (SQLException e) {throw new RuntimeException(e);}}}

运行结果

发现,使用了PreparedStatement后可以处理sql攻击

总结

所以,建议大家在今后的开发中,无论什么情况,都去使用PreparedStatement,而不是使用Statement,这样可以极大的避免因输入的内容(向变量传递值)造成SQL语句和原本我们所想的SQL不同造成的结果错误。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

30.1 时序数据库TSDB的典型特点

本节重点介绍 : db-ranking网站对db进行排名时序数据特点时序数据库特点时序数据库遇到的挑战开源时间序列数据库 db-ranking 一个神奇的网站 https://db-engines.com/en/ranking 时序数据ranking https://db-engines.com/en/ranking/timeseriesdbms 排名方法 https://db-en…

14:00面试,14:06就出来了,问的问题过于变态了。。。

我从一家小公司转投到另一家公司,期待着新的工作环境和机会。然而,新公司的加班文化让我有些始料未及。虽然薪资相对较高,但长时间的工作和缺乏休息使我身心俱疲。 就在我逐渐适应这种高强度的工作节奏时,公司突然宣布了一则令人…

架构师之路-学渣到学霸历程-49

实现不同终端的跳转实验 今天分享一下: nginx的跳转:主要看你的访问是手机还是网页;于是就有这个跳转的功能; 1、基础的环境部署 安装好nginx(这里最好的就是干净的环境)创建两个server;用于…

RK3568笔记1:BootRom

BootRom是瑞芯微公司在生产的CPU时,存储在内部flash中的一段固件代码,用于初始化硬件和启动系统。 RK3568 处理器也具备 BootROM。这是存储在处理器内部的只读存储器 (ROM) 中的一段代码,通常是不可修改的,其主要功能是在设备加电…

DataWind将字符串数组拆出多行的方法

摘要: 可视化建模中先将字符串split为array再用explode(array)即可 可视化建模 进入“可视化建模”页面 1.1 新建任务 如果团队内没有可视化建模任务。请点击“新建任务”,输入名称并确定。 1.2 建立数据连接 在左边栏中选择“数据连接”&#xff0c…

2024年【电工(中级)】考试及电工(中级)考试报名

题库来源:安全生产模拟考试一点通公众号小程序 电工(中级)考试参考答案及电工(中级)考试试题解析是安全生产模拟考试一点通题库老师及电工(中级)操作证已考过的学员汇总,相对有效帮…

【韩老师零基础30天学会Java】02章

sublime Text中本身没有GBK编码,需要安装 要在sublime Text中设置编码为GBK,请按照以下步骤操作 打开Sublime Text编辑器,点击菜单栏中的“Preferences”(首选项)选项,找打Package Control选项。点击Package Control,随后搜索Inst…

Pytorch实现运动鞋识别

Pytorch实现运动鞋识别 🍨 本文为🔗365天深度学习训练营 中的学习记录博客 🍖 原作者:K同学啊 电脑系统:Windows11 显卡型号:NVIDIA Quadro P620 语言环境:python 3.9.7 编译器:j…

老年人跌倒智能检测系统

项目源码获取方式见文章末尾! 600多个深度学习项目资料,快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

Spring Boot原理全解析:如何让开发更轻松高效(二)-起步依赖、自动装配

通过这篇博客,读者将能够掌握 Spring Boot 中的配置优先级和 Bean 管理的核心原理,为开发更加高效、可维护的 Spring Boot 应用打下坚实的基础。 目录 前言 起步依赖 自动配置 概述 常见方案 概述 方案一 方案二 总结 前言 通过这篇博客&#xf…

测试实项中的偶必现难测bug--短信触发H5拒绝行为

问题描述: 企业邀请其他人加入团队,发送邀请短信给对方,对方通过短信链接跳转到H5页面,输入手机后,点击发送验证码,前提是短信通知验证弹窗需要打开,收到短信验证码后,点击一键代入,会触发拒绝加入行为。 需求: 由于我们的邀请链接是一次性的,一旦有用户确认加入或…

PVE纵览-PVE与VM:谁才是你的最佳虚拟化选择?

PVE纵览-PVE与VM:谁才是你的最佳虚拟化选择? 文章目录 PVE纵览-PVE与VM:谁才是你的最佳虚拟化选择?摘要1 不同虚拟化平台的基础2 平台特性与功能3 性能与可靠性4 成本与经济性5 应用场景比较6 用户体验与支持7 结论与建议 关键字&…

陪诊问诊APP开发实战:基于互联网医院系统源码的搭建详解

时下,开发一款功能全面、用户体验良好的陪诊问诊APP成为了医疗行业的一大热点。本文将结合互联网医院系统源码,详细解析陪诊问诊APP的开发过程,为开发者提供实用的开发方案与技术指导。 一、陪诊问诊APP的背景与功能需求 陪诊问诊APP核心目…

post sim下如何将timing信息反标到仿真工具

文章目录 0 前言1 调用格式2 option介绍2.1 sdf_file (**必须**)2.2 module_instance (**可选**)2.3 config_file (**可选**)2.4 log_file (**可选**)2.5 mtm_spec (**可选**)2.6 scale_factors (**可选**)2.7 scale_type (**可选**) 0 前言 跑post sim时需要带入timing信息&a…

C++builder中的人工智能(16):神经网络中的SoftPlus激活函数

现在我们继续探索一下SoftPlus激活函数在人工神经网络(ANN)中的应用。了解SoftPlus激活函数的工作原理,将有助于您在使用C IDE构建C应用程序时更加得心应手。 目录 神经网络中的激活函数是什么?能在C中创建激活函数吗&#xff1f…

【图】图学习

0 回顾数据结构逻辑 1 图的定义和基本术语 必须有顶点,可以没有边。 Cn2和2*Cn2(数学上的,n个顶点取2个顶点) 概念有些多。。。。。。

类和对象(C++)(中)

1. 类的默认成员函数 默认成员函数就是⽤⼾没有显式实现,编译器会⾃动⽣成的成员函数称为默认成员函数。⼀个类,我们不写的情况下编译器会默认⽣成以下6个默认成员函数,需要注意的是这6个中最重要的是前4个,最后两个取地址重载不重…

港科夜闻 | 香港科大校董会汇聚顶尖医学专家及学者,为筹建第三间医学院提供专业意见...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大校董会汇聚顶尖医学专家及学者,为筹建第三间医学院提供专业意见。为支持政府及其新成立的工作组发展香港成为国际医疗培训、研究和创新枢纽,以及培养更多医生的愿景,香港科大于…

23.智能停车计费系统(基于springboot和vue的Java项目)

目录 1.系统的受众说明 2 相关概念和技术介绍 2.1 JAVA技术介绍 2.2 SpringBoot框架 2.3B/S架构 2.4 MySQL数据库 3 系统需求分析 3.1 问题定义 3.2 可行性分析 3.3系统用例分析 3.4 系统流程分析 3.4.1 登录流程 3.4.2 添加信息流程 3.4.3 删除信息流程 4…

golang安装,常用框架安装,记忆点

0.安装 虚拟机扩容 【Linux干货分享】LVM快速扩容虚拟机磁盘_哔哩哔哩_bilibili newvim 安装 sudo add-apt-repository ppa:neovim-ppa/stable sudo apt-get update sudo apt-get install -y neovim 最强Vim新手指南,手把手教你打造只属于自己的代码编辑器&am…