准备语句中动态where条件的java SQL注入
在我的应用程序中,我们从UI收集一些用户输入,并根据这些值生成具有不同“Where”条件的动态SQL来查询数据。我们发现这段代码有一些SQL注入缺陷
我无法重新安排此代码以防止该漏洞。任何建议都会有帮助
我的应用程序需要四个输入参数
- 序列号-可以是一个或无,也可以是两个值 2.创建日期-可以是,一个或无,或两个值
- ReportTypeNumber-可以是一个、一个或多个
- reportTitleNames可以是一个、一个或多个
基于这些输入值,我正在为准备好的语句构造动态“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();
}
# 1 楼答案
处理
strSerialNumberLogic
和strCreationDateLogic
的方式允许SQL注入攻击。与其直接将它们的值附加到where子句,不如使用条件逻辑来确定要使用的正确条件:虽然在附加str[SerialNumber | CreationDate]逻辑以避免注入攻击之前,您可以简单地检查以确保其值有效,但您的代码检查器可能仍会抛出错误,因此最好附加字符串文字而不是变量