本人微信公众号,欢迎扫码关注!

使用jdbc拼接条件查询语句时如何防止sql注入

  • 最近公司的项目在上线时需要进行安全扫描,但是有几个项目中含有部分老代码,操作数据库时使用的是jdbc,并且竟然好多都是拼接的SQL语句,真是令人抓狂。
  • 在具体改造时,必须使用PreparedStatement来防止SQL注入,普通SQL语句比较容易改造,本重点探讨在拼接查询条件的时候如何方式SQL注入,具体思路请参考下面的示例代码。

1 数据库示例数据

2 使用statement(不防止SQL注入)

2.1 示例代码

@Test
public void statementTest() {
String username = "tom";
String sex = "1";
String address = "' or '1'='1";
Statement stat = null;
ResultSet res = null; Connection conn = ConnectionFactory.getConnection();
String sql = "SELECT * FROM user WHERE 1 = 1"; sql += username == null ? "" : " AND username = '" + username + "'";
sql += sex == null ? "" : " AND sex = '" + sex + "'";
sql += address == null ? "" : " AND address = '" + address + "'"; System.out.println(sql); try {
stat = conn.createStatement();
res = stat.executeQuery(sql);
printRes(res);
} catch (SQLException e) {
e.printStackTrace();
} finally {
ResourceClose.close(res, stat, conn);
}
}

2.2 控制台结果

SELECT * FROM user WHERE 1 = 1 AND username = 'tom' AND sex = '1' AND address = '' or '1'='1'
10 tom 2014-07-10 1 beijing
16 tom 2018-07-31 1 shanghai
22 tom 2019-04-16 2 shanghai
24 tom 2019-06-22 1 guangzhou
25 tom 2019-01-22 2 guangzhou
28 tom 2018-07-31 1 shenzhen

2.3 小结

  • 经过上面的示例代码我们可以发现,单纯拼接SQL语句是非常危险的,特别容易被SQL注入,但是如果使用prepareStatement的话,像这种条件查询我们预先并不能确定到底有多少个?(占位符),也就不能使用按照?(占位符)索引去设置参数了,那怎么办呢?
  • 别担心,此时我们使用一个小小的技巧,具体参考下面的示例代码

3 使用prepareStatement(可以防止SQL注入)

3.1 示例代码

@Test
public void prepareStatementTest() {
String username = "tom";
String sex = null;
String address = "' or '1'='1";
PreparedStatement stat = null;
ResultSet res = null; Connection conn = ConnectionFactory.getConnection();
String sql = "SELECT * FROM user WHERE 1 = 1"; List<Object> param = new ArrayList<>(); if (username != null) {
sql += " AND username = ?";
param.add(username);
}
if (sex != null) {
sql += " AND sex = ?";
param.add(sex);
}
if (address != null) {
sql += " AND address = ?";
param.add(address);
}
System.out.println(sql); try {
stat = conn.prepareStatement(sql);
for (int i = 0; i < param.size(); i++) {
stat.setObject(i+1,param.get(i));
}
res = stat.executeQuery();
printRes(res);
} catch (SQLException e) {
e.printStackTrace();
} finally {
ResourceClose.close(res, stat, conn);
}
}

3.2 控制台结果

SELECT * FROM user WHERE 1 = 1 AND username = ? AND address = ?

3.3 小结

  • 可以看出,使用prepareStatement是可以防止SQL注入的。
  • 但进行类似条件拼接这种操作时,可以先把参数放入一个集合中,然后遍历集合,同时利用setObject(index,obj)这个方法就可以动态的获取参数的索引了,而且不用关心参数是何种类型。

4 问题总结

  • 如今在进行项目开发时已经很少使用原生的jdbc了,大多数都用功能强大的框架去完成,他们帮我们简化了很多操作,如获取数据库连接、封装结果集、SQL预编译(可以防止SQL注入)
  • 如果实在避免不了使用的话一定要使用可以需编译的prepareStatement对象,避免被SQL注入带来的风险。

