如果在查询字段中输入单引号"'",则会报错,这是因为输入的单引号和其他的sql组合在一起编程了一个新的sql,实际上这就是SQL注入漏洞,后来我在前台和后台都对输入的字符进行了判断。

永远也不要写这样的代码:

String queryString = "from Item i where i.description like '" + searchString + "'";
     List result = session.createQuery(queryString).list();

如果用户输入:foo' and callSomeStoredProcedure() and 'bar' = 'bar,则你的程序在执行一个简单查询后,还会调用某个存储过程,

这样你的程序就开了一个安全漏洞,如果用户偶尔输入了一个单引号,你的程序就可能报错。

永远也不要把未经检查的用户输入的值直接传给数据库!

幸运的时有一个简单的机制可以避免这种错误:

JDBC在绑定参数时有一个安全机制,它可以准确的将那些需要转义的字符进行转义(escape),

如上面的searchString,它被escape,不再作为一个控制字符了,而是作为被查询的匹配的字符串的一部分。(这里指的是prepared statement,而是用普通的statment不行,我试过)。

另外,如果我们使用参数绑定,还可以提高数据库的执行效率,prepared statement语句被编译一次后,被放在cache中,就不再需要编译,可以提高效率。

参数绑定有2种办法:使用positional parameter或者named parameter。

Hibernate支持JDBC样式的positional parameter(查询字符串中使用?),它同使用named parameter的效果一样(查询字符串中使用:)。

使用named parameter

使用named parameter,我们重新写上面的查询语句:

String queryString = "from Item item where item.description like :searchString";

冒号后面是一个named parameter,我们可以使用Query接口将一个参数绑定到searchString参数上:

List result = session.createQuery(queryString)
                      .setString("searchString", searchString)
                      .list();

因为searchString是一个用户输入的字符串,所以我们使用Query的setString()方法进行参数绑定,这样代码更清晰,更安全,效率更好!

如果有多个参数需要被帮定,我们这样处理:

String queryString = "from Item item "
                           + "where item.description like :searchString "
                           + "and item.date > :minDate";
List result = session.createQuery(queryString)
                  .setString("searchString", searchString)
                   .setDate("minDate", minDate)
                  .list();

使用positional parameter

如果你喜欢,也可以使用positional parameter:

String queryString = "from Item item "
                           + "where item.description like ? "
                           + "and item.date > ?";
List result = session.createQuery(queryString)
                  .setString(0, searchString)
                  .setDate(1, minDate)
                  .list();

这段代码可读性强不如上面的强,而且可维护性差,如果我们的查询稍微改变一点,将第一个参数和第二个参数改变一下位置:

String queryString = "from Item item "
                            + "where item.date > ? "
                           + "and item.description like ?";

这样我们的代码中涉及到位置的地方都要修改,所以我们强烈建议使用named parameter方式进行参数绑定。

最后,在named parameter中可能有一个参数出现多次的情况,应该怎么处理呢?

String userSearch = "from User u where u.username like :searchString"
                           + " or u.email like :searchString";
List result = session.createQuery(userSearch)
                  .setString("searchString", searchString)
                   .list();

不要使用

为了防止SQL注入,避免使用拼凑SQL语句的方式!!!

在Hibernate+Spring中getHibernateTemplate()返回的对象可以调用find(String queryString, Object value...Object value)来实现named parameter。比如:

Date startTime = new Date();

Date endTime = new Date();

String queryString = "from SdmsRacalertLog as log wherelog.alertTime between :startTime and :endTime";

return getHibernateTemplate().find(queryString, startTime, endTime);

