通过添加分隔符参数化查询
Posted
技术标签:
【中文标题】通过添加分隔符参数化查询【英文标题】:Parameterizing queries by adding a delimiter 【发布时间】:2018-08-13 13:50:43 【问题描述】:假设所有参数都是字符串,我通过这个函数运行所有参数(我禁止在我的网站上使用“|”字符)
public String EscapeParameter(String Param)
return "|" + param.replace("|", "") + "|"
这样的参数化查询是一种安全的方法吗?在这一点上,我确定所有参数都以“|”开头并以“|”结尾那么我可以遍历字符串并参数化查询,而不管它最初是如何构建的吗?
public String DynamicParameterizeQuery(String sql)
int stringSize = sql.length();
StringBuilder paraValueBuilder = new StringBuilder();
Boolean inParam = false;
StringBuilder sb = new StringBuilder();
Map<String, String> paramMap = new HashMap<String, String>();
for(int i = 0; i < stringSize; i++)
Character currentChar = sql.charAt(i);
if(currentChar == '|' && inParam == false)
inParam = true;
else if(currentChar == '|' && inParam == true)
inParam = false;
paramMap.put(":" + i*1000, paraValueBuilder.toString());
sb.append(":" + i*1000 + " ");
paraValueBuilder = new StringBuilder();
else
sb.append(currentChar);
getRows(sql, paramMap);
/**
* Gets a list of objects <T> from the database.
*
* @param <T> object type to be returned
* @param sql query to execute
* @param objectParameters query parameter values
* @param targetClass target class that will be returned. <T>
* @return A list of the specified objects.
*/
public <T> List<T> getRows(String sql, Object objectParameters, Class<T> targetClass)
RowMapper<T> rowMapper = new BeanPropertyRowMapper<T>(targetClass);
return getRows(sql, objectParameters, rowMapper);
这是防止 SQL 注入的安全方法吗?
【问题讨论】:
在可以使用适当的 SQL 参数的情况下,不清楚为什么需要这样做? 这个例子确实使用了正确的 SQL 参数,它只是在事后添加它们? 你能展示一个使用你的函数的例子吗? SQL 查询会是什么样子?另外,我不熟悉“@”标记作为参数占位符,我习惯于简单的?
占位符。此外,我从未见过采用 Map 对象的 executeQuery()
版本。你在用什么?
我说的是用某种分隔符来包装用户输入的参数,例如一个条形 public String EscapeParameter(String Param) return "|" + param.replace("|", "") + "|" 然后重新创建一个参数化查询
我已经更新了问题,它是 GenericJdbcDaoSupport,(它内置于)Spring
【参考方案1】:
我不会使用这种方法。
目前尚不清楚这是为了解决什么问题。我猜您的想法是,您需要将动态值连接到您的 SQL 查询中,以至于您宁愿这样做,然后编写一个精心设计的 Java 方法来提取这些值以将它们用作适当的参数。
你选择了“|”作为分隔符,这意味着您的网站必须禁止包含该字符的任何内容。祝您好运,向您的产品经理或用户解释该限制。
为什么不直接使用查询参数呢?
参数已知是一种安全可靠的解决方案。 参数最简单且不易出错。 参数不需要新的 Java 方法来取消连接字符串。 参数对值中可以出现的字符没有限制。顺便问一下,您的方法将如何处理二进制数据?使用每个人都知道是安全的标准解决方案有一些话要说。在代码审查期间,您可以节省至少 30 分钟,因为不必解释您的 DynamicParameterizeQuery() 方法以及为什么它是安全的以及为什么您的网站不支持“|”字符。
【讨论】:
代码审查?这个应用程序是 20 年前写的,有超过 3000 个查询,至少有 30 或 40000 个参数,可能更多。手动重写每个查询是不可能的。所以我只能试着想出下一个最好的东西。查询基本的第二个最安全的方法是什么 旧版本的 Apache Commons Lang 像 2.0 有StringEscapeUtils.escapeSql()
但在当前版本中已弃用。不管是使用第三方的字符串转义方法,还是自己的方法,或者参数,你不是都得重写每个查询吗?以上是关于通过添加分隔符参数化查询的主要内容,如果未能解决你的问题,请参考以下文章