SQL注入及如何解决
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
1、SQL注入案例
模拟一个用户登录的SQL注入案例,用户在控制台上输入用户名和密码, 然后使用 Statement 字符串拼接的方式实现用户的登录。
1.1 数据库中先创建用户表及数据
-- 创建一张用户表
CREATE TABLE `users` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(20),
`password` VARCHAR(50),
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8; -- 插入数据
INSERT INTO users(username,`password`) VALUES('张飞','123321'),('赵云','qazxsw'),('诸葛亮','123Qwe');
INSERT INTO users(username,`password`) VALUES('曹操','741258'),('刘备','plmokn'),('孙权','!@#$%^'); -- 查看数据
SELECT * FROM users;

1.2 编写一个登录程序
package com.study.task0201; import java.sql.*;
import java.util.Scanner; public class TestSQLIn {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding=UTF-8";
Connection conn = DriverManager.getConnection(url,"root","123456");
//System.out.println(conn);
// 获取语句执行平台对象 Statement
Statement smt = conn.createStatement(); Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String userName = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine(); String sql = "select * from users where username = '" + userName + "' and password = '" + password +"'";
//打印出SQL
System.out.println(sql);
ResultSet resultSet = smt.executeQuery(sql);
if(resultSet.next()){
System.out.println("登录成功!!!");
}else{
System.out.println("用户名或密码错误,请重新输入!!!");
} resultSet.close();
smt.close();
conn.close(); } }
1.3 正常登录
输入正确的用户名及密码后提示"登录成功"

1.4 登录失败
输入用户名或密码错误时,提示“用户名或密码错误,请重新输入”

1.5 模拟SQL注入
拼接的字符串中有or '1'='1' 为恒成立条件,因此 及时前面的用户及密码不存在也会取出所有记录,因此提示"登录成功"

1.6 SQL语法报错
使用拼接的方式,还会出现SQL语法错误等报错,例如

2. 解决方案
使用Statement方式,用户可以通过字符串拼接,改变原本SQL真正的含义,导致存在SQL注入的风险。解决SQL注入,可以通过预处理对象PreparedStatement来代替Statement进行处理。
1.1 程序
import java.sql.*;
import java.util.Scanner; public class TestSQLIn {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://192.168.250.177:3307/testdb?characterEncoding=UTF-8";
Connection conn = DriverManager.getConnection(url,"root","AisinoClod#2018)0710");
//System.out.println(conn);
// 获取语句执行平台对象 Statement
// Statement smt = conn.createStatement(); Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String userName = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine(); String sql = "select * from users where username = ? and password = ? ";
// System.out.println(sql);
// ResultSet resultSet = smt.executeQuery(sql);
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1,userName);
preparedStatement.setString(2,password); ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next()){
System.out.println("登录成功!!!");
}else{
System.out.println("用户名或密码错误,请重新输入!!!");
} preparedStatement.close();
resultSet.close();
// smt.close();
conn.close(); } }
2.2 正常登录

2.3 用户名密码错误
当用户名或密码输入错误时,会提示“用户名或密码错误,请重新输入”

2.4 模拟SQL注入
按照之前的情况,进行SQL注入的写法,测试后不再出现SQL注入情况。

2.5 模拟SQL语法错误
使用预处理类后,输入带有单引号或双引号的内容也不会再出现SQL语法错误的报错

