之前写代码,往后台传入一个组织好的String类型的Hql或者Sql语句,去执行。

这样其实是很蠢的一种做法!!!!

举个栗子~~

我们模仿一下用户登录的场景:

常见的做法是将前台获取到的用户名和密码,作为字符串动态拼接到查询语句中,然后去调用数据库查询~查询的结果不为null就代表用户存在,则登陆成功,否则登录失败!

正常情况下用户输入账号是和密码123(假设是错误的密码或者说这个用户根本不存在)

usernameString//前台输入的用户名
passwordString//前台输入的密码
//hql语句
String queryString = "from User t where t.username= " + usernameString + " and t.password="+ passwordString;
//执行查询
List result = session.createQuery(queryString).list();

正常用户输入的话,sql语句被拼接成: from User t where t.username=123456  and t.password=123 ;

这样是正常的sql语句。可以去查询数据库验证是否有此用户数据。

但是!

如果用户在密码输入框中输入:123  or 1=1   作为一个字符串传入后台后

sql语句被拼接成: from User t where t.username=123456  and t.password=123 or 1=1;

一旦加上or 1=1 那么这条sql永远成立!!!更严重的可以删除数据库中表,篡改信息,及其严重!!!

我们来解释一下为什么会被SQL注入?

sql注入的原因,表面上说是因为 拼接字符串,构成sql语句,没有使用 sql语句预编译,绑定变量。

但是更深层次的原因是,将用户输入的字符串,当成了 “sql语句” 来执行。

比如上面的 String queryString = "from User t where t.username= " + usernameString + " and t.password="+ passwordString;

我们希望用户输入的 username和password 的值,仅仅作为一个字符串字面值,传入数据库执行。

但是当输入了:123 or 1=1 时,其中的 or 1=1 并没有作为 where id= 的字面值,而是作为了 sql语句 来执行的。所以其本质是将用户的输入的数据,作为了命令来执行。

SQL防御

基本上大家都知道 采用sql语句预编译和绑定变量,是防御sql注入的最佳方法。为了防止SQL注入,避免使用拼凑SQL语句的方式!!!

实际项目中,一般我们都是采用各种的框架,比如ibatis, hibernate,mybatis等等。他们一般也默认就是sql预编译的。对于ibatis/mybatis,如果使用的是 #{name}形式的,那么就是sql预编译,使用 ${name} 就不是sql预编译的。

参数绑定有2种办法:使用positional parameter(查询字符串中使用?)或者named parameter(查询字符串中使用:)。

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

使用named parameter

usernameString//前台输入的用户名
passwordString//前台输入的密码
//hql语句
String queryString = "from User t where t.username:usernameString and t.password: passwordString";
//执行查询
List result = session.createQuery(queryString)
.setString("usernameString ", usernameString )
.setString("passwordString", passwordString)
.list();

使用positional parameter

usernameString//前台输入的用户名
passwordString//前台输入的密码
//hql语句
String queryString = "from User t where t.username=? and t.password=?";
//执行查询
List result = session.createQuery(queryString)
.setString(0, usernameString )
.setString(1, passwordString)
.list();

两者比较:positional parameter可读性强不如named parameter的强,而且可维护性差,如果我们的查询稍微改变一点,将第一个参数和第二个参数改变一下位置,

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

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

在举个栗子~~

我们模仿一下用户登录的场景:这次业务变换,有的网站,手机号可以作为用户名来登录,也能作为手机号本身登录。

常见的做法是将前台获取到的用户名or手机号和密码,作为字符串动态拼接到查询语句中,然后去调用数据库查询~查询的结果不为null就代表用户存在,则登陆成功,否则登录失败!

正常情况下用户输入账号是和密码

这里usernameString作为手机号又作为用户名出现了两次,怎么办呢?

大家请看下面代码:

usernameString//前台输入的用户名
passwordString//前台输入的密码
//hql语句
String queryString = "from User t where t.username:usernameString and
t.phone:usernameString and t.password: passwordString";
//执行查询
List result = session.createQuery(queryString)
.setString("usernameString ", usernameString )
.setString("passwordString", passwordString)
.list();

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

usernameString//前台输入的用户名
passwordString//前台输入的密码
//hql语句
String queryString = "from User t where t.username:usernameString and t.password: passwordString";
//执行查询
return getHibernateTemplate().find(queryString, usernameString, passwordString);

