SQL 针对混合漏洞和非漏洞查询数组的注入

SQL Injection for array of mixed vulnerability and non vulnerability queries

以下持久代码存在 SQL 漏洞。 strSetStatement[1]、strSetStatement[2]和strSetStatement[6]是根据genSetStatement方法发送设置参数。这可能是不受信任的数据。我正面临着修复这种简单查询和参数化查询的组合。

SQL注入漏洞代码

    public class SQLInjection{

        public static void main(String[] args) throws SQLException, IOException {

            String[] strSetStatement = new String[6];
            PreparedStatement m_statement;
            String url = "DBURL";
            Connection conenction = DriverManager.getConnection(url, "", "");

            m_statement = conenction.prepareStatement("SET CHARACTER_SET 'UTF8_FTCS'");

            // Setting DB Initial parameters | setting limits for queries 
            String strMatch = "100";
            String strTime = "100";
            String strRank = "2:1";

            genSetStatement(strSetStatement, strMatch, strTime, strRank);

            boolean logQuery = true;

            if (logQuery) {
                for (int i = 0; i <= 7; i++)
                    setlogComment(m_statement, strSetStatement[i]);
            }

        }

        private static void genSetStatement(String[] strSetStatement, String strMatch, String strTime, String strRank) {

            strSetStatement[0] = "SET SHOW_MATCHES 'FALSE';";
            strSetStatement[1] = "SET MAX_SEARCH_ROWS " + strMatch + ";";
            strSetStatement[2] = "SET MAX_EXEC_TIME " + strTime + ";";
            strSetStatement[3] = "SET SERVER_REPORT_TIME " + FTSSearchConst.SERVER_REPORT_TIME + ";";
            strSetStatement[4] = "SET SEARCH_MEMORY_SIZE " + FTSSearchConst.SEARCH_MEMORY_SIZE + ";";
            strSetStatement[5] = "SET THESAURUS_NAME 'FULTEXT';";
            strSetStatement[6] = "SET RELEVANCE_METHOD '" + strRank + "';";

        }

        private static void setlogComment(PreparedStatement stmt, String strSetState) throws SQLException, IOException {


            stmt.executeQuery(strSetState); // SQL injected area
        }

    }

我正在尝试通过添加“?”来执行以下操作在 strSetStatement[] 数组中。并检查查询是否有“?”在 setlogComment 方法中,但如何识别确切的参数并将变量绑定到它?

   strSetStatement[1] = "SET MAX_SEARCH_ROWS " + ? + ";";
    private static void setlogComment(PreparedStatement stmt, String strSetState) throws SQLException, IOException {

            if(strSetState.contains("?")){
                stmt.setString(1, arg1);            
            }
            stmt.executeQuery(strSetState); 
        }

警告:我不确定您要 SQL version/dialect 这些查询 运行,这应该是一些全文搜索扩展。

以下代码的目的是消除在您的代码片段中检测到的问题,但是,如果出现任何错误,您可能需要适当地更新它。

  1. 代码已被重新​​处理以去除冗余 methods/variables。
  2. 索引 1、2、6 处的查询已更新为包含 ? 外部参数。
  3. matchRowsexecTime 参数的类型已更改为 int
  4. 已设置 PreparedStatement 的参数并在主循环内执行查询。
public class SQLInjection {

    public static void main(String[] args) throws SQLException, IOException {

        String[] strSetStatement = {
            "SET SHOW_MATCHES 'FALSE';",
            "SET MAX_SEARCH_ROWS ?;",
            "SET MAX_EXEC_TIME ?;",
            "SET SERVER_REPORT_TIME " + FTSSearchConst.SERVER_REPORT_TIME + ";",
            "SET SEARCH_MEMORY_SIZE " + FTSSearchConst.SEARCH_MEMORY_SIZE + ";",
            "SET THESAURUS_NAME 'FULTEXT';",
            "SET RELEVANCE_METHOD ?;"
        };

        Connection connection = DriverManager.getConnection("DBURL", "", "");

        PreparedStatement m_statement = connection.prepareStatement("SET CHARACTER_SET 'UTF8_FTCS'");
        m_statement.executeQuery();

        // Setting DB Initial parameters | setting limits for queries 
        int matchRows   = 100;
        int execTimeSec = 100;
        String strRank  = "2:1";

        boolean logQuery = true;

        if (logQuery) {
            for (int i = 0; i < strSetStatement.length; i++) {
                PreparedStatement stmt = connection.prepareStatement(strSetStatement[i]);
                if (i == 1) {
                    stmt.setInt(1, matchRows);
                } else if (i == 2) {
                    stmt.setInt(1, execTimeSec);
                } else if (i == 6) {
                    stmt.setString(1, strRank);
                }
                stmt.executeQuery();
            }
        }
    }
}