Error: Only HTTPS URLs are allowed for security reasons.
"); + return; + } + + // Prevent access to internal/private networks using helper method + if (isInternalAddress(host)) { + response.getWriter().println("Error: Access to internal/private network addresses is not allowed.
"); + return; + } + + // Use validated URL + url = ssrfURL; + } catch (Exception e) { + response.getWriter().println("Error: Invalid URL format.
"); + return; + } } URL oracle = new URL(url); @@ -122,6 +184,18 @@ public void UseUrlOpenConnectionhttps(javax.servlet.http.HttpServletRequest requ String UrlToOpen = ssrfURL.replaceFirst("HTTPS://", ""); UrlToOpen = UrlToOpen.replaceFirst("https://", ""); + // Security fix: Validate hostname to prevent SSRF attacks using helper method + if (isInternalAddress(UrlToOpen)) { + response.getWriter().println("Error: Access to internal/private network addresses is not allowed.
"); + return; + } + + // Validate that the hostname doesn't contain suspicious characters + if (!UrlToOpen.matches("[a-zA-Z0-9\\-\\.]+")) { + response.getWriter().println("Error: Invalid hostname format.
"); + return; + } + try { System.out.printf("Opening SSL socket for host : %s\n", UrlToOpen); SSLSocketFactory factory = diff --git a/src/main/java/com/endor/BooksServlet.java b/src/main/java/com/endor/BooksServlet.java index 73168c41..21e86138 100644 --- a/src/main/java/com/endor/BooksServlet.java +++ b/src/main/java/com/endor/BooksServlet.java @@ -439,17 +439,16 @@ private boolean getCustomersUpdateColName(String first, String last, String pass Connection conn = connect(); if (conn == null) return false; - Statement stmt = null; - try { - stmt = conn.createStatement(); - } catch (SQLException e) { - e.printStackTrace(); - } + PreparedStatement stmt = null; try { - String[] cols = {"FIRST", "LAST"}; - String query = String.format("UPDATE CUSTOMERS SET FIRST = '%s' WHERE LAST = '%s' AND PASSWORD = '%s'", first, last, pass); + // Security fix: Use PreparedStatement instead of Statement to prevent SQL injection + String query = "UPDATE CUSTOMERS SET FIRST = ? WHERE LAST = ? AND PASSWORD = ?"; System.out.println("QUERY :" + query); - int ret = stmt.executeUpdate(query, cols); + stmt = conn.prepareStatement(query, new String[]{"FIRST", "LAST"}); + stmt.setString(1, first); + stmt.setString(2, last); + stmt.setString(3, pass); + int ret = stmt.executeUpdate(); // Clean up stmt.close(); } catch (SQLException e) { @@ -470,20 +469,24 @@ private boolean executeSQLWithColIndex(String methodName, String first, String l Connection conn = connect(); if (conn == null) return false; - Statement stmt = null; - try { - stmt = conn.createStatement(); - } catch (SQLException e) { - e.printStackTrace(); - } + PreparedStatement stmt = null; try { + // Security fix: Use PreparedStatement to prevent SQL injection int[] cols = {1, 2}; - String query = String.format("UPDATE CUSTOMERS SET FIRST = '%s' WHERE LAST = '%s' AND PASSWORD = '%s'", first, last, pass); + String query = "UPDATE CUSTOMERS SET FIRST = ? WHERE LAST = ? AND PASSWORD = ?"; System.out.println("QUERY :" + query); if (methodName.equalsIgnoreCase("execute")) { - boolean ret = stmt.execute(query, cols); + stmt = conn.prepareStatement(query, cols); + stmt.setString(1, first); + stmt.setString(2, last); + stmt.setString(3, pass); + boolean ret = stmt.execute(); } else if (methodName.equalsIgnoreCase("executeUpdate")) { - int ret = stmt.executeUpdate(query, cols); + stmt = conn.prepareStatement(query, cols); + stmt.setString(1, first); + stmt.setString(2, last); + stmt.setString(3, pass); + int ret = stmt.executeUpdate(); } else { System.out.println("Invalid SQL method!"); } @@ -493,7 +496,7 @@ private boolean executeSQLWithColIndex(String methodName, String first, String l return false; } finally { try { - stmt.close(); + if (stmt != null) stmt.close(); conn.close(); } catch (SQLException e) { System.err.println(e.getMessage()); @@ -506,20 +509,24 @@ private boolean executeSQLWithAutogenkeys(String methodName, String first, Strin Connection conn = connect(); if (conn == null) return false; - Statement stmt = null; - try { - stmt = conn.createStatement(); - } catch (SQLException e) { - e.printStackTrace(); - } + PreparedStatement stmt = null; try { + // Security fix: Use PreparedStatement to prevent SQL injection int autogenkeys = Statement.RETURN_GENERATED_KEYS; - String query = String.format("UPDATE CUSTOMERS SET FIRST = '%s' WHERE LAST = '%s' AND PASSWORD = '%s'", first, last, pass); + String query = "UPDATE CUSTOMERS SET FIRST = ? WHERE LAST = ? AND PASSWORD = ?"; System.out.println("QUERY :" + query); if (methodName.equalsIgnoreCase("execute")) { - boolean ret = stmt.execute(query, autogenkeys); + stmt = conn.prepareStatement(query, autogenkeys); + stmt.setString(1, first); + stmt.setString(2, last); + stmt.setString(3, pass); + boolean ret = stmt.execute(); } else if (methodName.equalsIgnoreCase("executeUpdate")) { - int ret = stmt.executeUpdate(query, autogenkeys); + stmt = conn.prepareStatement(query, autogenkeys); + stmt.setString(1, first); + stmt.setString(2, last); + stmt.setString(3, pass); + int ret = stmt.executeUpdate(); } else { System.out.println("Invalid SQL method!"); } @@ -529,7 +536,7 @@ private boolean executeSQLWithAutogenkeys(String methodName, String first, Strin return false; } finally { try { - stmt.close(); + if (stmt != null) stmt.close(); conn.close(); } catch (SQLException e) { System.err.println(e.getMessage()); @@ -582,11 +589,13 @@ public static String insertCustomers(String first, String last, String pass) { // Create database connection conn = DriverManager.getConnection(db, user, password); - // Create and execute statement - Statement stmt = conn.createStatement(); - String sql = "INSERT INTO CUSTOMER VALUES (\'" + first + "\',\'" + last + "\', \'" + pass + "')"; - System.out.println("Adding: " + sql); - stmt.executeQuery(sql); + // Security fix: Use PreparedStatement instead of concatenating values to prevent SQL injection + PreparedStatement stmt = conn.prepareStatement("INSERT INTO CUSTOMER VALUES (?, ?, ?)"); + stmt.setString(1, first); + stmt.setString(2, last); + stmt.setString(3, pass); + System.out.println("Adding customer: " + first + " " + last); + stmt.executeUpdate(); System.out.println("Inserted into Database"); // Clean up @@ -640,15 +649,16 @@ public boolean executeSQLHelper(String methodName, String name, String pass) { try { StringBuffer sbuf = new StringBuffer(); - String query = new String(); - - query = "select FIRST, LAST from CUSTOMERS WHERE LAST=\'" + name + "\' AND PASSWORD= \'" + pass + "\'"; + // Security fix: Use PreparedStatement with parameters to prevent SQL injection + String query = "select FIRST, LAST from CUSTOMERS WHERE LAST=? AND PASSWORD=?"; if (methodName.equalsIgnoreCase("executeQuerySQL")) { System.out.println("QUERY :" + query); - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query); + PreparedStatement stmt = conn.prepareStatement(query); + stmt.setString(1, name); + stmt.setString(2, pass); + ResultSet rs = stmt.executeQuery(); // Loop through the data and print all artist names while (rs.next()) { sbuf.append("Customer Name: " + rs.getString("FIRST") + " " + rs.getString("LAST")); @@ -662,6 +672,8 @@ public boolean executeSQLHelper(String methodName, String name, String pass) { } else if (methodName.equalsIgnoreCase("PreparedStatementEexecuteQuerySQL")) { System.out.println("PreparedStatementQUERY :" + query); PreparedStatement stmt = conn.prepareStatement(query); + stmt.setString(1, name); + stmt.setString(2, pass); ResultSet rs = stmt.executeQuery(); // Loop through the data and print all artist names while (rs.next()) { @@ -674,12 +686,16 @@ public boolean executeSQLHelper(String methodName, String name, String pass) { stmt.close(); rs.close(); } else if (methodName.equalsIgnoreCase("executeSQL")) { - Statement stmt = conn.createStatement(); - retVal = stmt.execute(query); + PreparedStatement stmt = conn.prepareStatement(query); + stmt.setString(1, name); + stmt.setString(2, pass); + retVal = stmt.execute(); stmt.close(); } else if (methodName.equalsIgnoreCase("executeUpdateSQL")) { - Statement stmt = conn.createStatement(); - retVal = stmt.executeUpdate(query) > 0; + PreparedStatement stmt = conn.prepareStatement(query); + stmt.setString(1, name); + stmt.setString(2, pass); + retVal = stmt.executeUpdate() > 0; stmt.close(); } } catch (SQLException e) { @@ -701,49 +717,50 @@ public boolean executeSQLHelper(String methodName, int n, String name, String pa if (conn == null) return false; - // Check for multiple values entry before constructing the query + // Security fix: Parse multiple values for IN clause using PreparedStatement String[] name_values = name.split(","); - String parse_name_values = name_values[0]; - for (int i = 1; i< name_values.length; i++ ) { - parse_name_values += "\',\'" ; - parse_name_values += name_values[i]; - } try { StringBuffer sbuf = new StringBuffer(); - String query; + PreparedStatement stmt = null; - // Check for filter operation + // Check for filter operation with LIKE if(n==2) { - query = "select FIRST, LAST from CUSTOMERS WHERE LAST like \'" + name + "%\' AND PASSWORD= \'" + pass + "\'"; + String query = "select FIRST, LAST from CUSTOMERS WHERE LAST like ? AND PASSWORD= ?"; + System.out.println("QUERY :" + query); + stmt = conn.prepareStatement(query); + stmt.setString(1, name + "%"); + stmt.setString(2, pass); } - // Check for normal query operation + // Check for normal query operation or IN clause else { - if(parse_name_values.contains(",")) { - query = "select FIRST, LAST from CUSTOMERS WHERE LAST IN (\'" + parse_name_values + "\')"; + if(name_values.length > 1) { + // Security fix: Build parameterized query for IN clause + StringBuilder queryBuilder = new StringBuilder("select FIRST, LAST from CUSTOMERS WHERE LAST IN ("); + for (int i = 0; i < name_values.length; i++) { + queryBuilder.append("?"); + if (i < name_values.length - 1) { + queryBuilder.append(","); + } + } + queryBuilder.append(")"); + String query = queryBuilder.toString(); + System.out.println("QUERY :" + query); + stmt = conn.prepareStatement(query); + for (int i = 0; i < name_values.length; i++) { + stmt.setString(i + 1, name_values[i]); + } } else { - query = "select FIRST, LAST from CUSTOMERS WHERE LAST=\'" + parse_name_values + "\' AND PASSWORD= \'" + pass + "\'"; + String query = "select FIRST, LAST from CUSTOMERS WHERE LAST=? AND PASSWORD=?"; + System.out.println("QUERY :" + query); + stmt = conn.prepareStatement(query); + stmt.setString(1, name_values[0]); + stmt.setString(2, pass); } } - System.out.println("QUERY :" + query); - // Check for preparedstatement - if (methodName.equalsIgnoreCase("executeQuerySQL")) { - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query); - // Loop through the data and print all artist names - while (rs.next()) { - sbuf.append("Customer Name: " + rs.getString("FIRST") + " " + rs.getString("LAST")); - System.out.println("Customer Name: " + rs.getString("FIRST") + " " + rs.getString("LAST")); - sbuf.append("Error: Invalid command. Only alphanumeric characters, spaces, hyphens, underscores and dots are allowed.
"); + return; + } + + String[] envArr = null; + if (env != null && !env.isEmpty()) { + envArr = env.split(";"); + // Validate each environment variable + for (String envVar : envArr) { + if (!envVar.matches("[a-zA-Z0-9_]+=.+")) { + out.println("Error: Invalid environment variable format. Use KEY=value format.
"); + return; + } + } + } + + try { + // Use ProcessBuilder for safer command execution with validated inputs + ProcessBuilder pb = new ProcessBuilder(command.split("\\s+")); + if (envArr != null) { + for (String envVar : envArr) { + String[] keyValue = envVar.split("=", 2); + pb.environment().put(keyValue[0], keyValue[1]); + } + } + Process process = pb.start(); + out.println("Warning: Command execution is inherently dangerous and should be avoided in production applications.
"); + out.println("Command executed with validation
"); + } catch (Exception e) { + out.println("Error executing command. Please contact system administrator.
"); + System.err.println("Command execution error: " + e.getMessage()); + } + } } } diff --git a/src/main/java/com/endor/OSCommandServlet.java b/src/main/java/com/endor/OSCommandServlet.java index 2339661e..0f141b4c 100644 --- a/src/main/java/com/endor/OSCommandServlet.java +++ b/src/main/java/com/endor/OSCommandServlet.java @@ -32,7 +32,27 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t out.println(form); String command = request.getParameter("command"); - String find = "find " + command; - Runtime.getRuntime().exec(find); + + // Security fix: Validate and sanitize input to prevent command injection + if (command != null && !command.isEmpty()) { + // Only allow alphanumeric characters, spaces, dots, slashes and hyphens for file paths + if (!command.matches("[a-zA-Z0-9\\s\\-_./]+")) { + out.println("Error: Invalid file path. Only alphanumeric characters, spaces, dots, slashes, hyphens and underscores are allowed.
"); + return; + } + + // Use ProcessBuilder for safer command execution with explicit arguments + try { + ProcessBuilder pb = new ProcessBuilder("find", command); + pb.redirectErrorStream(true); + Process process = pb.start(); + out.println("Warning: Command execution is inherently dangerous and should be avoided in production applications.
"); + out.println("Command executed (with validation)
"); + } catch (Exception e) { + // Security fix: Don't expose detailed error messages to users + out.println("Error executing command. Please contact system administrator.
"); + System.err.println("Command execution error: " + e.getMessage()); + } + } } }