通过添加分隔符参数化查询

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() 但在当前版本中已弃用。不管是使用第三方的字符串转义方法,还是自己的方法,或者参数,你不是都得重写每个查询吗?

以上是关于通过添加分隔符参数化查询的主要内容,如果未能解决你的问题,请参考以下文章

jmeter 参数化

使用dapper进行参数化查询

JMeter接口测试——参数化(从文件中读取参数)

jmeter——变量引用

JMeter参数化之__CSVRead()

二. Jmeter--参数化