使用jdbc拼接条件查询语句时如何防止sql注入的更多相关文章

  1. sql查询语句时怎么把几个字段拼接成一个字段

    sql查询语句时怎么把几个字段拼接成一个字段SELECT CAST(COLUMN1 AS VARCHAR(10)) + '-' + CAST(COLUMN2 AS VARCHAR(10) ...) a ...

  2. MySQL数据库详解(一)执行SQL查询语句时,其底层到底经历了什么?

    一条SQL查询语句是如何执行的? 前言 ​ 大家好,我是WZY,今天我们学习下MySQL的基础框架,看一件事千万不要直接陷入细节里,你应该先鸟瞰其全貌,这样能够帮助你从高维度理解问题.同样,对于MyS ...

  3. JAVA jdbc(数据库连接池)学习笔记(二) SQL注入

    PS:今天偶然间发现了SQL的注入...所以就简单的脑补了一下,都是一些简单的例子...这篇写的不怎么样...由于自己没有进行很深的研究... 学习内容: 1.SQL注入的概念...   所谓SQL注 ...

  4. Mybatis 的分页条件查询语句编写

    刚来到一家新公司, 翻看项目代码, 发现一位同事写的查询逻辑很好, 不用插件, 一个语句完成了分页条件查询. 而我之前一般都是在业务层对参数进行判断, 如果有条件,就调用条件查询的方法, 如果没有条件 ...

  5. 当执行一条查询语句时,MySQL内部经历了什么?

    假如说我们有一张表 T ,表里只有一个字段 ID,当我们执行下边这条SQL语句时: mysql> select * fron T where ID=10; 在我们眼中能看到的只是输入一条 SQL ...

  6. 当程序执行一条查询语句时,MySQL内部到底发生了什么? (说一下 MySQL 执行一条查询语句的内部执行过程?

    先来个最基本的总结阐述,希望各位小伙伴认真的读一下,哈哈: 1)客户端(运行程序)先通过连接器连接到MySql服务器. 2)连接器通过数据库权限身份验证后,会先查询数据库缓存是否存在(之前执行过相同条 ...

  7. MySQL多表查询,Navicat使用,pymysql模块,sql注入问题

    一.多表查询 #建表 create table dep( id int, name varchar(20) ); create table emp( id int primary key auto_i ...

  8. 一、JDBC的概述 二、通过JDBC实现对数据的CRUD操作 三、封装JDBC访问数据的工具类 四、通过JDBC实现登陆和注册 五、防止SQL注入

    一.JDBC的概述###<1>概念 JDBC:java database connection ,java数据库连接技术 是java内部提供的一套操作数据库的接口(面向接口编程),实现对数 ...

  9. 通过jdbc使用PreparedStatement,提升性能,防止sql注入

    为什么要使用PreparedStatement? 一.通过PreparedStatement提升性能 Statement主要用于执行静态SQL语句,即内容固定不变的SQL语句.Statement每执行 ...

随机推荐

  1. Docker快速入门(二)

    上篇文章<Docker快速入门(一)>介绍了docker的基本概念和image的相关操作,本篇将进一步介绍image,容器和Dockerfile. 1 image文件 (1)Docker ...

  2. Windows10远程报错:由于CredSSP加密Oracle修正

    Windows10远程桌面连接 报错信息 : 网上找到方法 但是奈何是 "Win10家庭版" 不能使用这个办法,具体操作可以看最后的引用链接 !!!! 策略路径:"计算机 ...

  3. cxf webservice生成客户端代码及调用服务端遇到的问题

    1.  从网上下载cxf开发的工具 apache-cxf-3.1.4.zip, 解压文件,找到apache-cxf-3.1.4\bin目录,里面包含一个wsdl2java文件 2. 设置环境变量 1. ...

  4. GenyMotion 配合 Android Studio 的安装

    众所周知,Android Studio 自带的模拟器对内存和CPU消耗都很大却并没有很好的效果,简直是谷歌为了卖手机设计的.而Geny Motion 对机能的要求大大降低,又不会像自带模拟器那么卡.G ...

  5. scrapy安装过程问题解决、新建项目、调试断点

    一.安装问题 1. 下载速度太慢 使用国外源,下载速度很慢,可以考虑使用豆瓣的镜像下载 pip install -i https://pypi.douban.com/simple/ scrapy 2. ...

  6. django-团队简介的网页

    团队简介的网页,是使用Django完成的 关于Django的教程网址:http://www.runoob.com/django/django-tutorial.html 小组作业成果如下:

  7. Robot Framework自动化_环境搭建以及第一个用例

    Robot Framework自动化_环境搭建以及第一个脚本 培训老师:肖能尤 2016/06/07 课程目的 一.Robot framework 环境搭建以及第一个脚本 课程内容 1    安装前准 ...

  8. dup和dup2应用实例(dup跟APUE有出入,close+dup=dup2?)

    dup/dup2函数 有时我们希望把标准输入重定向到一个文件,或者把标准输出重定向到一个网络连接. dup()与dup2()能对输入文件描述符进行重定向. 函数原型如下: dup函数创建一个新的文件描 ...

  9. Java中的queue和deque对比详解

    队列(queue)简述 队列(queue)是一种常用的数据结构,可以将队列看做是一种特殊的线性表,该结构遵循的先进先出原则.Java中,LinkedList实现了Queue接口,因为LinkedLis ...

  10. 000webhost虚拟主机绑定自定义二级域名

    作者:荒原之梦 原文链接:http://zhaokaifeng.com/?p=558 前言: 最近想给导航狗IT信息导航做一个文件服务器专门存放文件,以提供引用或下载.于是,我在000webhost上 ...