在Java中使用准备好的语句和变量绑定以便能够通过与JDBC驱动程序在Java中使用准备好的语句和变

2019-05-12 04:10发布

我正在使用

  1. 的JdbcTemplate进行JDBC连接到MySQL数据库
  2. 准备的语句来保护自己尽可能多地从SQL注入攻击
  3. 在需要接受来自用户的请求,在任何十几个不同的列的数据进行排序
  4. 下面的语句

     jdbcTemplate.query("SELECT * FROM TABLE1 ORDER BY ? ?", colName, sortOrder); 

当然,这是不行的,因为变量绑定不应该在查询表达式指定列名只是参数值。

那么......是人们解决这一问题? 只是做在Java代码中的排序似乎是一个简单的解决方案,但因为我得到一个字符串变量对列进行排序,和可变告诉我的排序顺序....这是一个丑陋的数量的比较,条件覆盖。 这似乎是它应该是一个共同的模式来解决这一个共同的问题...

Answer 1:

占位符? 只能用于参数值,但不会列和排序顺序方向。 因此,要做到这一点的标准方法是尖如这里是使用字符串#格式()或类似的东西到你的列名,订单价值附加到您的查询。

另一种选择是使用Spring的JPA的数据,你可以给你的方法作为参数类型的实例排序可以包含数据库排序所有需要的信息。



Answer 2:

我只想拼接列名和顺序的SQL查询,但只有在

  1. 验证列名和顺序都在这方面有效。
  2. 消毒来对抗任何企图SQL注入攻击。

我觉得这是有效率相比,在获取结果到应用层和他们在这里整理。



Answer 3:

我的建议是键列的映射。 这是一个安全的解决方案。

在开始的时候,我们开始我们的最简单的方式映射。 为了方便起见,我重载的get(Obiect key)方法,以在发生故障时恢复默认列(“全名”)。 这将防止SqlExeption。

    static Map<String,String> sortCol;
{
    sortCol = new HashMap<String, String>(){
        {//Enter all data for mapping
            put("name","fullName");
            put("rok","year");
            put("rate","likes");
            put("count-rate","countRate");

        }
        /**
         * 
         * @param key for column name
         * @return column name otherwise default "fullName"
         */
        @Override
        public String get(Object key) {
            String col =super.get(key);
            return null==col?"fullName":col;
        }
    };
}

下面是使用一个简单的例子。

String sqlQuery= "Select \"fullName\",year,likes,count-rate, country ..."+
 "from  blaBla..."+
 "where blaBla..."+
 "order by "+sortCol.get("keySort") "\n"; // keySort can have the value name, count-rate etc .. 

顺便说一句,你永远不应该泄露列的实名用户接口,如REST或SOAP等..对于攻击者来说,这是一个很大的帮助。



文章来源: Using a prepared statement and variable bind Order By in Java with JDBC driver