7

今天遇到了一些使用 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();
}

这安全吗?

4

3 回答 3

5

Hibernate Criteria Queries 在 Sql Injection 方面是安静安全的,因为它们在执行任何获取时将字符串作为参数传递。甚至,除非您通过字符串文字构建查询,否则 Hql 是安静安全的。

有关更多详细信息,您应该查看通过打开休眠 sql 日志记录在数据库级别触发的查询。

于 2013-04-05T19:48:40.693 回答
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 查询中一样。

于 2013-04-05T20:09:48.460 回答
1

Hibernate 对清理输入很有用,但清理输入并不是防止 SQL 注入攻击的最佳实践。随着您的代码随着时间的推移而开发,您需要记住随着数据库和客户端应用程序的更改而更改您的 Hibernate 环境;这为错误留下了很大的空间,任何一个错误都可能危及您的数据库。

为了防止 SQL 注入攻击,最好使用准备好的语句。在准备好的语句中,您的客户端应用程序将发出一个非 SQL 请求并让您的服务器生成您的 SQL 语句。

例如,如果用户想要城市“达拉斯”中的所有用户,那么您的客户端应用程序应该发出类似于用户名等于“达拉斯”的请求,然后您的服务器可以生成:

SELECT * FROM users WHERE name='Dallas'
于 2014-10-16T17:16:01.383 回答