From b568c23097c4cda257ed82de614280d4bdac9069 Mon Sep 17 00:00:00 2001 From: snow Date: Mon, 10 Aug 2026 15:50:53 -0700 Subject: [PATCH] Fix error SQL injection level 4 Signed-off-by: snow --- .../ErrorBasedSQLInjectionVulnerability.java | 16 ++++++----- ...rorBasedSQLInjectionVulnerabilityTest.java | 28 ++++++++++++++++--- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/ErrorBasedSQLInjectionVulnerability.java b/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/ErrorBasedSQLInjectionVulnerability.java index 507adfde3..7d089a895 100644 --- a/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/ErrorBasedSQLInjectionVulnerability.java +++ b/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/ErrorBasedSQLInjectionVulnerability.java @@ -200,16 +200,16 @@ public ResponseEntity doesCarInformationExistsLevel3( htmlTemplate = "LEVEL_1/SQLInjection_Level1") public ResponseEntity doesCarInformationExistsLevel4( @RequestParam Map queryParams) { - final String id = queryParams.get(Constants.ID).replaceAll("'", ""); + final String id = queryParams.get(Constants.ID); BodyBuilder bodyBuilder = ResponseEntity.status(HttpStatus.OK); bodyBuilder.body(ErrorBasedSQLInjectionVulnerability.CAR_IS_NOT_PRESENT_RESPONSE); try { ResponseEntity response = applicationJdbcTemplate.query( - (conn) -> - conn.prepareStatement( - "select * from cars where id='" + id + "'"), - (ps) -> {}, + (conn) -> conn.prepareStatement("select * from cars where id=?"), + (prepareStatement) -> { + prepareStatement.setString(1, id); + }, (rs) -> { if (rs.next()) { CarInformation carInformation = new CarInformation(); @@ -225,7 +225,8 @@ public ResponseEntity doesCarInformationExistsLevel4( } catch (JsonProcessingException e) { LOGGER.error("Following error occurred", e); return bodyBuilder.body( - GENERIC_EXCEPTION_RESPONSE_FUNCTION.apply(e)); + ErrorBasedSQLInjectionVulnerability + .CAR_IS_NOT_PRESENT_RESPONSE); } } else { return bodyBuilder.body( @@ -237,7 +238,8 @@ public ResponseEntity doesCarInformationExistsLevel4( return response; } catch (Exception ex) { LOGGER.error("Following error occurred", ex); - return bodyBuilder.body(GENERIC_EXCEPTION_RESPONSE_FUNCTION.apply(ex)); + return bodyBuilder.body( + ErrorBasedSQLInjectionVulnerability.CAR_IS_NOT_PRESENT_RESPONSE); } } diff --git a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/ErrorBasedSQLInjectionVulnerabilityTest.java b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/ErrorBasedSQLInjectionVulnerabilityTest.java index a665b7540..c7ef946ad 100644 --- a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/ErrorBasedSQLInjectionVulnerabilityTest.java +++ b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/ErrorBasedSQLInjectionVulnerabilityTest.java @@ -8,11 +8,14 @@ import static org.mockito.Mockito.verify; import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.sasanlabs.vulnerability.utils.Constants; import org.springframework.http.HttpStatus; @@ -85,10 +88,10 @@ void doesCarInformationExistsLevel3_ExpectParamEscaped() throws IOException { } @Test - void doesCarInformationExistsLevel4_ExpectValidResponse() { + void doesCarInformationExistsLevel4_ExpectValidResponse() throws Exception { // Arrange Map queryParams = new HashMap<>(); - queryParams.put(Constants.ID, "1'"); + queryParams.put(Constants.ID, "#"); // Mock the response entity ResponseEntity mockResponseEntity = @@ -107,11 +110,28 @@ void doesCarInformationExistsLevel4_ExpectValidResponse() { // Assert assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals("Sample response", response.getBody()); + + ArgumentCaptor creatorCaptor = + ArgumentCaptor.forClass(PreparedStatementCreator.class); + ArgumentCaptor setterCaptor = + ArgumentCaptor.forClass(PreparedStatementSetter.class); verify(template) .query( - Mockito.any(PreparedStatementCreator.class), - Mockito.any(PreparedStatementSetter.class), + creatorCaptor.capture(), + setterCaptor.capture(), Mockito.any(ResultSetExtractor.class)); + + Connection connection = Mockito.mock(Connection.class); + PreparedStatement preparedStatement = Mockito.mock(PreparedStatement.class); + doReturn(preparedStatement) + .when(connection) + .prepareStatement("select * from cars where id=?"); + + creatorCaptor.getValue().createPreparedStatement(connection); + setterCaptor.getValue().setValues(preparedStatement); + + verify(connection).prepareStatement("select * from cars where id=?"); + verify(preparedStatement).setString(1, "#"); } @Test