创建 sql 查询时使用 java.text.MessageFormat.format() 是否安全?
is it safe to use java.text.MessageFormat.format() when creating an sql query?
我正在使用 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);
这不安全。 MessageFormat.format
只是将给定字符串中出现的 {x} 替换为给定对象,而不转义后者。
因此它相当于字符串连接。
要构建包含变量数据的 SQL 查询,应始终使用准备好的语句。
像填写 table 和列名 那样创建 SQL 字符串只会是不安全的(SQL 注入)变量字符串源于一些传递的输入。
因此 StringBuilder
甚至可能比 MessageFormat
更响亮(清晰)。另一方面,格式更具可读性。
由于命名占位符会更好,请考虑 Apache Common StringSubstitutor
等。
在每种情况下,代码检查器都可能会针对此 SQL 注入发出警告。
有时您可以使用
DatabaseMetaData metaData = connection.getMetaData();
并使用 table 和列名对元数据进行操作。
这是一种很大程度上独立于数据库供应商的 JDBC 查询数据库的方式。
我正在使用 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);
这不安全。 MessageFormat.format
只是将给定字符串中出现的 {x} 替换为给定对象,而不转义后者。
因此它相当于字符串连接。
要构建包含变量数据的 SQL 查询,应始终使用准备好的语句。
像填写 table 和列名 那样创建 SQL 字符串只会是不安全的(SQL 注入)变量字符串源于一些传递的输入。
因此 StringBuilder
甚至可能比 MessageFormat
更响亮(清晰)。另一方面,格式更具可读性。
由于命名占位符会更好,请考虑 Apache Common StringSubstitutor
等。
在每种情况下,代码检查器都可能会针对此 SQL 注入发出警告。
有时您可以使用
DatabaseMetaData metaData = connection.getMetaData();
并使用 table 和列名对元数据进行操作。
这是一种很大程度上独立于数据库供应商的 JDBC 查询数据库的方式。