HQL注入/ findAll与排序

时间:2015-11-29 19:35:49

标签: grails hql gorm

在我的应用程序中,通过使用像QueryBuilder.groovy这样的单独脚本附加第一部分(where子句)和第二部分(order by)来构建查询,因此按部分顺序易于HQL注入,这可以使用命名参数进行清理。因此,我想使用findAll通过分别传递查询和排序和分页参数来检索一组记录。我看到了这样的实现:

     domainClass.findAll(query,[namedParams],[max: 10, offset: 5])

当我将sortColumn和sortDirection作为命名参数传递时,sortColumn工作正常,但sortDirection不起作用。我需要一种方法来使sortDirection作为命名参数或任何其他方式将“按方向排序”与findAll结果相结合。许多人在各种论坛上建议直接将参数作为查询的一部分使用,但这对我的应用程序来说是不可接受的,因为它会将查询暴露给HQL注入。 提前谢谢。

这是一个例子:

  queryString = "FROM BookCatalog b WHERE b.bookNumber = :bookNumber"

这会传递给QueryBuilder.groovy,会发生类似这样的事情:

  sort = "$params.sortColumn $params.sortDirection"
  queryString.order(sort)

  public void sort(String query){
       this.query = this.query+" order by "+query
  }

最后findAll检索记录列表:

  def list = findAll(queryString,namedParams,queryParams)

因为逻辑只是将排序参数附加到查询字符串,潜在的黑客可以做这样的事情:

  bookCatalogView?offset=2&max=5&sortColumn=1,2,3 **or 1=1**

  bookCatalogView?offset=2&max=5&sortColumn=1,2,3;**select * from whatever**

1 个答案:

答案 0 :(得分:1)

不要连字符串,这是不好的做法。

如果要创建复杂查询,请考虑使用createCriteria()

SomeDomainClass.createCriteria().list {
    order("propName", "desc")
}

或者,如果您需要更多控制,请使用sessionFactory方式:

query = sessionFactory.getCurrentSession().createCriteria(DomainClass.class)
query.addOrder(Order.asc("someField"))
query.addOrder(Order.desc("someotherField"))