java - hibernate : How to prevent SQL injection when the collection elements needs to check with `like` operator?

标签 java hibernate sql-injection oracle12c

我有一个类似这样的查询

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 来自外部源。

如果我的集合元素将基于 = 运算符进行比较,那么我使用准备好的语句,例如:

sbQry.append(column in (:collection));
Query query = session.createSQLQuery(sbQry.toString());
query.setParameterList("collection",myCollection);

有人可以建议我如何防止这种情况下的 SQL 注入(inject)吗?

任何帮助将不胜感激。

最佳答案

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

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]);
}

我还没有测试过上面的代码,但它应该可以让你有一个大概的了解。

使用绑定(bind)参数而不是字符串连接是防止 SQL 注入(inject)的安全方法,而且还使代码更易于编写和阅读。

还使用 ArrayList 作为术语和 String.join(),这意味着您不必为开头的 1=1 或特殊条件代码而大惊小怪或该系列术语的结尾。

关于java - hibernate : How to prevent SQL injection when the collection elements needs to check with `like` operator?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49512493/

相关文章:

java - 当我在 Elasticsearch 2.2 中恢复并同时索引更多文档时,ES 的行为如何?

java - Hibernate @OneToMany 注释到底是如何工作的?

MySql - 限制查询的 SELECT 子句中允许的计算

mysql - 来自命令行的注入(inject)证明 SQL 语句

c# - Entity Framework +sql注入(inject)

java - 在 ScramSha1Authenticator 中使用强大的算法 - 按照 Veracode?

java - 如何在 Java/jtds 应用程序中支持 SQL GO 语句?

java - java 中对象与原始传递如何工作(在集合的上下文中)?

java - 在 hibernate 选择中创建对象

java - 找不到文件 mysql-connector-java-5.1.13-bin.jar