用java PreparedStatement就不用担心sql注入了吗?

2023-10-31

    http://www.cnblogs.com/iyangyuan/archive/2015/09/15/4809494.html

用java PreparedStatement就不用担心sql注入了吗?

言归正传,对java有了解的同学基本上都体验过JDBC,基本都了解PreparedStatement,PreparedStatement相比Statement基本解决了SQL注入问题,而且效率也有一定提升。

     关于PreparedStatement和Statement其他细节我们不讨论,只关心注入问题。无论读者是老鸟还是菜鸟,都需要问一下自己,PreparedStatement真的百分百防注入吗?

     接下来我们研究一下PreparedStatement如何防止注入,本文以MySQL数据库为例。

     为了避免篇幅过长,我这里只贴代码片段,希望读者能有一定的基础。

1 String sql = "select * from goods where min_name = ?";  // 含有参数
2 PreparedStatement st = conn.prepareStatement(sql);
3 st.setString(1, "儿童"); // 参数赋值
4 System.out.println(st.toString()); //com.mysql.jdbc.JDBC4PreparedStatement@d704f0: select * from goods where min_name = '儿童'

     这段代码属于JDBC常识了,就是简单的根据参数查询,看不出什么端倪,但假如有人使坏,想注入一下呢?

1 String sql = "select * from goods where min_name = ?";  // 含有参数
2 PreparedStatement st = conn.prepareStatement(sql);
3 st.setString(1, "儿童'"); // 参数赋值
4 System.out.println(st.toString()); //com.mysql.jdbc.JDBC4PreparedStatement@d704f0: select * from goods where min_name = '儿童\''

     简单的在参数后边加一个单引号,就可以快速判断是否可以进行SQL注入,这个百试百灵,如果有漏洞的话,一般会报错。

     之所以PreparedStatement能防止注入,是因为它把单引号转义了,变成了\',这样一来,就无法截断SQL语句,进而无法拼接SQL语句,基本上没有办法注入了。

     所以,如果不用PreparedStatement,又想防止注入,最简单粗暴的办法就是过滤单引号,过滤之后,单纯从SQL的角度,无法进行任何注入。

     其实,刚刚我们提到的是String参数类型的注入,大多数注入,还是发生在数值类型上,幸运的是PreparedStatement为我们提供了st.setInt(1, 999);这种数值参数赋值API,基本就避免了注入,因为如果用户输入的不是数值类型,类型转换的时候就报错了。

     好,现在读者已经了解PreparedStatement会对参数做转义,接下来再看个例子。

1 String sql = "select * from goods where min_name = ?";  // 含有参数
2 PreparedStatement st = conn.prepareStatement(sql);
3 st.setString(1, "儿童%"); // 参数赋值
4 System.out.println(st.toString()); //com.mysql.jdbc.JDBC4PreparedStatement@8543aa: select * from goods where min_name = '儿童%'

     我们尝试输入了一个百分号,发现PreparedStatement竟然没有转义,百分号恰好是like查询的通配符。

     正常情况下,like查询是这么写的:

1 String sql = "select * from goods where min_name like ?";  // 含有参数
2 st = conn.prepareStatement(sql);
3 st.setString(1, "儿童" + "%"); // 参数赋值
4 System.out.println(st.toString()); //com.mysql.jdbc.JDBC4PreparedStatement@8543aa: select * from goods where min_name like '儿童%'

     查询min_name字段以"儿童"开头的所有记录,其中"儿童"二字是用户输入的查询条件,百分号是我们自己加的,怎么可能让用户输入百分号嘛!等等!如果用户非常聪明,偏要输入百分号呢?

String sql = "select * from goods where min_name like ?";  // 含有参数
st = conn.prepareStatement(sql);
st.setString(1, "%儿童%" + "%"); // 参数赋值
System.out.println(st.toString()); //com.mysql.jdbc.JDBC4PreparedStatement@8543aa: select * from goods where min_name like '%儿童%%'

     聪明的用户直接输入了"%儿童%",整个查询的意思就变了,变成包含查询。实际上不用这么麻烦,用户什么都不输入,或者只输入一个%,都可以改变原意。

     虽然此种SQL注入危害不大,但这种查询会耗尽系统资源,从而演化成拒绝服务攻击。

     那如何防范呢?笔者能想到的方案如下:

        

          ·直接拼接SQL语句,然后自己实现所有的转义操作。这种方法比较麻烦,而且很可能没有PreparedStatement做的好,造成其他更大的漏洞,不推荐。

          ·直接简单暴力的过滤掉%。笔者觉得这方案不错,如果没有严格的限制,随便用户怎么输入,既然有限制了,就干脆严格一些,干脆不让用户搜索%,推荐。

        

     目前做搜索,只要不是太差的公司,一般都有自己的搜索引擎(例如著名的java开源搜索引擎solr),很少有在数据库中直接like的,笔者并不是想在like上钻牛角尖,而是提醒读者善于思考,每天都在写着重复的代码,却从来没有停下脚步细细品味。

     有读者可能会问,为什么我们不能手动转义一下用户输入的%,其他的再交给PreparedStatement转义?这个留作思考题,动手试一下就知道为什么了。

     注意,JDBC只是java定义的规范,可以理解成接口,每种数据库必须有自己的实现,实现之后一般叫做数据库驱动,本文所涉及的PreparedStatement,是由MySQL实现的,并不是JDK实现的默认行为,也就是说,不同的数据库表现不同,不能一概而论。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用java PreparedStatement就不用担心sql注入了吗? 的相关文章

