Hibernate:当集合元素需要用`like`操作符检查时,如何防止SQL注入?

时间:2018-03-27 12:08:29

标签: java hibernate sql-injection oracle12c

我有@Scope("singleton")这样的事情。

query

此查询StringBuilder sbQry = new StringBuilder(); sbQry.append("select * from tableName where 1=1"); if(!myCollection.isEmpty()){ sbQry.append(" and ("); for (int i = 0; i < myCollection.size(); i++) { final String module = myCollection.get(i); sbQry.append("column = '" + module + "' or column like 'J_'||'" + module.replaceAll("-", "%") + "'"); if (!(i == (myCollection.size() - 1))) { sbQry.append(" or "); } } sbQry.append(") "); } 容易受sbQry攻击,因为SQLInjection来自外部来源。

如果我的集合元素将基于myCollection运算符进行比较,那么我使用预处理语句,如:

=

有人可以建议我如何在这种情况下阻止SQL注入。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

为防止SQL注入,您应该使用绑定参数,而不是字符串插值。

StringBuilder sbQry = new StringBuilder();
List<String> params = new ArrayList<>();
sbQry.append("select * from tableName");
if(!myCollection.isEmpty()){
    sbQry.append(" where ");
    int size = myCollection.size;
    List<String> terms = new ArrayList<>();
    for (int i = 0; i < size; i++) {
        final String module = myCollection.get(i);
        terms.add("column = ? or column like ?");
        params.add(module);
        params.add("J_" + module.replaceAll("-", "%"));
    }
    sbQry.append(String.join(" or ", terms));
}

Query q = sess.createQuery(sbQry);
int size = params.size();
for (int i = 0; i < size; i++) {
    q.setString(i, params[i]);
}

我没有测试过上面的代码,但它应该给你一般的想法。

使用绑定参数代替字符串连接是一种防止SQL注入的安全方法,它还使代码更易于编写和更易于阅读。

同样使用ArrayList作为术语,String.join(),意味着您不必为1=1或特殊条件代码而烦恼,无论是术语系列的开头还是结尾。