3. 小结
Statement 与 PreparedStatement的主要区别如下:
- Statement用于执行静态SQL语句,在执行时,必须指定一个事先准备好的SQL语句
- PrepareStatement是预编译的SQL语句对象,语句中可以包含动态参数“?”,在执行时可以为“?”动态设置参数值
- PrepareStatement可以减少编译次数提高数据库性能
SQL注入及如何解决的更多相关文章
- java学习笔记38(sql注入攻击及解决方法)
上一篇我们写了jdbc工具类:JDBCUtils ,在这里我们使用该工具类来连接数据库, 在之前我们使用 Statement接口下的executeQuery(sql)方法来执行搜索语句,但是这个接口并 ...
- 网站如何防止sql注入攻击的解决办法
首先我们来了解下什么是SQL注入,SQL注入简单来讲就是将一些非法参数插入到网站数据库中去,执行一些sql命令,比如查询数据库的账号密码,数据库的版本,数据库服务器的IP等等的一些操作,sql注入是目 ...
- SQL注入原理与解决方法代码示例
一.什么是sql注入? 1.什么是sql注入呢? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网 ...
- php和mysql数据库防SQL注入的有效解决办法
<?php$mysqli = new mysqli("localhost", "my_user", "my_password", &q ...
- Java程序员从笨鸟到菜鸟之(一百零二)sql注入攻击详解(三)sql注入解决办法
sql注入攻击详解(二)sql注入过程详解 sql注入攻击详解(一)sql注入原理详解 我们了解了sql注入原理和sql注入过程,今天我们就来了解一下sql注入的解决办法.怎么来解决和防范sql注入, ...
- jdbc mysql crud dao模型 sql注入漏洞 jdbc 操作大文件
day17总结 今日内容 l JDBC 1.1 上次课内容总结 SQL语句: 1.外键约束:foreign key * 维护多个表关系! * 用来保证数据完整性! 2.三种关系: * 一对多: * 一 ...
- Spring MVC 如何防止XSS、SQL注入攻击
在Web项目中,通常需要处理XSS,SQL注入攻击,解决这个问题有两个思路: 在数据进入数据库之前对非法字符进行转义,在更新和显示的时候将非法字符还原 在显示的时候对非法字符进行转义 如果项目还处在起 ...
- 【攻防实战】SQL注入演练!
这篇文章目的是让初学者利用SQL注入技术来解决他们面临的问题, 成功的使用它们,并在这种攻击中保护自己. 1.0 介绍 当一台机器只打开了80端口, 你最依赖的漏洞扫描器也不能返回任何有用的内容, 并 ...
- Python中防止sql注入的方法详解
SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库.下面这篇文章主要给大家介绍了关于Python中 ...
随机推荐
- JPA使用之@Query的常用写法
准备 实体 @Data @Table(name = "task_apply") @Entity public class TaskApply { @Id @GeneratedVal ...
- 理解go语言的shellcode加载器
序言 本文假设你知道unsafe包常见函数的用法,若否,请查看 https://books.studygolang.com/gopl-zh/ch13/ch13-01.html 第13章. 例子和代码 ...
- Linux三剑客grep、awk、sed
何为Linux三剑客? 第一个剑客是 grep,grep 会根据正则表达式查找相关内容并打印对应的数据. 第二个剑客是 awk,awk 的名字来源于三个作者的名字简称,它可以根据定位到的数据行处理其中 ...
- 分析 5种分布式事务方案,还是选了阿里的 Seata(原理 + 实战)
好长时间没发文了,最近着实是有点忙,当爹的第 43 天,身心疲惫.这又赶上年底,公司冲 KPI 强制技术部加班到十点,晚上孩子隔两三个小时一醒,基本没睡囫囵觉的机会,天天处于迷糊的状态,孩子还时不时起 ...
- 蓝桥杯——Java集合练习题
回文数.维密.约瑟夫环 回文数 问题描述: 123321是一个非常特殊的数,它从左边读和从右边读是一样的.输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n. 输入格式: ...
- 【2020.12.03提高组模拟】A组反思
估计:40+10+0+0=50 实际:40+10+0+0=50 rank40 T1 赛时看到\(n,m\leq9\),我当机立断决定打表,暴力打了几个点之后发现在\(n\ne m\)且\(k\ne0\ ...
- 区块链学习1:Merkle树(默克尔树)和Merkle根
☞ ░ 前往老猿Python博文目录 ░ 一.简介 默克尔树(Merkle tree,MT)又翻译为梅克尔树,是一种哈希二叉树,树的根就是Merkle根. 关于Merkle树老猿推荐大家阅读<M ...
- 网鼎杯2020 AreUSerialz
0x00 前言 ...有一说一,赵总的BUUCTF上的这道题目并没有复现到精髓.其实感觉出题人的题目本身没有那么简单的,只不过非预期实在是太简单惹. 涉及知识点: 1.php中protected变量反 ...
- Leetcode学习笔记(4)
题目1 ID121 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股 ...
- Scrum冲刺_Day06
一.团队展示: 1.项目:light_note备忘录 2.队名:删库跑路队 3.团队成员 队员(不分先后) 项目角色 黄敦鸿 后端工程师.测试 黄华 后端工程师.测试 黄骏鹏 后端工程师.测试 黄源钦 ...