随机推荐

  • html文件上传美化

    html上传按钮美化 效果图 描述 通过定位覆盖原来的按钮 代码 div class layui form item div
  • 排序算法-----计数排序

    目录 前言 计数排序 1 算法描述 2 基本思想 3 实现逻辑 4 示例剖析 5 动图演示 代码实现 1 C C 代码 2 Python代码 算法分析 时间复杂度 空间复杂度 稳定性 局限性 前言 有没有一种排序时间复杂度为直线正比的排序算
  • hyper-v虚拟机的创建时间总是是1601的问题。

    解决办法 1 在虚拟机正在运行时 点击停止服务 虚拟机不会关闭 2 同意强制关闭后 在重新启动服务即可 3 虚拟机的创建时间将正确显示
  • 2015中国各地区最佳大学排行榜 报考首选前五强

    艾瑞深中国校友会网最新发布2015中国各地区最佳大学排行榜 2015中国各地区最佳独立学院排行榜和2015中国各地区最佳民办大学排行榜等榜单 旨在让两岸四地高考考生及家长了解中国各地区高校的办学水平和办学实力 2015中国各地区最佳大学排行
  • 数据库常见知识点

    数据库 Mysql的金额用什么数据类型表示 在mysql中 金额用 DECIMAL 类型 DECIMAL类型是专门为财务相关问题而设计的数据类型 能够解决数据的范围和精度的问题 常用于货币数据 如价格 工资 帐户余额等 它实际上是以字符串的
  • 经典分类算法——感知机算法

    文章目录 经典分类算法 感知机算法 1 感知机算法思想 错误修正 2 感知机算法 原始形式 形式化表示 3 感知机算法 对偶形式 形式化表示 4 感知机算法 随机梯度下降 SGD 5 感知机算法 一种变形 6 感知器算法 示例 7 感知器算
  • 代码审计及工具

    代码审计 是对应用程序源代码进行系统性检查的工作 它的目的是为了找到并且修复应用程序在开发阶段存在的一些漏洞或者程序逻辑错误 避免程序漏洞被非法利用给企业带来不必要的风险 代码审计不是简单的检查代码 审计代码的原因是确保代码能安全的做到对信
  • python之多线程并发

    前言 今天呢笔者想和大家来聊聊python多线程的并发 废话就不多说了咱们直接进入主题哟 一 线程执行 python的内置模块提供了两个内置模块 thread和threading thread是源生模块 threading是扩展模块 在th
  • boost::python::converter::as_to_python_function相关的测试程序

    boost python converter as to python function相关的测试程序 boost python是一个用于将C 代码集成到Python中的强大工具库 其中的converter模块提供了将C 对象转换为Pyth
  • java-IDEA常用插件

    1 JRebel 热部署插件 1 IDEA 中搜索并安装插件 JRebel 重启 2 获取UUID https www guidgen com 3 按下图填写信息 https jrebel qekang com UUID 把UUID替换成上
  • 基于深度学习的商品推荐系统(Web)

    基于深度学习的商品推荐系统 ECRS Web 项目简介 技术栈 项目用到的技术如下 语言 Python3 Java Web端 Layui Flask Nginx Gevent Flask Cache 模型训练 PaddleRec Paddl
  • js反爬中如何如何处理无限debugger

    有时候在爬取网站时 遇到无限debugger的情况 一种是constructor中的debugger 还有一种是eval中的debugger 可以通过hook的方式绕过无限debugger 处理eval中无限debugger var eva
  • 26. selenium:浏览器自动测试模块——一款方便且能装X的爬虫工具(附多个实例)

    目录 前言 什么是selenium 配置selenium 安装selenium库 安装浏览器驱动 以Chrome为例 使用selenium库 例1 实现打开网页拿取网页标题 运行效果 例2 实现抓取某招聘网站Python岗位的职位信息 运行
  • setImageResource和setImageDrawable区别

    ImageView设置图片的方式有很多钟 可以在xml里面写android src drawable xxx 也可以在java代码里面设置 在java里面的设置方式也有多种 方法包括 setImageResource setImageDra
  • Xilinx ISE系列教程(3):关联第三方编辑器Notepad++/VS Code/UltraEdit/Sublime Text/Emacs/Vim

    文章目录 toc 1 ISE关联Notepad 编辑器 2 ISE关联VS Code编辑器 3 ISE关联UltraEdit编辑器 4 ISE关联Sublime Text3编辑器 5 ISE关联Emacs编辑器 6 ISE关联Vim编辑器
  • VMware中Centos Linux 8虚拟机安装过程

    VMware Workstation的安装过程已经有博文分享 本文是VMware安装成功后虚拟机安装的过程 在安装前需要下载CentOS镜像文件 阿里云地址为 https mirrors aliyun com centos 我下载的是8 即
  • 下载百度网盘资源不限速的两种方法

    下载百度网盘资源不限速的两种方法 方法1 适合文件大小4g以下的下载 由于直接用proxpee down下载资源文件时出现 error code 31090 error msg package is too large request id
  • 神仙文献管理软件Mendeley 保姆级教程

    神仙文献管理软件Mendeley 保姆级教程 英国文文的文章 知乎 https zhuanlan zhihu com p 65992720 Mendeley是一款Elsevier公司旗下的免费文献管理软件 集文献的搜集 管理 搜索 阅读 标
  • 云计算与大数据-虚拟化与容器技术题库

    第2章 虚拟化与容器技术习题 2 1 选择题 1 典型的虚拟化架构不包括 D A 宿主机操作系统 B 虚拟机 C 虚拟化层 D 虚拟内存 2 虚拟化技术的研究目的包括 D A 降低管理成本 B 增强可移植性 C 提高软件开发效率 D 以上都
  • 用java PreparedStatement就不用担心sql注入了吗?

    http www cnblogs com iyangyuan archive 2015 09 15 4809494 html 用java PreparedStatement就不用担心sql注入了吗 言归正传 对java有了解的同学基本上都体