在Java和JDBC驱动程序中使用准备好的语句和变量bind Order By
我正在使用在Java和JDBC驱动程序中使用准备好的语句和变量bind Order By,java,sorting,jdbc,collections,jdbctemplate,Java,Sorting,Jdbc,Collections,Jdbctemplate,我正在使用 jdbcTemplate,用于建立到mySQL数据库的JDBC连接 准备语句以尽可能保护自己免受SQL注入攻击 需要接受来自用户的请求,对十几个不同列中的任意一列的数据进行排序 以下声明 jdbcTemplate.query("SELECT * FROM TABLE1 ORDER BY ? ?", colName, sortOrder); 当然,这不起作用,因为变量绑定不应该指定列名,而应该指定查询中表达式的参数值 那么,人们是如何解决这个问题的呢?在Java代码中进行排序似乎是
jdbcTemplate.query("SELECT * FROM TABLE1 ORDER BY ? ?", colName, sortOrder);
那么,人们是如何解决这个问题的呢?在Java代码中进行排序似乎是一个简单的解决方案,但因为我得到了一个变量字符串供列进行排序,并且一个变量告诉我排序顺序……这是一个需要涵盖的比较条件的丑陋数字。这似乎应该是一个常见的问题,用一个通用模式来解决它…我只想将列名和顺序连接到SQL查询,但只有在
我觉得这比将结果提取到应用程序层并在此处进行排序更有效。占位符
?
只能用于参数值,而不能用于列和排序顺序方向。因此,标准的方法是使用或类似的方法将列名和顺序值附加到查询中
另一种选择是使用SpringDataJPA,您可以将一个类型的实例作为参数提供给您的方法,该实例可以包含数据库排序所需的所有信息。我的建议是键和列的映射。这是一种安全的解决方案 开始时,我们以最简单的方式启动地图。为了方便起见,我重载了get(obect key)方法,以便在失败时返回default列(“全名”)。这将防止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;
}
};
}
顺便说一下,您不应该在用户界面中透露列的真实名称,如REST或SOAP等。。。对于攻击者来说,这是一个很大的帮助。您能在这里回答吗?同样的问题:我将替换2。使用“检查值是否在允许值列表中”。如果我没有弄错的话,您可以通过注入ORDER by secretValue之类的内容,甚至是ORDER by secretValue=42之类的表达式来提取大量信息(假设您找到了Sanitarizer允许的表达式)。
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 ..