From a32c16eb7edddbb1913ad50bf9a88692947af53a Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 06:02:17 +0000 Subject: [PATCH] Fix SQL Injection vulnerability in MainController - Added `execUpdate(String query, Object... params)` to `DatabaseHandler` to support parameterized queries using `PreparedStatement`. - Updated `MainController.loadRenewOp`, `MainController.loadIssueOperation`, and `MainController.loadSubmissionOp` to use `execUpdate` instead of string concatenation. - This prevents SQL injection attacks where user input (book ID, member ID) is directly embedded in SQL statements. Co-authored-by: G30RG3-GJ <203693057+G30RG3-GJ@users.noreply.github.com> --- .../assistant/database/DatabaseHandler.java | 13 +++++++++++++ .../assistant/ui/main/MainController.java | 18 ++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/library/assistant/database/DatabaseHandler.java b/src/library/assistant/database/DatabaseHandler.java index e9c4f53..dd82529 100644 --- a/src/library/assistant/database/DatabaseHandler.java +++ b/src/library/assistant/database/DatabaseHandler.java @@ -138,6 +138,19 @@ public boolean execAction(String qu) { } } + public boolean execUpdate(String query, Object... params) { + try (PreparedStatement statement = conn.prepareStatement(query)) { + for (int i = 0; i < params.length; i++) { + statement.setObject(i + 1, params[i]); + } + statement.executeUpdate(); + return true; + } catch (SQLException ex) { + LOGGER.log(Level.ERROR, "{}", ex); + return false; + } + } + public boolean deleteBook(Book book) { try { String deleteStatement = "DELETE FROM BOOK WHERE ID = ?"; diff --git a/src/library/assistant/ui/main/MainController.java b/src/library/assistant/ui/main/MainController.java index 50b0fff..db5c501 100644 --- a/src/library/assistant/ui/main/MainController.java +++ b/src/library/assistant/ui/main/MainController.java @@ -236,13 +236,11 @@ private void loadIssueOperation(ActionEvent event) { JFXButton yesButton = new JFXButton("YES"); yesButton.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent event1) -> { - String str = "INSERT INTO ISSUE(memberID,bookID) VALUES (" - + "'" + memberID + "'," - + "'" + bookID + "')"; - String str2 = "UPDATE BOOK SET isAvail = false WHERE id = '" + bookID + "'"; + String str = "INSERT INTO ISSUE(memberID,bookID) VALUES (?, ?)"; + String str2 = "UPDATE BOOK SET isAvail = false WHERE id = ?"; System.out.println(str + " and " + str2); - if (databaseHandler.execAction(str) && databaseHandler.execAction(str2)) { + if (databaseHandler.execUpdate(str, memberID, bookID) && databaseHandler.execUpdate(str2, bookID)) { JFXButton button = new JFXButton("Done!"); button.setOnAction((actionEvent) -> { bookIDInput.requestFocus(); @@ -330,10 +328,10 @@ private void loadSubmissionOp(ActionEvent event) { JFXButton yesButton = new JFXButton("YES, Please"); yesButton.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent ev) -> { String id = bookID.getText(); - String ac1 = "DELETE FROM ISSUE WHERE BOOKID = '" + id + "'"; - String ac2 = "UPDATE BOOK SET ISAVAIL = TRUE WHERE ID = '" + id + "'"; + String ac1 = "DELETE FROM ISSUE WHERE BOOKID = ?"; + String ac2 = "UPDATE BOOK SET ISAVAIL = TRUE WHERE ID = ?"; - if (databaseHandler.execAction(ac1) && databaseHandler.execAction(ac2)) { + if (databaseHandler.execUpdate(ac1, id) && databaseHandler.execUpdate(ac2, id)) { JFXButton btn = new JFXButton("Done!"); btn.setOnAction((actionEvent) -> { bookID.requestFocus(); @@ -364,9 +362,9 @@ private void loadRenewOp(ActionEvent event) { } JFXButton yesButton = new JFXButton("YES, Please"); yesButton.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent event1) -> { - String ac = "UPDATE ISSUE SET issueTime = CURRENT_TIMESTAMP, renew_count = renew_count+1 WHERE BOOKID = '" + bookID.getText() + "'"; + String ac = "UPDATE ISSUE SET issueTime = CURRENT_TIMESTAMP, renew_count = renew_count+1 WHERE BOOKID = ?"; System.out.println(ac); - if (databaseHandler.execAction(ac)) { + if (databaseHandler.execUpdate(ac, bookID.getText())) { JFXButton btn = new JFXButton("Alright!"); AlertMaker.showMaterialDialog(rootPane, rootAnchorPane, Arrays.asList(btn), "Book Has Been Renewed", null); disableEnableControls(false);