【问题标题】:What are the risks when using StringBuilder and JPA native queries?使用 StringBuilder 和 JPA 原生查询有哪些风险?
【发布时间】:2018-02-05 16:18:47
【问题描述】:

我需要创建一个原生 sql 查询,我打算使用 StringBuilder 来创建它。

StringBuilder sqlQuery = new StringBuilder();
    sqlQuery.append("SELECT ");
    sqlQuery.append("b.\"id\", ");
    sqlQuery.append("b.\"title\", ");
    sqlQuery.append("a.\"author_name\" as author ");
    sqlQuery.append("FROM ");
    sqlQuery.append(":dbName b ");
    sqlQuery.append("JOIN ");
    sqlQuery.append(":dbName2 a");
    sqlQuery.append(" ON a.\"id\" = b.\"author\"");

    ObjectQuery query = objectManager.createQuery(sqlQuery.toString());
    query.setParameter("dbName", "Book");
    query.setParameter("dbName2", "Author");

使用StringBuilder的append安全吗?这不会导致来自攻击者的 SQL 注入吗?攻击者是否能够附加将删除整个数据库的查询的一部分?有什么建议吗?

我知道这个查询很简单,可以用单个字符串编写,但我有更大的查询,如果语句和循环根据参数附加更多行

我知道命名查询更安全,但就我而言,直到最后一刻我才知道查询会是什么样子。

【问题讨论】:

  • 您在这里使用 StringBuilder 的原因是什么?您的查询可以写入一个字符串文字,无需串联。
  • @Tom 我对决定附加什么的 if 语句有更大的查询。为了便于阅读,我放了一个简短的
  • AFAIK,不管你使用 String 还是 StringBuilder,如果你不使用preparedstatement,那么它很容易受到攻击。
  • 如果您在没有验证的情况下附加用户输入,或者您没有仔细转义用户输入,是的,可能存在这种可能性
  • 您可能需要查看 CriteriaAPI。

标签: java jpa eclipselink


【解决方案1】:

如果您在示例代码中使用Query.setParameter() 设置参数值:

query.setParameter("dbName", "Book");
query.setParameter("dbName2", "Author");

您不应该有 SQL 注入问题。

当您在创建的查询中连接自己的用户数据时,就会发生 SQL 注入。
但您不在这种情况下,因为StringBuilder 对象创建的查询完全由您掌握,并且不会从外部客户端获取任何值。

使用StringBuilder的append安全吗?

虽然StringBuilder 变量(注意:StringBuilder 不是线程安全的)是在方法范围内创建和操作的,但它并不比其他解决方案更安全。

它与安全没有任何关系,但正如@HRgiger 建议的那样,一个不错的选择是使用Criteria API。
当您解释查询的构建是非常动态的时,这是有道理的:

我对 if 语句有更大的查询来决定要做什么 追加

它将生成更易于维护和可读的代码。

【讨论】:

  • @Octtavius 你提到你使用了很多 if 条件,正如大卫所说,如果你不使用用户输入,这就是答案
  • @HRgiger, davidxxx .append() 方法怎么样。有没有更好的方法来创建查询或使用 StringBuilder 可以吗?
  • @Octtavius jpa2 criteriabuilder
  • 感谢大卫和@HRgiger,解释得很好。只是想知道:使用 Criteria API 会有什么优势,特别是如果我使用 sql 查询?我想这不是更安全或更快。可能它可能会更快,因为它不会像 JPQL 那样在每个方法调用上都被解析。但是,如果查询根据参数变化很大,那么 Criteria 可能没有太多优势。我不期望任何 cmets/答案,因为这是一个不同的话题,但很高兴听到你的想法。 :)
  • @Octtavius 相反,条件更适合多参数搜索条件和条件,当您想保持类型安全时会导致原因
【解决方案2】:

在这种情况下,仅仅因为使用setParameter,就没有受到SQL注入攻击的风险,但是你必须注意StringBuilder不是线程安全的类型。

【讨论】:

  • 对。虽然上面的本地 StringBuilder 是可以的,但“线程安全”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-18
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
  • 2011-08-31
  • 1970-01-01
  • 2011-04-23
相关资源
最近更新 更多