JDBC第二天:防sql攻击
1 什么是SQL攻击
在需要用户输入的地方,用户输入的是SQL语句的片段,最终用户输入的SQL片段与我们DAO中写的SQL语句合成一个完整的SQL语句!例如用户在登录时输入的用户名和密码都是为SQL语句的片段!
2 演示SQL攻击
首先我们需要创建一张用户表,用来存储用户的信息。
|
CREATE TABLE user( uid CHAR(32) PRIMARY KEY, username VARCHAR(30) UNIQUE KEY NOT NULL, PASSWORD VARCHAR(30) ); INSERT INTO user VALUES('U_1001', 'zs', 'zs'); SELECT * FROM user; |
现在用户表中只有一行记录,就是zs。
下面我们写一个login()方法!
|
public void login(String username, String password) { Connection con = null; Statement stmt = null; ResultSet rs = null; try { con = JdbcUtils.getConnection(); stmt = con.createStatement(); String sql = "SELECT * FROM user WHERE " + "username='" + username + "' and password='" + password + "'"; rs = stmt.executeQuery(sql); if(rs.next()) { System.out.println("欢迎" + rs.getString("username")); } else { System.out.println("用户名或密码错误!"); } } catch (Exception e) { throw new RuntimeException(e); } finally { JdbcUtils.close(con, stmt, rs); } } |
下面是调用这个方法的代码:
|
login("a' or 'a'='a", "a' or 'a'='a"); |
这行当前会使我们登录成功!因为是输入的用户名和密码是SQL语句片段,最终与我们的login()方法中的SQL语句组合在一起!我们来看看组合在一起的SQL语句:
|
SELECT * FROM tab_user WHERE username='a' or 'a'='a' and password='a' or 'a'='a' |
3 防止SQL攻击
- 过滤用户输入的数据中是否包含非法字符;
- 分步交验!先使用用户名来查询用户,如果查找到了,再比较密码;
- 使用PreparedStatement。
4 PreparedStatement是什么?
PreparedStatement叫预编译声明!
PreparedStatement是Statement的子接口,你可以使用PreparedStatement来替换Statement。
PreparedStatement的好处:
- 防止SQL攻击;
- 提高代码的可读性,以可维护性;
- 提高效率。
5 PreparedStatement的使用
- 使用Connection的prepareStatement(String sql):即创建它时就让它与一条SQL模板绑定;
- 调用PreparedStatement的setXXX()系列方法为问号设置值
- 调用executeUpdate()或executeQuery()方法,但要注意,调用没有参数的方法;
|
String sql = “select * from tab_student where s_number=?”; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setString(1, “S_1001”); ResultSet rs = pstmt.executeQuery(); rs.close(); pstmt.clearParameters(); pstmt.setString(1, “S_1002”); rs = pstmt.executeQuery(); |
在使用Connection创建PreparedStatement对象时需要给出一个SQL模板,所谓SQL模板就是有“?”的SQL语句,其中“?”就是参数。
在得到PreparedStatement对象后,调用它的setXXX()方法为“?”赋值,这样就可以得到把模板变成一条完整的SQL语句,然后再调用PreparedStatement对象的executeQuery()方法获取ResultSet对象。
注意PreparedStatement对象独有的executeQuery()方法是没有参数的,而Statement的executeQuery()是需要参数(SQL语句)的。因为在创建PreparedStatement对象时已经让它与一条SQL模板绑定在一起了,所以在调用它的executeQuery()和executeUpdate()方法时就不再需要参数了。
PreparedStatement最大的好处就是在于重复使用同一模板,给予其不同的参数来重复的使用它。这才是真正提高效率的原因。
所以,建议大家在今后的开发中,无论什么情况,都去需要PreparedStatement,而不是使用Statement。
package cn.itcast.demo3;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.Test;
/**
* PreapredStatement
* 防SQL攻击
* @author cxf
*
*/
public class Demo3 {
/**
* 登录
* 使用username和password去查询数据
* 若查出结果集,说明正确!返回true
* 若查出不出结果,说明用户名或密码错误,返回false
* @param username
* @param password
* @return
* @throws Exception
*/
public boolean login(String username, String password) throws Exception {
/*
* 一、得到Connection
* 二、得到Statement
* 三、得到ResultSet
* 四、rs.next()返回的是什么,我们就返回什么
*/
// 准备四大参数
String driverClassName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/mydb3";
String mysqlUsername = "root";
String mysqlPassword = "123";
// 加载驱动类
Class.forName(driverClassName);
// 得到Connection
Connection con = DriverManager.getConnection(url, mysqlUsername, mysqlPassword);
// 得到Statement
Statement stmt = con.createStatement();
// 给出sql语句,调用stmt的executeQuery(),得到ResultSet
String sql = "select * from t_user where username='" + username + "' and password='" + password + "'";
System.out.println(sql);
ResultSet rs = stmt.executeQuery(sql);
return rs.next();
}
/**
* SQL攻击!
* @throws Exception
*/
@Test
public void fun1() throws Exception {
//select * from t_user where username='a' or 'a'='a' and password='a' or 'a'='a'
String username = "a' or 'a'='a";
String password = "a' or 'a'='a";
boolean bool = login(username, password);
System.out.println(bool);
}
public boolean login2(String username, String password) throws Exception {
/*
* 一、得到Connection
* 二、得到Statement
* 三、得到ResultSet
* 四、rs.next()返回的是什么,我们就返回什么
*/
// 准备四大参数
String driverClassName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/mydb3?useServerPrepStmts=true&cachePrepStmts=true";
String mysqlUsername = "root";
String mysqlPassword = "123";
// 加载驱动类
Class.forName(driverClassName);
// 得到Connection
Connection con = DriverManager.getConnection(url, mysqlUsername, mysqlPassword);
///
///
/*
* 一、得到PreparedStatement
* 1. 给出sql模板:所有的参数使用?来替代
* 2. 调用Connection方法,得到PreparedStatement
*/
String sql = "select * from t_user where username=? and password=?";
PreparedStatement pstmt = con.prepareStatement(sql);
/*
* 二、为参数赋值
*/
pstmt.setString(1, username);//给第1个问号赋值,值为username
pstmt.setString(2, password);//给第2个问号赋值,值为password
ResultSet rs = pstmt.executeQuery();//调用查询方法,向数据库发送查询语句
pstmt.setString(1, "liSi");
pstmt.setString(2, "123");
pstmt.executeQuery();
return rs.next();
}
@Test
public void fun2() throws Exception {
//select * from t_user where username='a' or 'a'='a' and password='a' or 'a'='a'
String username = "zhangSan";
String password = "123";
boolean bool = login2(username, password);
System.out.println(bool);
}
/**
* 测试JdbcUtils.getConnection()
* @throws SQLException
* @throws ClassNotFoundException
* @throws IOException
*/
@Test
public void fun3() throws SQLException {
Connection con = JdbcUtils.getConnection();
System.out.println(con);
Connection con1 = JdbcUtils.getConnection();
System.out.println(con1);
}
}
JDBC第二天:防sql攻击的更多相关文章
- 回头探索JDBC及PreparedStatement防SQL注入原理
概述 JDBC在我们学习J2EE的时候已经接触到了,但是仅是照搬步骤书写,其中的PreparedStatement防sql注入原理也是一知半解,然后就想回头查资料及敲测试代码探索一下.再有就是我们在项 ...
- JDBC及PreparedStatement防SQL注入
概述 JDBC在我们学习J2EE的时候已经接触到了,但是仅是照搬步骤书写,其中的PreparedStatement防sql注入原理也是一知半解,然后就想回头查资料及敲测试代码探索一下.再有就是我们在项 ...
- PHP自带防SQL攻击函数区别
为了防止SQL注入攻击,PHP自带一个功能可以对输入的字符串进行处理,可以在较底层对输入进行安全上的初步处理,也即Magic Quotes.(php.ini magic_quotes_gpc).如果m ...
- SQL攻击-预编译--缓存
PreparedStatement l 它是Statement接口的子接口: l 强大之处: 防SQL攻击: 提高代码的可读性.可维护性: 提高效率! l 学习PreparedStatement的用法 ...
- nginx服务器防sql注入/溢出攻击/spam及禁User-agents
本文章给大家介绍一个nginx服务器防sql注入/溢出攻击/spam及禁User-agents实例代码,有需要了解的朋友可进入参考. 在配置文件添加如下字段即可 代码如下 复制代码 server { ...
- PHP防SQL注入攻击
PHP防SQL注入攻击 收藏 没有太多的过滤,主要是针对php和mysql的组合. 一般性的防注入,只要使用php的 addslashes 函数就可以了. 以下是一段copy来的代码: PHP代码 $ ...
- web攻击之八:溢出攻击(nginx服务器防sql注入/溢出攻击/spam及禁User-agents)
一.什么是溢出攻击 首先, 溢出,通俗的讲就是意外数据的重新写入,就像装满了水的水桶,继续装水就会溢出,而溢出攻击就是,攻击者可以控制溢出的代码,如果程序的对象是内核级别的,如dll.sys文件等,就 ...
- 「PHP开发APP接口实战009」日常安全防范之防SQL入和XSS攻击
防SQL注入和XSS攻击通用过滤 首先在 /app/library/ 目录下创建 Security.php 文件并添加以下代码: <?php /** * * 防SQL注入和XSS攻击通用过滤 * ...
- tp5怎么防sql注入 xss跨站脚本攻击
在 application/config.php 中有个配置选项 框架默认没有设置任何过滤规则,你可以是配置文件中设置全局的过滤规则 则会调用这些函数 自动过滤 // 默认全局过滤方法 用逗号分隔多个 ...
- 【荐】PDO防 SQL注入攻击 原理分析 以及 使用PDO的注意事项
我们都知道,只要合理正确使用PDO,可以基本上防止SQL注入的产生,本文主要回答以下几个问题: 为什么要使用PDO而不是mysql_connect? 为何PDO能防注入? 使用PDO防注入的时候应该特 ...
随机推荐
- kubernetes 二次开发-认证,鉴权(1)
基于webhook的认证 授权过程 认证授权服务需要满足如下kubernetes的规范 kubernetes api-server组件发送 http post 请求 url:https://authn ...
- LLM 大模型学习必知必会系列(八):10分钟微调专属于自己的大模型
LLM 大模型学习必知必会系列(八):10分钟微调专属于自己的大模型 1.环境安装 # 设置pip全局镜像 (加速下载) pip config set global.index-url https:/ ...
- jquery的节点的替换 节点的克隆
// 节点的替换 / 标签的替换 // 1 , $('已有标签').replaceWith(替换的新的标签) // 替换所有 // 将已有的span ...
- 剑指Offer-64.滑动窗口的最大值(C++/Java)
题目: 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6, ...
- 关于 Elasticsearch 不同分片设置的压测报告
摘要 为了验证当前集群经常出现索引超时以及请求拒绝的问题,现模拟线上集群环境及索引设置,通过压测工具随机生成测试数据,针对当前的 850 个分片的索引,以及减半之后的索引,以及更小分片索引的写入进行压 ...
- C# ML.NET 使用GPU遇到 Failed to get convolution algorithm.This is probably because cuDNN failed to initialize
C# ML.NET 使用GPU遇到 Failed to get convolution algorithm.This is probably because cuDNN failed to initi ...
- 夜莺官方文档优化第一弹:手把手教你部署和架构讲解,消灭所有部署失败的 case!干!
前置说明 各种环境的选型建议 Docker compose 方式:仅仅用于简单测试,不推荐在生产环境使用 Docker compose,升级起来挺麻烦的,除非你对 Docker compose 真的很 ...
- #PowerBi 1分钟学会,用PowerBi获取数据库最近90天的数据(DATE_SUB)
在powerbi报表中,我们往往会对数据源进行日常刷新,powerbi链接了数据库的情况下,根据日期灵活取数是我们必须掌握的一个技能. 在本文中,我们将介绍如何使用 SQL 的 DATE_SUB 函数 ...
- spark使用jdbc批次提交方式写入phoniex的工具类
一.需求:spark写入phoniex 二.实现方式 1.官网方式 dataFrame.write .format("org.apache.phoenix.spark") .mod ...
- R 语言入门学习笔记:软件安装踩坑记录——删除所有包以及彻底解决库包被安装到 C 盘用户目录下的问题,以及一些其他需要注意的点
目录 R 语言入门学习笔记:软件安装踩坑记录--删除所有包以及彻底解决库包被安装到 C 盘用户目录下的问题,以及一些其他需要注意的点 软件版本及环境 遇到的问题描述 问题的分析和探究 最终的解决方案 ...