sqli error

Confluence User - 07 Dec, 2024

String sql = "SELECT c_process_def_id, c_processid FROM app_fd_bill WHERE c_bill_number = ?";
                stmt = con.prepareStatement(sql);
                stmt.setString(1, billNo);
                rs = stmt.executeQuery();


I need to get values of c_process_def_id, c_processid because these are needed for 
assignmentReassign(processDefId, processId, activityId, username, user);
where
c_process_def_id = Accounts#70#bill_management
and  
processId= 2602_Accounts_bill_management.
stmt.setString(1, billNo); billNo=2

I'm doing this outside process, so I'm storing the values in the database instance, but when I execute these values i get error

ERROR 06 Dec 2024 12:12:31 org.joget.apps.app.service.SqlFilterAspect - Possible SQLi from IP:0:0:0:0:0:0:0:1. Query string is _action=submit&OWASP_CSRFTOKEN=D8YK-063H-WJGC-PRLX-Y2PJ-EAC7-DLK0-THNZ
4794
java.sql.SQLException: Possible SQLi from IP:0:0:0:0:0:0:0:1. Query string is _action=submit&OWASP_CSRFTOKEN=D8YK-063H-WJGC-PRLX-Y2PJ-EAC7-DLK0-THNZ

sql;sqlinjection

6


08 Dec, 2024
confluenceUser
confluenceUser

Hi, Can you please share the full beanshell code? 

08 Dec, 2024
confluenceUser
confluenceUser

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.sql.DataSource;
import org.joget.apps.app.service.AppUtil;
import org.joget.commons.util.LogUtil;
import org.joget.apps.form.model.FormRow;
import org.joget.workflow.model.service.WorkflowManager;

// Retrieve form values
FormRow row = rows.get(0);
String billNoS = row.getProperty("bill_no_s_r1"); // Format: value1;value2;...
String dhList = row.getProperty("dh_list_r1");   // Format: value1;value2;...


// Parse bill numbers and DH list into arrays
if (!billNoS.contains(";")) {
    billNoS += ";";
}
if (!dhList.contains(";")) {
    dhList += ";";
}
// Sanitize billNoS and dhList by removing unexpected characters
billNoS = billNoS.replaceAll("[^a-zA-Z0-9;]", "").trim();
dhList = dhList.replaceAll("[^a-zA-Z0-9;]", "").trim();


String[] billNumbers = billNoS.split(";");
String[] dhUsers = dhList.split(";");

// Database connection variables
Connection con = null;
PreparedStatement stmt = null;
PreparedStatement updateStmt = null;
ResultSet rs = null;

try {
    // Get data source and establish connection
    DataSource ds = (DataSource) AppUtil.getApplicationContext().getBean("setupDataSource");
    con = ds.getConnection();

    if (!con.isClosed()) {
        LogUtil.info("DB Connection", "Connected successfully.");

        // Split bills among DH users using arrays
        int numBills = billNumbers.length;
        int numUsers = dhUsers.length;
        String[][] userBillGroups = new String[numUsers][]; // Array to hold bill groups for each user

        // Initialize each user's bill group
        for (int i = 0; i < numUsers; i++) {
            userBillGroups[i] = new String[(numBills + numUsers - 1) / numUsers]; // Distribute bills evenly
        }

        // Assign bills to users in a round-robin fashion
        int[] groupSizes = new int[numUsers]; // Track the number of bills per user
        for (int i = 0; i < numBills; i++) {
            int userIndex = i % numUsers;
            userBillGroups[userIndex][groupSizes[userIndex]++] = billNumbers[i].trim();
        }

        // Iterate through each user and assign their respective bills
        for (int i = 0; i < numUsers; i++) {
            String user = dhUsers[i].trim();

            for (int j = 0; j < groupSizes[i]; j++) {
                String billNo = userBillGroups[i][j].trim();
                billNo = billNo.replaceAll("[^a-zA-Z0-9]", "").trim();
                LogUtil.info("conn",billNo);

                // Query to fetch processDefId and processId for the given bill number
                String sql = "SELECT c_process_def_id, c_processid FROM app_fd_bill WHERE c_bill_number = ?";
                stmt = con.prepareStatement(sql);
                stmt.setString(1, billNo);
                rs = stmt.executeQuery();

                if (rs.next()) {
                    String processDefId = rs.getString("c_process_def_id");
                    String processId = rs.getString("c_processid");

                    // Reassign task to the current user
                    String activityId = "Precheck DH"; // Constant activity ID
                    String username = null;           // Set username to null
                    WorkflowManager workflowManager = (WorkflowManager) AppUtil.getApplicationContext().getBean("workflowManager");
                    workflowManager.assignmentReassign(processDefId, processId, activityId, username, user);
                    LogUtil.info("Assignment Reassign", 
                        "Reassigned activity '" + activityId + "' for ProcessDefId: " + processDefId + 
                        ", ProcessId: " + processId + " to user: " + user);

                    // Update c_token_status in the database
                    String updateSql = "UPDATE app_fd_bill SET c_token_status = 'dh_wise_allocated' WHERE c_bill_number = ?";
                    updateStmt = con.prepareStatement(updateSql);
                    updateStmt.setString(1, billNo);
                    int rowsUpdated = updateStmt.executeUpdate();

                    LogUtil.info("DB Update", "Updated c_token_status for bill number " + billNo + ". Rows affected: " + rowsUpdated);
                } else {
                    LogUtil.warn("DB Query", "No process details found for bill number: " + billNo);
                }

                // Close result set and statement for each iteration
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (updateStmt != null) updateStmt.close();
            }
        }
    }
} catch (Exception e) {
    LogUtil.error("Beanshell Script", e, "Error while reassigning tasks and updating status.");
} finally {
    // Close database resources
    try {
        if (rs != null) rs.close();
        if (stmt != null) stmt.close();
        if (updateStmt != null) updateStmt.close();
        if (con != null) con.close();
    } catch (Exception e) {
        LogUtil.error("DB Close", e, "Error while closing database resources.");
    }
}

09 Dec, 2024
confluenceUser
confluenceUser

Could you tell us where this beanshell getting executed? Post Form submission tool?

09 Dec, 2024
confluenceUser
confluenceUser

the code is placed in the 'section' (where we place elements) → properties → save data,  of the form 

09 Dec, 2024
confluenceUser
confluenceUser

Hi Sakthi, If you are executing your code inside a form store binder, you should wrap your code within a function that takes the necessary injected variables as parameters and returns the FormRowSet as the return type. In the above shared code i could not see any results being returned. 

09 Dec, 2024
confluenceUser
confluenceUser

Load & Store Form Grid Data Using Bean Shell Form Binder

for jdbc store type we don't need to return formrowset ryt?


RELATED QUESTIONS

Your answer


To answer a question you'll need an account.

Print