【问题标题】:is it safe to use java.text.MessageFormat.format() when creating an sql query?创建 sql 查询时使用 java.text.MessageFormat.format() 是否安全?
【发布时间】:2020-01-28 11:53:18
【问题描述】:

我正在使用 MessageFormat.format() 为我的 PreparedStatement 创建字符串。我读到使用 StringBuilder 可能是 sql 注入的原因。 MessageFormat也一样吗?

代码是这样的

String SQL
        = "select CT.SYS_CHANGE_OPERATION, CT.{0} as ID, t.*\n"
        + "from changetable (changes {1}, ?) as CT \n"
        + "left outer join {2} as t \n"
        + "on t.{3} = CT.{4} \n"
        + "order by CT.SYS_CHANGE_VERSION";

String finalSQL = MessageFormat.format(SQL, primaryKey, table, table, primaryKey, primaryKey);
        PreparedStatement pstmt = con.prepareStatement(finalSQL);

【问题讨论】:

  • 使用库转义所有用户输入
  • @toastedDeli 没有用户输入。我在 switch case 中使用它,而不是编写相同的脚本 50 次。
  • 如果primaryKeytable 不包含用户输入,它应该是安全的。但是使用StringBuilder 也是安全的。

标签: java database mssql-jdbc


【解决方案1】:

这不安全。 MessageFormat.format 只是用给定的对象替换给定字符串中出现的 {x} 而不转义后者。 因此它相当于字符串连接。

要构建包含变量数据的 SQL 查询,应始终使用预准备语句。

【讨论】:

    【解决方案2】:

    仅当变量字符串来自某些传递的输入时,像填写表和列名那样创建 SQL 字符串才是不安全的(SQL 注入)。

    因此StringBuilder 甚至可能比MessageFormat 更清晰(清晰)。另一方面,格式更具可读性。

    命名占位符会更好,考虑 Apache Common StringSubstitutor 或类似的。

    在任何情况下,代码检查器都可能会针对这方面的 SQL 注入发出警告。

    有时你可以使用

    DatabaseMetaData metaData = connection.getMetaData();
    

    并使用表名和列名对元数据进行操作。

    这是一种很大程度上独立于数据库供应商的 JDBC 查询数据库的方式。

    【讨论】:

      猜你喜欢
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      • 2012-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多