深入理解 SQL 注入漏洞及解决方案
一、引言
在当今数字化时代,数据库作为存储和管理数据的核心组件,其安全性至关重要。SQL 注入是一种常见且极具威胁性的数据库安全漏洞,它可能导致数据泄露、篡改甚至系统被完全控制。本文将深入探讨 SQL 注入漏洞的产生原因、表现形式以及如何有效地解决这一问题。
二、SQL 注入漏洞的产生效果
在已知用户名的情况下,攻击者可以通过输入特殊构造的密码,利用 SQL 注入漏洞绕过系统的身份验证机制,成功登录系统。例如,原本需要正确的用户名和密码才能访问的系统,攻击者只需输入特定的字符组合,如 “aaa'or'1=1” 作为密码(用户名已知),就可以在不知道正确密码的情况下登录进去,这显然严重破坏了系统的安全性和访问控制机制。
三、SQL 注入漏洞的产生原因
SQL 注入漏洞的产生主要源于应用程序在拼接 SQL 语句时没有对用户输入进行充分的验证和过滤。以常见的登录场景为例,后台程序拼接 SQL 语句的代码通常如下:
String sql = "select * from t_user where username = '"+username+"' and password = '"+password+"'";
在这种情况下,如果用户输入恶意的字符,就会改变 SQL 语句的逻辑。比如,当用户输入 “aaa'or'1=1” 作为密码时,拼接后的 SQL 语句变为:
String sql = "select * from t_user where username = 'aaa'or'1=1' and password = 'sfsdfsds";
由于 “or '1=1'” 恒为真,无论密码是否正确,该查询都能返回结果,从而导致攻击者绕过了密码验证。
按照 AND
优先级高于 OR
的规则,它会先计算 '1=1' and password = '123456'
这部分,然后再与前面的 username = 'aaa'
通过 OR
进行运算。
如果 '1=1'
恒为 true
,当 password = '123456'
结果为 false
时,'1=1' and password = '123456'
结果为 false
,但由于前面有 OR
连接 username = 'aaa'
,只要 username = 'aaa'
为 true
,整个表达式的结果就为 true
,这就可能导致不符合预期的查询结果,也是 SQL 注入利用的一个原理基础。
另一种常见的恶意输入是 “aaa'‐‐ '”,拼接后的 SQL 语句变为:
String sql = "select * from t_user where username = 'aaa'‐‐ '' and password = 'sfsdfsdfs";
“‐‐” 在 SQL 中是注释符,这使得后面的密码验证部分被注释掉,查询只验证用户名,同样也实现了非法登录。
四、SQL 注入漏洞的解决方案
为了解决 SQL 注入漏洞,我们可以使用PreparedStatement
接口,它是Statement
的子接口,具有以下优势:
- 预编译功能:
PreparedStatement
能够将 SQL 语句中的参数部分使用 “?”(占位符)来代替,并先将编写的 SQL 语句发送到 MySQL 服务器端进行编译。编译后的 SQL 语句格式固定,后续传入的任何值都会作为 “?” 的参数处理,从而避免了恶意输入改变 SQL 语句逻辑的情况。 - 具体使用方法:
- 获取预编译对象:通过
Connection
接口的prepareStatement(String sql)
方法来预编译 SQL 语句。例如:
- 获取预编译对象:通过
Connection conn = JdbcUtils.getConnection();
String sql = "select * from y_user where username =? and password =?";
PreparedStatement stmt = conn.prepareStatement(sql);
- 设置参数值:使用
setXxxx()
系列方法(如setString()
、setInt()
等)向 “?” 传入值,参数的位置从 1 开始计数。例如:
stmt.setString(1,username);
stmt.setString(2,password);
- 执行 SQL 语句:根据 SQL 语句的类型,使用
executeQuery()
方法执行查询操作(返回结果集),使用executeUpdate()
方法执行增删改操作。例如:
ResultSet rs = stmt.executeQuery();
五、示例代码分析
以下是一个完整的 Java 代码示例,展示了如何模拟 SQL 注入漏洞以及如何使用PreparedStatement
解决该问题:
package cn.qcby.demo1;import cn.qcby.utils.JdbcUtils;import java.sql.*;/*** 演示SQL注入的问题,漏洞* 在已知用户名的情况下,通过sql语言关键字,登录系统。密码随意输入的。* SQL注入产生原因是SQL语句的拼接,利用SQL关键字产生效果。* 需要解决SQL注入的问题** 解决SQL注入问题,采用SQL语句预编译的方式,把SQL语句中的参数使用?占位符来表示,先把SQL语句编译,格式固定的。* 再给?传入值,传入任何内容都表示值。数据库会判断SQL执行的结果。*/
public class JdbcTest4 {public static void main(String[] args) {// 模拟登录的功能,有SQL注入的问题//String result = new JdbcTest4().login("aaa'or'1=1", "1234sdf");//System.out.println(result);String result = new JdbcTest4().login2("aaa'or'1=1", "123456");System.out.println(result);}/*** 采用预编译的方式,解决SQL注入的问题* @param username* @param password* @return*/public String login2(String username,String password){Connection conn = null;// 预编译执行SQL语句对象PreparedStatement stmt = null;ResultSet rs = null;try {// 获取到连接conn = JdbcUtils.getConnection();// 使用?占位符String sql = "select * from y_user where username =? and password =?";// 预编译SQL语句,把SQL语句固定//Statement statement = conn.createStatement();//statement不能防止sql注入问题 prepareStatement 能够防止sql注入问题stmt = conn.prepareStatement(sql);// 需要给?设置值stmt.setString(1,username);stmt.setString(2,password);// 执行SQL语句rs = stmt.executeQuery();// 遍历数据if(rs.next()){// 表示存在数据,如果存在,说明用户名和密码编写正确return "登录成功...";}else{return "登录失败了...";}} catch (SQLException e) {e.printStackTrace();}finally {JdbcUtils.close(conn,stmt,rs);}return null;}/*** 模拟登录的功能,通过用户名和密码从数据库中查询* @param username* @param password* @return*/public String login(String username,String password){Connection conn = null;Statement stmt = null;ResultSet rs = null;try {// 获取到连接conn = JdbcUtils.getConnection();// 编写SQL语句的拼接 '1=1' true password = '1234sdfsce' false true and false 整体上false// String sql = "select * from t_user where username = 'aaa' or '1=1' and password = '1234sdfsce'";// String sql = "select * from t_user where username = 'aaa' or false";String sql = "select * from y_user where username = '"+username+"' and password = '"+password+"'";// 执行sqlstmt = conn.createStatement();// 执行rs = stmt.executeQuery(sql);// 遍历数据if(rs.next()){// 表示存在数据,如果存在,说明用户名和密码编写正确return "登录成功...";}else{return "登录失败了...";}} catch (SQLException e) {e.printStackTrace();}finally {JdbcUtils.close(conn,stmt,rs);}return null;}}
相关文章:
深入理解 SQL 注入漏洞及解决方案
一、引言 在当今数字化时代,数据库作为存储和管理数据的核心组件,其安全性至关重要。SQL 注入是一种常见且极具威胁性的数据库安全漏洞,它可能导致数据泄露、篡改甚至系统被完全控制。本文将深入探讨 SQL 注入漏洞的产生原因、表现形式以及如…...
使用 deepseek实现 go语言,读取文本文件的功能,要求支持 ascii,utf-8 等多种格式自适应
使用 deepseek实现 go语言,读取文本文件的功能,要求支持 ascii,utf-8 等多种格式自适应我要用 chatgpt,也问过,但是比 deepseek 还是差一个级别,具体如下: package mainimport ("bufio&qu…...
7.【线性代数】——求解Ax=0,主列和自由列
七 求解Ax0,主列和自由列 1. 消元、秩、特解特解零空间 2. 简化行阶梯形式 :主元上下都是0,主元简化为1 1. 消元、秩、特解 矩阵消元 [ 1 2 2 2 2 4 6 8 3 6 8 10 ] ⏟ A ⇒ r o w 2 − 2 r o w 1 , r o w 3 − 3 r o w 1 [ 1 2 2 2 0 0 2 4 0 0 2 4 ]…...
vue3结合后端传递过来的文件进行预览功能
业务的需要,前端需要根据后端传递过来的文件流进行预览的功能,前端点击链接直接触发浏览器的窗口的预览功能。 实现方式一: 使用弹窗和iframe的标签的形式进行预览文件,但是iframe可能会出现网站安全性的问题,限制比较…...
【Python爬虫(39)】掌控全局:分布式爬虫的任务管理与监控之道
【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取ÿ…...

Jenkins整合Jmeter实现接口自动化测试
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、安装jmeter 下载:http://jmeter.apache.org/download_jmeter.cgi 这里我用了一台Windows安装jmeter用来写接口测试的脚本,启动前修改j…...
Web 自动化测试提速利器:Aqua 的 Web Inspector (检查器)使用详解
Web 自动化测试提速利器:Aqua 的 Web Inspector (检查器)使用详解 前言简介一、安装二、Web Inspector 的使用2.1 获取元素定位器(Locators)2.2 将定位器添加到代码2.3 验证定位器2.4 处理 Frames (框架)总结前言 JetBrains 的 Aqua IDE 提供强大的 Web Inspector 工具,帮…...
大语言模型:从开发到运行的深度解构
一、LLM开发训练的全流程解析 1. 数据工程的炼金术 数据采集:构建涵盖网页文本(Common Crawl)、书籍、论文、代码等领域的超大规模语料库,典型规模可达数十TB。例如GPT-4的训练数据包含超过13万亿token数据清洗:通过…...
【GoLang】【算法模板】2、GoLang 算法模板整理
文章目录 0、前言1、GoLang 算法必会技巧1.1、标准库1.1.1、sort 包1.1.2、slice 包 1.2、数据结构1.2.1、优先队列 2、板子2.1、二分2.1.1、lower_bound、upper_bound 2.2、字符串2.2.1、kmp 0、前言 整理一下 golang 的算法板子,作为备忘录使用。可能有些板子、博…...

合理建模--最短路径
这道题目难就难在如何想到用最短路径来做 主要是这个题目不能用bfs来写,因为距离并不是1 狄克斯特拉算法很久没写了,有些地方生疏了 且这个题目需要记录三个信息,得用tuple 题目地址 int dx[] {0,0,1,-1};int dy[] {1,-1,0,0}; class Solut…...

喜报!博睿数据案例获经观传媒“2024年度数字转型创新案例”!
本文已在“经观”APP中发表,点击下方文章链接查看原文: 2024科技创变纪:创新破局 变量启新 近日,经济观察报“2024年度卓越创新实践案例”榜单评选结果正式公布。博睿数据选送的案例“从零到一:可观测体系建设的探索…...

基于图扑 HT 可视化技术打造智慧地下采矿可视化方案
在前端开发领域,不断涌现的新技术为各行业带来了创新变革的可能。今天,让我们聚焦于图扑软件自研的 HT for Web 产品,看看它如何在前端 2D、3D 渲染方面发力,为智慧地下采矿可视化打造令人惊叹的解决方案,为开发者开启…...
深度学习(2)-深度学习关键网络架构
关键网络架构 深度学习有4种类型的网络架构:密集连接网络、卷积神经网络、循环神经网络和Transformer。每种类型的模型都是针对特定的输入模式,网络架构包含了关于数据结构的假设,即模型搜索的假设空间。某种架构能否解决某个问题࿰…...

【学习笔记】Cadence电子设计全流程(二)原理图库的创建与设计(8-15)
【学习笔记】Cadence电子设计全流程(二)原理图库的创建与设计(下) 2.8 Cadence 软件自带元件库2.9 原理图元器件关联PCB2.10 原理图元器件库的移植2.11 已有原理图输出元器件库2.12 原理图设计中调用元器件库2.13 原理图元器件库关…...

【Linux网络编程】IP协议格式,解包步骤
目录 解析步骤 1.版本字段(大小:4比特位) 2.首部长度(大小:4比特位)(单位:4字节) 🍜细节解释: 3.服务类型(大小:8比特…...

给老系统做个安全检查——Burp SqlMap扫描注入漏洞
背景 在AI技术突飞猛进的今天,类似Cursor之类的工具已经能写出堪比大部分程序员水平的代码了。然而,在我们的代码世界里,仍然有不少"老骥伏枥"的系统在兢兢业业地发光发热。这些祖传系统的代码可能早已过时,架构可能岌…...

Windows 快速搭建C++开发环境,安装C++、CMake、QT、Visual Studio、Setup Factory
安装C 简介 Windows 版的 GCC 有三个选择: CygwinMinGWmingw-w64 Cygwin、MinGW 和 mingw-w64 都是在 Windows 操作系统上运行的工具集,用于在 Windows 环境下进行开发和编译。 Cygwin 是一个在 Windows 上运行的开源项目,旨在提供类Uni…...

开源免费文档翻译工具 可支持pdf、word、excel、ppt
项目介绍 今天给大家推荐一个开源的、超实用的免费文档翻译工具(DeeplxFile),相信很多人都有需要翻译文档的时刻,这款工具就能轻松解决你的需求。 它支持多种文档格式翻译,包括 Word、PDF、PPT、Excel ,使…...

从CNN到Transformer:遥感影像目标检测的未来趋势
文章目录 前言专题一、深度卷积网络知识专题二、PyTorch应用与实践(遥感图像场景分类)专题三、卷积神经网络实践与遥感影像目标检测专题四、卷积神经网络的遥感影像目标检测任务案例【FasterRCNN】专题五、Transformer与遥感影像目标检测专题六、Transfo…...
【GORM学习笔记】GORM介绍以及增删改查相关操作
优缺点 优点:提高开发效率,防止SQL注入、对不熟悉SQL语句的人友好、代码统一缺点:牺牲执行能力、牺牲灵活性、弱化SQL能力 在一些小型项目上使用ORM可以大大提高开发效率,但是在一些对性能要求高得场景下,ORM可能没有…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...