[英]SQL injection for Dynamic where conditions in prepared statement
在我的應用程序中,我們從UI收集一些用戶輸入,並基於這些值生成具有不同“ Where”條件的動態SQL,以查詢數據。 發現該代碼段具有一些SQL注入缺陷。
我無法重新排列此代碼以防止出現這種情況。 任何建議都會有所幫助。
我的應用程序有四個輸入參數,
基於這些輸入值,我正在為准備好的語句構建動態“哪里”條件。 此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 [SerialNumber | CreationDate] Logic值之前先進行檢查以確保其值有效,以避免注入攻擊,但您的代碼檢查器可能仍會引發錯誤,因此最好附加字符串文字而不是變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.