【问题标题】:Named parameters not bound命名参数未绑定
【发布时间】:2021-08-13 05:31:54
【问题描述】:

我有多个 HQL 语句易受 SQL 注入示例的影响:

public List<Person> SearchList(String userName, String firstName, String lastName, String email) Exception {
   List<Person> personList = new ArrayList<>();
   String hql = " FROM **.***.***.entity.Person P WHERE ";
   boolean buName = false;
   boolean bfName = false;
   if (StringUtils.isNotEmpty(userName)){
      hql = hql + "lower(P.userName) like :userName "; 
      buName = true;
   }
   if (StringUtils.isNotEmpty(firstName) && StringUtils.isNotEmpty(lastName)){    
      if(buName){
         hql = hql + " OR ";
      }
      hql = hql + "(lower(P.firstName) like :firstName AND lower(P.lastName) like :lastName) ";  
      bfName = true;    
   }
   if (StringUtils.isNotEmpty(internetAddr)){    
      if(buName || bfName){
         hql = hql + " OR ";
      }
      hql = hql + "lower(P.email) = :email"; 
   }
   try {
      Query query = getCurrentSession().createQuery(hql);
        
      if (StringUtils.isNotEmpty(userName)) {
         query.setParameter("userName", '%'+userName.toLowerCase()+'%');
      } else if (StringUtils.isNotEmpty(firstName) && StringUtils.isNotEmpty(lastName)) {
         query.setParameter("firstName", '%'+firstName.toLowerCase()+'%');
         query.setParameter("lastName", '%'+lastName.toLowerCase()+'%');
      } else if (StringUtils.isNotEmpty(email)) {
         query.setParameter("email", email.toLowerCase());
      }

      personList = query.list();
   } catch(Exception e){
      throw new Exception(e.getMessage());
   }
   return personList;
}

这里我避免在查询"'%" + userName + "%'" 中连接以避免 SQL 注入漏洞,现在我看到与

相关的异常
Named parameters not bound: lastname

这是基于使用 firstname 的搜索而发生的。我怎样才能避免这种情况?

【问题讨论】:

  • 在 JDBC 中使用和设置参数可以避免 SQL 注入攻击。当有人可以将东西注入实际的 SQL 语句本身时,就会发生 SQL 注入攻击。

标签: java sql hibernate hql createquery


【解决方案1】:

你应该纠正这个:

if (StringUtils.isNotEmpty(userName)) {
   query.setParameter("userName", '%'+userName.toLowerCase()+'%');
} else if (StringUtils.isNotEmpty(firstName) && StringUtils.isNotEmpty(lastName)) {
   query.setParameter("firstName", '%'+firstName.toLowerCase()+'%');
   query.setParameter("lastName", '%'+lastName.toLowerCase()+'%');
} else if (StringUtils.isNotEmpty(email)) {
   query.setParameter("email", email.toLowerCase());
}   

到这里:

if (StringUtils.isNotEmpty(userName)) {
   query.setParameter("userName", '%'+userName.toLowerCase()+'%');
}
if (StringUtils.isNotEmpty(firstName) && StringUtils.isNotEmpty(lastName)) {
   query.setParameter("firstName", '%'+firstName.toLowerCase()+'%');
   query.setParameter("lastName", '%'+lastName.toLowerCase()+'%');
}
if (StringUtils.isNotEmpty(email)) {
   query.setParameter("email", email.toLowerCase());
}   

因为您应该将命名参数添加到 HQL 并通过 query.setParameter 一致地设置它们。

注意

我在查询“'%”+用户名+“%'”中避免串联以避免SQL注入漏洞

您可以在 HQL 中使用 concatenation (operation),如下所示:

... 
lower(P.userName) like '%' || :userName || '%'
...

它也可以让您避免 SQL 注入。但请注意,这个like 很可能会导致full table scan

【讨论】:

    猜你喜欢
    • 2021-04-05
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 2020-02-13
    • 2022-11-01
    • 1970-01-01
    • 2013-06-15
    相关资源
    最近更新 更多