动态SQL中带有预准备语句的SQL注入错误

时间:2018-11-26 21:53:08

标签: dynamic-sql prepared-statement sql-injection

在我的应用程序中,我们从UI收集一些用户输入,并基于这些值生成具有不同“ Where”条件的动态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 个答案:

答案 0 :(得分:0)

您如何得出这样的结论:您在此代码中进行了SQL注入?那将有助于清理。 无论如何,查看您的代码,看来strSerialNumberLogicstrCreationDateLogic都是来自外部源的变量,并且以允许注入SQL的方式加以隐喻。如果此外部源是用户,则可以执行SQL注入。如果不是,那么这可能是误报。无论如何,我都会通过更改逻辑变量将其转换为Enums来改进代码。