如果在查询字段中输入单引号"'",则会报错,这是因为输入的单引号和其他的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. 在windows下安装mysql

    本文主要讲mysql解压版在windows下的安装和配置,在官网http://www.mysql.com/下载mysql-cluster-gpl-7.3.7-winx64.zip,然后将mysql解压 ...

  2. windows程序设计读书笔记1——创建窗口

    第一个win32程序,简单的创建窗口: #include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ...

  3. Oracle EBS-SQL (OM-6):打开订单.sql

    /*打开头*/ update oe_order_headers_all t set t.flow_status_code = 'BOOKED', t.open_flag = 'Y' where t.o ...

  4. EPiServer 简单项目总结

    国内用到的EPiServer应该不多,所以记录点用到过的东西,以便分享 1.EPiServer office site http://www.episerver.com/ 2.EPiServer CM ...

  5. [置顶] lvs-tun隧道模式搭建

    一.lvs直接路由原理 由于图片还要一张一张上传,可以到下面网站下载我的word版本: http://download.csdn.net/user/y0908105023 补充基础知识: OSI(Op ...

  6. matlab---边缘之sobel简单实例

    最近在项目中需要做一些图像边缘检测的工作,但是由于之前没接触过图像处理的相关知识,所以只得 在matlab里面对一些图像处理函数挨个挨个的试着用.在用的过程中在慢慢的明白了一些简单的图像处 理方法. ...

  7. systemctl 命令完全指南

    http://www.linuxidc.com/Linux/2015-07/120833.htm Systemctl是一个systemd工具,主要负责控制systemd系统和服务管理器. System ...

  8. 什么是OAuth

    什么是OAuth 如今很多网站的功能都强调彼此间的交互,因此我们需要一种简单,标准的解决方案来安全的完成应用的授权,于是,OAuth应运而生,看看官网对其的定义: An open protocol t ...

  9. linux下的时间及时区设置

    一.时间设置及同步 1修改系统时间 #date -s 06/18/14 #date -s 14:20:50 2命令查看.设置硬件时间 #hwclock  --show 或者clock  --show ...

  10. 让rdlc报表在ReportViewer中水平居中的方法

    正常情况下,rdlc报表在Reportviewer中是居左显示的,如图: 在Reporviewer的属性中,我没有找到能让rdlc的居中显示的方法.网上其他人用的方法都试了,没能实现,只能自己找方法解 ...