Mysql Hibernate createSQLQuery-它如何验证SQL?

Mysql Hibernate createSQLQuery-它如何验证SQL?,mysql,hibernate,sql-injection,Mysql,Hibernate,Sql Injection,我有一些代码可以将用户的搜索词转换为MySQL查询: String sql = String.format("SELECT * FROM my_table WHERE my_column = '%s'", value); HibernateUtil.getCurrentSession().createSQLQuery(sql); 为了测试我是否受到保护,因为我认为以这种方式学习会很有趣——我想尝试SQL注入我自己的应用程序。所以我搜索: x'; DROP TABLE test;-- 这将导致

我有一些代码可以将用户的搜索词转换为MySQL查询:

String sql = String.format("SELECT * FROM my_table WHERE my_column = '%s'", value);
HibernateUtil.getCurrentSession().createSQLQuery(sql);
为了测试我是否受到保护,因为我认为以这种方式学习会很有趣——我想尝试SQL注入我自己的应用程序。所以我搜索:

x'; DROP TABLE test;--
这将导致以下查询:

SELECT * FROM my_table WHERE my_column = 'x'; DROP TABLE test;--
但是Hibernate抛出了一个SQLGrammarException。当我通过phpMyAdmin运行此代码时,它会正确地删除测试表

Hibernate如何验证我的SQL?也许更重要的是,这可以防止SQL注入,或者我应该使用setParameter。如果它不能保护我,我可以举一个SQL的例子来执行注入。我认为实际验证会很有趣。

根据,方法createSQLQuery“为给定的SQL字符串创建一个新的查询实例”,因此我们可以假设Hibernate在每次调用该方法时对单个查询执行SQL检查

重要提示:createSQLQuery在Hibernate上已被弃用,请查看上面给出的链接以了解执行SQL查询的新方法

现在,谈到如何防止SQL注入,最好的方法是在查询中使用参数

有确切的例子,你需要的,请检查出来


希望这对你的学习有帮助,祝你好运

由于
createSQLQuery
只允许一条语句,因此可以防止执行多条语句。这里保护您的不是Hibernate,而是您的JDBC驱动程序和数据库,因为它不知道如何处理分隔符
在单个语句的上下文中

但是您仍然不能安全地抵御SQL注入。在这种情况下,还有很多其他的可能性可以注入SQL。举个例子:

假设您正在查询中搜索某些特定于用户的项:

 String sql = String.format(
     "SELECT * FROM my_table WHERE userId = %s AND my_column = '%s'", 
     currentUserId, value);
用户现在可以输入:

 x' OR '1' = '1
这将导致SQL:

 SELECT * FROM my_table WHERE userId = 1234 AND my_column = 'x' OR '1' = '1'
而且由于
具有更高的优先级,他将看到所有项目,甚至是其他用户的项目

例如,即使您提供的示例也可能是危险的

 x' OR (SELECT userName FROM USER) = 'gwg

将告诉我您的数据库是否包含名为
gwg
的用户(假设我知道您的数据库布局,我可以通过类似的查询找到)。

建议使用参数化查询。@doublesharp,对,但在我更改所有数据访问代码之前,我想验证
createSQLQuery
是否没有清理我的SQL。
SQLGrammarException
的消息是什么?