PS:其实说这么多都是扯淡,因为现在真是商业项目中,没有把密码以明文的方式存入数据库的,基本上都是经过加密以后进行比对。所以不管用户输入什么都会解密成一个字符串。所以,这种SQL注入基本上已经不存在了~~~~

所以还是建议大家在开发中,多规范一下自己的代码,让代码更加健壮!

使用Hibernate防止SQL注入的方法的更多相关文章

  1. 防御SQL注入的方法总结

    这篇文章主要讲解了防御SQL注入的方法,介绍了什么是注入,注入的原因是什么,以及如何防御,需要的朋友可以参考下   SQL 注入是一类危害极大的攻击形式.虽然危害很大,但是防御却远远没有XSS那么困难 ...

  2. mysql进阶(二十四)防御SQL注入的方法总结

    防御SQL注入的方法总结 这篇文章主要讲解了防御SQL注入的方法,介绍了什么是注入,注入的原因是什么,以及如何防御,需要的朋友可以参考下. SQL注入是一类危害极大的攻击形式.虽然危害很大,但是防御却 ...

  3. 在php中防止SQL注入的方法

    摘要:我们php手手工安装的,php的默认配置文件在 /usr/local/apache2/conf/php.ini,我们最主要就是要配置php.ini中的内容,让我们执行 php能够更安全.整个PH ...

  4. Python中防止sql注入的方法详解

    SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库.下面这篇文章主要给大家介绍了关于Python中 ...

  5. python防止sql注入的方法

    python防止sql注入的方法: 1. 使用cursor.execute(sql, args)的参数位: sql_str = "select * from py_msgcontrol.py ...

  6. PHP+Mysql防止SQL注入的方法

    这篇文章介绍的内容是关于PHP+Mysql防止SQL注入的方法,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 方法一: mysql_real_escape_string -- 转义 S ...

  7. SQL 注入防御方法总结

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

  8. Hibernate防止SQL注入

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

  9. hibernate规避SQL注入实例

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

随机推荐

  1. vuex相关(actions和mutation的异曲同工)

    vuex说明: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 包含的内容: state: ...

  2. 树莓派 -- bcm2835 library (1)

    bcm2835 library提供了user space 操作IO的代码. 本文不涉及代码分析,先直观的按照user guide完成操作. 1. 在Raspberry中安装bcm2835 librar ...

  3. CSS Specificity(特殊性)

    CSS的特殊性是非常重要却又经常被忽视的属性,特别是在团队合作下的产品迭代开发中,因为不注重CSS的特殊性最后导致某些代码混乱不堪,这里就把自己对CSS特殊性的认识做一些归纳总结. CSS的特殊性(s ...

  4. Python学习之单继承与多继承

    继承 面向对象编程语言的一个主要功能就是“继承”. 继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展. (1) 单继承:python同时支持类的继承 ...

  5. 【转载】Hadoop NameNode 高可用 (High Availability) 实现解析

    转载:https://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop-name-node/ NameNode 高可用整体架构概述 在 Had ...

  6. 读书笔记:《人有人的用处》------N.维纳. (2016.12.28)

    读书笔记:<人有人的用处>------N.维纳 ·某些系统可以依其总能量而和其他系统区别开来. ·在某些情况下,一个系统如果保持足够长时间的运转,那它就会遍历一切与其能量相容的位置和动量的 ...

  7. 76-Bears/Bulls Power,熊力/牛力震荡指标.(2015.7.1)

    Bears/Bulls Power 熊力/牛力震荡指标 Power,熊力/牛力震荡指标.(2015.7.1)" title="76-Bears/Bulls Power,熊力/牛力震 ...

  8. 关于c# .net爬虫

    刚开始听到爬虫这两个字眼的时候感觉挺稀奇的,之前并没有接触过爬虫,正好这会手上没事,于是便百度了一下. 1.网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种 ...

  9. cmake打印变量值

    看下面的例子,我们在cmake定义了一个变量“USER_KEY”,并打印此变量值.status表示这是一般的打印信息,我们还可以设置为“ERROR”,表示这是一种错误打印信息. SET(USER_KE ...

  10. Error connecting to database: No such file or directory

    标签:Error connecting to database: No such file or directory 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明 ...