在我的应用程序中,我们从UI收集一些用户输入,并基于这些值生成具有不同“where”条件的动态SQL,以查询数据。发现这段代码有一些SQL注入缺陷。
基于这些输入值,我正在为准备好的语句构造动态的“where”条件。此SQL存在问题。请帮助我重写它来修复SQL注入缺陷。
下面是构造动态SQL的方法。
public void filter(String strSerialNumberLogic, String strSerialNumber1,
String strSerialNumber2, String strCreationDateLogic,
long lngCreationDate1, long lngCreationDate2,
String strTypeNumbers, String strTitles, long lngLoc)
throws SQLException, ClassNotFoundException {
StringBuffer strWhere = new StringBuffer();
List paramList = new ArrayList();
String arrTypeNumbers[];
String arrTitles[];
int i;
boolean bolHit;
if (!strTypeNumbers.equals("") || !strTitles.equals("")) {
arrTypeNumbers = strTypeNumbers.split(",");
arrTitles = strTitles.split(",");
bolHit = false;
strWhere.append("(");
for (i = 0; i < arrTypeNumbers.length; i++) {
if (arrTypeNumbers[i].length() > 0) {
if (bolHit) {
strWhere.append(" OR ");
} else {
bolHit = true;
}
strWhere.append(" REPORT_NUMBER = ?");
paramList.add(arrTypeNumbers[i]);
}
}
for (i = 0; i < arrTitles.length; i++) {
if (arrTitles[i].length() > 0) {
if (bolHit) {
strWhere.append(" OR ");
} else {
bolHit = true;
}
strWhere.append(" REPORT_NAME = ?");
paramList.add(arrTitles[i]);
}
}
strWhere.append(") ");
}
if (!strSerialNumber1.equals("")) {
if (!strWhere.equals("")) {
strWhere.append(" AND ");
}
strWhere.append(" REPORT_FILE_NO " + strSerialNumberLogic + " ? ");
paramList.add(strSerialNumber1);
if (strSerialNumberLogic.equals("between")) {
strWhere.append(" AND ? ");
paramList.add(strSerialNumber2);
}
}
if (lngCreationDate1 != 0) {
if (!strWhere.equals("")) {
strWhere.append(" AND ");
}
strWhere.append(" REPORT_CREATION_DATE " + strCreationDateLogic + " ? ");
paramList.add(Long.toString(lngCreationDate1));
if (strCreationDateLogic.equals("between")) {
strWhere.append(" AND ? ");
paramList.add(Long.toString(lngCreationDate2));
}
}
if (lngLoc != 0) {
if (!strWhere.equals("")) {
strWhere.append(" AND ");
}
strWhere.append(" REPORT_FILE_LOCATION = ? ");
paramList.add(Long.toString(lngLoc));
}
String finalQuery = "";
if (!strWhere.equals("")) {
finalQuery = "WHERE " + strWhere.toString();
}
String strSQL = "SELECT * " + "FROM D990800 "
+ "LEFT JOIN D990400 ON REPORT_SYSTEM_ID ||" + " REPORT_NO = REPORT_NUMBER " + finalQuery
+ "ORDER BY REPORT_FILE_NO ASC";
System.out.println("strSQL:" + strSQL );
System.out.println("paramList:" + paramList );
Connection conn = ConnectionFactory.instance().getConnection();
PreparedStatement preparedStatement = null;
preparedStatement = conn.prepareStatement(strSQL);
for (int index = 0; index < paramList.size(); index++) {
String param = (String) paramList.get(index);
if (isParsableInt(param)) {
preparedStatement.setInt(index+1, Integer.parseInt(param));
} else {
preparedStatement.setString(index+1, param);
}
}
ResultSet rsReports = preparedStatement.executeQuery();
buildCollection(rsReports);
rsReports.close();
preparedStatement.close();
conn.close();
}
处理StrSerialNumberLogic
和StrCreationDateLogic
的方式允许SQL注入攻击。您应该使用条件逻辑来确定要使用的正确条件,而不是直接将它们的值追加到where子句中:
strWhere.append(" REPORT_FILE_NO ");
switch (strSerialNumberLogic) {
case "=":
strWhere.append("= ? ");
paramList.add(strSerialNumber1);
break;
case "!=":
case "<>":
strWhere.append("!= ? ");
paramList.add(strSerialNumber1);
break;
case "<":
strWhere.append("< ? ");
paramList.add(strSerialNumber1);
break;
case "<=":
strWhere.append("<= ? ");
paramList.add(strSerialNumber1);
break;
case ">":
strWhere.append("> ? ");
paramList.add(strSerialNumber1);
break;
case ">=":
strWhere.append(">= ? ");
paramList.add(strSerialNumber1);
break;
case "between":
strWhere.append("between ? and ? ");
paramList.add(strSerialNumber1);
paramList.add(strSerialNumber2);
break;
case "not between":
strWhere.append("not between ? and ? ");
paramList.add(strSerialNumber1);
paramList.add(strSerialNumber2);
break;
case "is null":
strWhere.append("is null ");
break;
case "is not null":
strWhere.append("is not null ");
break;
}
尽管您可以简单地检查以确保STR[SerialNumberCreationDate]逻辑的值在追加之前有效,以避免注入攻击,但代码检查器仍然可能引发错误,因此最好追加字符串文本而不是变量。
我正试图为我的mysqli连接编写一个非常小的抽象层,但遇到了一个问题。由于我维护的是较旧的代码,我需要从我的查询中获得一个关联数组,因为这是代码设置的方式,因此一旦这样做了,我的工作就少了...这个函数可以处理各种查询(不仅仅是选择)... 我写的函数是这样的: 添加的问题 仅仅为了保留关联数组返回,这样的开销是不是太大了?是否应该改用?
问题内容: 我有以下查询: 这返回 我将如何使它工作?说参数是否为“有效”,则返回具有以下条件的记录? 问题答案: 您可以使用另一种方法:
问题内容: 我有一个执行查询的SQL Server 2005存储过程。该存储过程采用三个参数。参数如下: @StateID为int, @ CountyID为int, @ CityID为int 这些参数用于查询客户列表。如果参数值不为null,我基本上想做一个“ AND”。但是,我目前无法执行if- else。如果参数值不为null,如何添加这些子句。换一种说法: 问题答案: 加上一些OR语句: 对
问题内容: 我正在创建一个需要条件子句的SQL查询。 应该是这样的: 上面的查询不起作用。这是不正确的语法,还是我不知道的另一种方式来做到这一点? 我不想使用动态SQL,是否还有其他方法,还是必须使用类似的解决方法,例如对不同的子句使用和使用相同的查询? 问题答案: 试试这个 您可以在此处阅读有关条件WHERE的更多信息。
根据给定的表数据,第三行中的非空字段是“field1”和“field3”。因此WHERE子句将是: 我如何编写一个具有动态WHERE子句的通用SQL来满足这个需求?
我对where条件、order by和limit有一个查询。我使用准备好的语句来设置where条件和限制。当前,我使用字符串append作为order,从而导致SQL注入漏洞。