Hibernate防止SQL注入的更多相关文章

  1. hibernate规避SQL注入实例

    项目被检测出SQL注入,注入url如:http://127.0.0.1:8080/Test/wlf/getServiceInfo.html?province=%25E6%25B5%2599%25E6% ...

  2. 使用Hibernate防止SQL注入的方法

    之前写代码,往后台传入一个组织好的String类型的Hql或者Sql语句,去执行. 这样其实是很蠢的一种做法!!!! 举个栗子~~ 我们模仿一下用户登录的场景: 常见的做法是将前台获取到的用户名和密码 ...

  3. hibernate防止sql注入对参数赋值传参数的例子

    来源于:https://my.oschina.net/u/1754093/blog/707083 1.按参数名称绑定 在HQL语句中定义命名参数要用":"开头,形式如下: Quer ...

  4. Hibernate使用中防止SQL注入的几种方案

    Hibernate使用中防止SQL注入的几种方案 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数 ...

  5. Hibernate一些防止SQL注入的方式

    Hibernate在操作数据库的时候,有以下几种方法来防止SQL注入,大家可以一起学习一下. 1.对参数名称进行绑定: Query query=session.createQuery(hql); qu ...

  6. 【Hibernate实战】源码解析Hibernate参数绑定及PreparedStatement防SQL注入原理

        本文采用mysql驱动是5.1.38版本. 本篇文章涉及内容比较多,单就Hibernate来讲就很大,再加上数据库驱动和数据库相关,非一篇文章或一篇专题就能说得完.本文从使用入手在[Spr ...

  7. 防御sql注入

    1. 领域驱动安全 领域驱动安全是一种代码设计方法.其思想是将一个隐式的概念转化为显示,个人认为即是面向对象的方法,将一个概念抽象成一个类,在该类中通过方法对类的属性进行约束.是否是字符串,包含什么字 ...

  8. 网页闯关游戏(riddle webgame)--SQL注入的潘多拉魔盒

    前言: 之前编写了一个网页闯关游戏(类似Riddle Game), 除了希望大家能够体验一下我的游戏外. 也愿意分享编写这个网页游戏过程中, 学到的一些知识. web开发初学者往往会忽视一些常见的漏洞 ...

  9. SQL 注入防御方法总结

    SQL 注入是一类危害极大的攻击形式.虽然危害很大,但是防御却远远没有XSS那么困难. SQL 注入可以参见:https://en.wikipedia.org/wiki/SQL_injection S ...

随机推荐

  1. kettle查询出来的真实值被识别为null

    问题描述: 通过关联表查询出来的applyId(申请编号),在数据流里也是能看到的,但是在写入到数据表中的时候,由于设置了这个字段不能为空,所以一直报错. 问题实质: 数据流内存在的数据却不能保存,原 ...

  2. Mac ssh登陆linux并且显示linux图形

    背景: Mac 通过[终端]ssh登陆linux并且在Mac显示linux图形 Mac 主机IP: 10.2.1.1 linux 主机IP: 192.168.1.1 说明: 想要ssh访问并且显示li ...

  3. CentOS6.5下Mysql数据库的安装与配置

    一.mysql简介 说到数据库,我们大多想到的是关系型数据库,比如mysql.oracle.sqlserver等等,这些数据库软件在windows上安装都非常的方便,在Linux上如果要安装数据库,咱 ...

  4. C语言基础11

    函数指针的定义: 函数类型 (标识符 指针变量名)(形参列表) void  printHello( ); void printHello( ){ printf("hello world!!! ...

  5. 解析XML【C#】

     1.XML元素XML元素包含一个开标记.元素中的数据.闭标记例如:<book>book name</book>其中book是元素名称  book name是元素数据元素名称区 ...

  6. python学习day4

    目录 一.迭代器 二.yield生成器 三.装饰器 四.递归 五.基础算法 迭代器 #1.在不使用for循环的情况下 li = [11 ,22, 33, 44] #count = len(li) #s ...

  7. C# 线程池异步调用

    许多应用程序使用多个线程,但这些线程经常在休眠状态中耗费大量的时间来等待事件发生.其他线程可能进入休眠状态,并且仅定期被唤醒以轮询更改或更新状态信息,然后再次进入休眠状态.为了简化对这些线程的管理,. ...

  8. Starling开发微信打灰机(二)

    上一篇中,已经把starling开发环境搭建好,那么现在开始写代码. 这一篇来完成打灰机的欢迎界面. 游戏素材下载 首先创建Asset.as来加载图片,声音和字体等资源,其中只有两张背景图是单独的图片 ...

  9. OSCHina技术导向:Java全文搜索框架Lucene

    Lucene 是apache软件基金会一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎.Lucene的目的是为软件开发人员提供一个简单易用 ...

  10. poj 1458 Common Subsequence_最长公共子串

    题意:略 求最长公共子串 #include<iostream> #include<cstdio> #include<string> using namespace ...