今天遇到了一些使用Hibernate执行查询的代码。该查询使用从表单提交的值。这让我很好奇这种代码是否“消毒”了它的输入。
public List<School> search(String query) {
Session session = this.getCurrentSession();
query = "%" + query + "%";
Criteria criteria = session.createCriteria(getPersistentClass());
criteria.createAlias("country", "a");
Criterion nameCriterion = Restrictions.ilike("name", query);
Criterion cityCriterion = Restrictions.ilike("city", query);
Criterion countryCriterion = Restrictions.ilike("a.name", query);
Criterion criterion = Restrictions.or(Restrictions.or(nameCriterion, cityCriterion), countryCriterion);
criteria.add(criterion);
return criteria.list();
}
这样安全吗?
答案 0 :(得分:5)
如果您考虑SQL注入攻击,那么是的,Hibernate Criteria API是安全的。
它将通过首先从指定的查询字段编译它并且仅在应用查询参数之后生成基础查询(它应该使用经典的PreparedStatement
)。这样,JDBC驱动程序将知道查询的哪个部分是字段,哪个部分是参数。然后驱动程序将注意清理参数。
如果您需要在那里放置参数,那么您应该注意Criteria
上应用的SQL限制。例如
String vulnerable = //parameter from user interface
criteria.add(
Restrictions.sqlRestriction("some sql like + vulnerable") //vulnerable
criteria.add(
Restrictions.sqlRestriction("some sql like ?",
vulnerable, Hibernate.STRING)) //safe
在这种情况下,vulnerable
参数可以“泄漏”到查询字段部分,并被JDBC驱动程序检查绕过,就像在正常的易受攻击的SQL查询中一样。
答案 1 :(得分:4)
Hibernate Criteria查询在Sql Injection方面是安静的,因为它们在执行任何提取时将字符串作为参数传递。甚至,除非你通过字符串文字构建查询,否则Hql是安静的。
有关更多详细信息,您应该通过启用hibernate sql logging来查看在数据库级别触发的查询。
答案 2 :(得分:1)
Hibernate对于清理输入非常有用,但清理输入并不是防止SQL注入攻击的最佳实践。随着代码的不断发展,您需要记住在数据库和客户端应用程序发生变化时更改Hibernate卫生设施;这留下了很大的错误空间,任何一个错误都可能危及您的数据库。
为防止SQL注入攻击,最好使用预准备语句。在准备好的语句中,您的客户端应用程序将发出非SQL请求,并让您的服务器生成您的SQL语句。
例如,如果用户想要城市“Dallas”中的所有用户,那么您的客户端应用程序应该发出类似于 username equals“Dallas”的请求,然后您的服务器就可以生成:< / p>
SELECT * FROM users WHERE name='Dallas'