From e4362787ca10fba084d2ab8d9237821eab2f1ff3 Mon Sep 17 00:00:00 2001 From: Paul Weber Date: Wed, 31 May 2023 22:16:27 +0200 Subject: [PATCH 1/6] Add first version of unit tests for union based sql injection vulnerability --- ...ionBasedSQLInjectionVulnerabilityTest.java | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java diff --git a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java new file mode 100644 index 00000000..621b6909 --- /dev/null +++ b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java @@ -0,0 +1,156 @@ +package org.sasanlabs.service.vulnerability.sqlInjection; + + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.ResultSetExtractor; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +public class UnionBasedSQLInjectionVulnerabilityTest { + + private UnionBasedSQLInjectionVulnerability unionBasedSQLInjectionVulnerability; + private JdbcTemplate template; + + @BeforeEach + void setUp() throws IOException { + template = Mockito.spy(new JdbcTemplate()); + + doReturn(null) + .when(template) + .query(anyString(), (ResultSetExtractor) any()); + + unionBasedSQLInjectionVulnerability = Mockito.spy(new UnionBasedSQLInjectionVulnerability(template)); + } + + @Test + public void getCarInformationLevel1_ExpectParamInjected() throws IOException { + // Act + Map params = new HashMap(); + params.put("id", "1 UNION SELECT * FROM cars;"); + unionBasedSQLInjectionVulnerability.getCarInformationLevel1(params); + + // Assert + verify(template).query(eq("select * from cars where id=1 UNION SELECT * FROM cars;"), (ResultSetExtractor) any()); + } + + @Test + public void getCarInformationLevel2_ExpectParamInjected() throws IOException { + // Act + Map params = new HashMap(); + params.put("id", "1' UNION SELECT * FROM cars; --"); + unionBasedSQLInjectionVulnerability.getCarInformationLevel2(params); + + // Assert + verify(template).query(eq("select * from cars where id='1' UNION SELECT * FROM cars; --'"), (ResultSetExtractor) any()); + } + +// private JdbcTemplate applicationJdbcTemplate; +// +// public UnionBasedSQLInjectionVulnerabilityTest( +// @Qualifier("applicationJdbcTemplate") JdbcTemplate applicationJdbcTemplate) { +// this.applicationJdbcTemplate = applicationJdbcTemplate; +// } +// +// @AttackVector( +// vulnerabilityExposed = VulnerabilityType.UNION_BASED_SQL_INJECTION, +// description = "UNION_SQL_INJECTION_URL_PARAM_APPENDED_DIRECTLY_TO_QUERY", +// payload = "UNION_BASED_SQL_INJECTION_PAYLOAD_LEVEL_1") +// @VulnerableAppRequestMapping( +// value = LevelConstants.LEVEL_1, +// htmlTemplate = "LEVEL_1/SQLInjection_Level1") +// public ResponseEntity getCarInformationLevel1( +// @RequestParam Map queryParams) { +// String id = queryParams.get("id"); +// return applicationJdbcTemplate.query( +// "select * from cars where id=" + id, +// (rs) -> { +// CarInformation carInformation = new CarInformation(); +// if (rs.next()) { +// carInformation.setId(rs.getInt(1)); +// carInformation.setName(rs.getString(2)); +// carInformation.setImagePath(rs.getString(3)); +// } +// return new ResponseEntity(carInformation, HttpStatus.OK); +// }); +// } +// +// @AttackVector( +// vulnerabilityExposed = VulnerabilityType.UNION_BASED_SQL_INJECTION, +// description = +// "UNION_SQL_INJECTION_URL_PARAM_WRAPPED_WITH_SINGLE_QUOTE_APPENDED_TO_QUERY", +// payload = "UNION_BASED_SQL_INJECTION_PAYLOAD_LEVEL_2") +// @VulnerableAppRequestMapping( +// value = LevelConstants.LEVEL_2, +// htmlTemplate = "LEVEL_1/SQLInjection_Level1") +// public ResponseEntity getCarInformationLevel2( +// @RequestParam Map queryParams) { +// String id = queryParams.get("id"); +// CarInformation carInformation = new CarInformation(); +// return applicationJdbcTemplate.query( +// "select * from cars where id='" + id + "'", +// (rs) -> { +// if (rs.next()) { +// carInformation.setId(rs.getInt(1)); +// carInformation.setName(rs.getString(2)); +// carInformation.setImagePath(rs.getString(3)); +// } +// return new ResponseEntity(carInformation, HttpStatus.OK); +// }); +// } +// +// @AttackVector( +// vulnerabilityExposed = VulnerabilityType.UNION_BASED_SQL_INJECTION, +// description = +// "UNION_SQL_INJECTION_URL_PARAM_REMOVES_SINGLE_QUOTE_WITH_SINGLE_QUOTE_APPENDED_TO_QUERY") +// @VulnerableAppRequestMapping( +// value = LevelConstants.LEVEL_3, +// variant = Variant.SECURE, +// htmlTemplate = "LEVEL_1/SQLInjection_Level1") +// public ResponseEntity getCarInformationLevel3( +// @RequestParam Map queryParams) { +// String id = queryParams.get("id").replaceAll("'", ""); +// return applicationJdbcTemplate.query( +// "select * from cars where id='" + id + "'", +// (rs) -> { +// CarInformation carInformation = new CarInformation(); +// if (rs.next()) { +// carInformation.setId(rs.getInt(1)); +// carInformation.setName(rs.getString(2)); +// carInformation.setImagePath(rs.getString(3)); +// } +// return new ResponseEntity(carInformation, HttpStatus.OK); +// }); +// } +// +// @VulnerableAppRequestMapping( +// value = LevelConstants.LEVEL_4, +// variant = Variant.SECURE, +// htmlTemplate = "LEVEL_1/SQLInjection_Level1") +// public ResponseEntity getCarInformationLevel4( +// @RequestParam Map queryParams) { +// String id = queryParams.get("id"); +// +// return applicationJdbcTemplate.query( +// "select * from cars where id=?", +// (prepareStatement) -> { +// prepareStatement.setString(1, id); +// }, +// (rs) -> { +// CarInformation carInformation = new CarInformation(); +// if (rs.next()) { +// carInformation.setId(rs.getInt(1)); +// carInformation.setName(rs.getString(2)); +// carInformation.setImagePath(rs.getString(3)); +// } +// return new ResponseEntity(carInformation, HttpStatus.OK); +// }); +// } +} From d3b8f305603105c472560bc4f11efc27a1df638b Mon Sep 17 00:00:00 2001 From: Paul Weber Date: Tue, 12 Sep 2023 17:05:11 +0200 Subject: [PATCH 2/6] Added tests for the UnionBasedSQLInjction Added some tests and also cleaned up the controller a little bit by extracting result handling code to helper function. --- .../UnionBasedSQLInjectionVulnerability.java | 76 +++++++------------ ...ionBasedSQLInjectionVulnerabilityTest.java | 42 +++++++++- 2 files changed, 65 insertions(+), 53 deletions(-) diff --git a/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerability.java b/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerability.java index 749258ba..27371748 100644 --- a/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerability.java +++ b/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerability.java @@ -1,5 +1,7 @@ package org.sasanlabs.service.vulnerability.sqlInjection; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.Map; import org.sasanlabs.internal.utility.LevelConstants; import org.sasanlabs.internal.utility.Variant; @@ -25,10 +27,10 @@ value = "UnionBasedSQLInjectionVulnerability") public class UnionBasedSQLInjectionVulnerability { - private JdbcTemplate applicationJdbcTemplate; + private final JdbcTemplate applicationJdbcTemplate; public UnionBasedSQLInjectionVulnerability( - @Qualifier("applicationJdbcTemplate") JdbcTemplate applicationJdbcTemplate) { + @Qualifier("applicationJdbcTemplate") final JdbcTemplate applicationJdbcTemplate) { this.applicationJdbcTemplate = applicationJdbcTemplate; } @@ -40,19 +42,11 @@ public UnionBasedSQLInjectionVulnerability( value = LevelConstants.LEVEL_1, htmlTemplate = "LEVEL_1/SQLInjection_Level1") public ResponseEntity getCarInformationLevel1( - @RequestParam Map queryParams) { - String id = queryParams.get("id"); + @RequestParam final Map queryParams) { + final String id = queryParams.get("id"); return applicationJdbcTemplate.query( "select * from cars where id=" + id, - (rs) -> { - CarInformation carInformation = new CarInformation(); - if (rs.next()) { - carInformation.setId(rs.getInt(1)); - carInformation.setName(rs.getString(2)); - carInformation.setImagePath(rs.getString(3)); - } - return new ResponseEntity(carInformation, HttpStatus.OK); - }); + this::resultSetToResponse); } @AttackVector( @@ -64,19 +58,11 @@ public ResponseEntity getCarInformationLevel1( value = LevelConstants.LEVEL_2, htmlTemplate = "LEVEL_1/SQLInjection_Level1") public ResponseEntity getCarInformationLevel2( - @RequestParam Map queryParams) { - String id = queryParams.get("id"); - CarInformation carInformation = new CarInformation(); + @RequestParam final Map queryParams) { + final String id = queryParams.get("id"); return applicationJdbcTemplate.query( "select * from cars where id='" + id + "'", - (rs) -> { - if (rs.next()) { - carInformation.setId(rs.getInt(1)); - carInformation.setName(rs.getString(2)); - carInformation.setImagePath(rs.getString(3)); - } - return new ResponseEntity(carInformation, HttpStatus.OK); - }); + this::resultSetToResponse); } @AttackVector( @@ -88,19 +74,11 @@ public ResponseEntity getCarInformationLevel2( variant = Variant.SECURE, htmlTemplate = "LEVEL_1/SQLInjection_Level1") public ResponseEntity getCarInformationLevel3( - @RequestParam Map queryParams) { - String id = queryParams.get("id").replaceAll("'", ""); + @RequestParam final Map queryParams) { + final String id = queryParams.get("id").replaceAll("'", ""); return applicationJdbcTemplate.query( "select * from cars where id='" + id + "'", - (rs) -> { - CarInformation carInformation = new CarInformation(); - if (rs.next()) { - carInformation.setId(rs.getInt(1)); - carInformation.setName(rs.getString(2)); - carInformation.setImagePath(rs.getString(3)); - } - return new ResponseEntity(carInformation, HttpStatus.OK); - }); + this::resultSetToResponse); } @VulnerableAppRequestMapping( @@ -108,22 +86,22 @@ public ResponseEntity getCarInformationLevel3( variant = Variant.SECURE, htmlTemplate = "LEVEL_1/SQLInjection_Level1") public ResponseEntity getCarInformationLevel4( - @RequestParam Map queryParams) { - String id = queryParams.get("id"); + @RequestParam final Map queryParams) { + final String id = queryParams.get("id"); return applicationJdbcTemplate.query( "select * from cars where id=?", - (prepareStatement) -> { - prepareStatement.setString(1, id); - }, - (rs) -> { - CarInformation carInformation = new CarInformation(); - if (rs.next()) { - carInformation.setId(rs.getInt(1)); - carInformation.setName(rs.getString(2)); - carInformation.setImagePath(rs.getString(3)); - } - return new ResponseEntity(carInformation, HttpStatus.OK); - }); + prepareStatement -> prepareStatement.setString(1, id), + this::resultSetToResponse); + } + + private ResponseEntity resultSetToResponse(final ResultSet rs) throws SQLException { + final CarInformation carInformation = new CarInformation(); + if (rs.next()) { + carInformation.setId(rs.getInt(1)); + carInformation.setName(rs.getString(2)); + carInformation.setImagePath(rs.getString(3)); + } + return new ResponseEntity<>(carInformation, HttpStatus.OK); } } diff --git a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java index 621b6909..8bc984d3 100644 --- a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java +++ b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementSetter; import org.springframework.jdbc.core.ResultSetExtractor; import java.io.IOException; @@ -14,7 +15,7 @@ import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -public class UnionBasedSQLInjectionVulnerabilityTest { +class UnionBasedSQLInjectionVulnerabilityTest { private UnionBasedSQLInjectionVulnerability unionBasedSQLInjectionVulnerability; private JdbcTemplate template; @@ -31,9 +32,9 @@ void setUp() throws IOException { } @Test - public void getCarInformationLevel1_ExpectParamInjected() throws IOException { + void getCarInformationLevel1_ExpectParamInjected() throws IOException { // Act - Map params = new HashMap(); + final Map params = new HashMap<>(); params.put("id", "1 UNION SELECT * FROM cars;"); unionBasedSQLInjectionVulnerability.getCarInformationLevel1(params); @@ -42,7 +43,7 @@ public void getCarInformationLevel1_ExpectParamInjected() throws IOException { } @Test - public void getCarInformationLevel2_ExpectParamInjected() throws IOException { + void getCarInformationLevel2_ExpectParamInjected() throws IOException { // Act Map params = new HashMap(); params.put("id", "1' UNION SELECT * FROM cars; --"); @@ -52,6 +53,39 @@ public void getCarInformationLevel2_ExpectParamInjected() throws IOException { verify(template).query(eq("select * from cars where id='1' UNION SELECT * FROM cars; --'"), (ResultSetExtractor) any()); } + @Test + void getCarInformationLevel3_ExpectParamEscaped() throws IOException { + // Act + Map params = new HashMap(); + params.put("id", "1' UNION SELECT * FROM cars; --"); + unionBasedSQLInjectionVulnerability.getCarInformationLevel3(params); + + // Assert + verify(template).query(eq("select * from cars where id='1 UNION SELECT * FROM cars; --'"), (ResultSetExtractor) any()); + + } + + @Test + void getCarInformationLevel4_ExpectParamEscaped() throws IOException { + // Setup + template = Mockito.spy(new JdbcTemplate()); + PreparedStatementSetter setter = (ps) -> {}; + doReturn(null) + .when(template) + .query(anyString(), (PreparedStatementSetter) any(), (ResultSetExtractor) any()); + + unionBasedSQLInjectionVulnerability = Mockito.spy(new UnionBasedSQLInjectionVulnerability(template)); + + // Act + Map params = new HashMap(); + params.put("id", "1' UNION SELECT * FROM cars; --"); + unionBasedSQLInjectionVulnerability.getCarInformationLevel4(params); + + // Assert + verify(template).query(eq("select * from cars where id=?"), (PreparedStatementSetter) any(), (ResultSetExtractor) any()); + + } + // private JdbcTemplate applicationJdbcTemplate; // // public UnionBasedSQLInjectionVulnerabilityTest( From d7ba0a550d508f69b7e5fee6c790e3fbf18b9d8f Mon Sep 17 00:00:00 2001 From: Paul Weber Date: Tue, 12 Sep 2023 17:13:06 +0200 Subject: [PATCH 3/6] Cleanup --- ...ionBasedSQLInjectionVulnerabilityTest.java | 111 +----------------- 1 file changed, 4 insertions(+), 107 deletions(-) diff --git a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java index 8bc984d3..fc24740b 100644 --- a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java +++ b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java @@ -45,7 +45,7 @@ void getCarInformationLevel1_ExpectParamInjected() throws IOException { @Test void getCarInformationLevel2_ExpectParamInjected() throws IOException { // Act - Map params = new HashMap(); + final Map params = new HashMap<>(); params.put("id", "1' UNION SELECT * FROM cars; --"); unionBasedSQLInjectionVulnerability.getCarInformationLevel2(params); @@ -56,7 +56,7 @@ void getCarInformationLevel2_ExpectParamInjected() throws IOException { @Test void getCarInformationLevel3_ExpectParamEscaped() throws IOException { // Act - Map params = new HashMap(); + final Map params = new HashMap<>(); params.put("id", "1' UNION SELECT * FROM cars; --"); unionBasedSQLInjectionVulnerability.getCarInformationLevel3(params); @@ -66,10 +66,9 @@ void getCarInformationLevel3_ExpectParamEscaped() throws IOException { } @Test - void getCarInformationLevel4_ExpectParamEscaped() throws IOException { + void getCarInformationLevel4_ExpecParamEscaped() throws IOException { // Setup template = Mockito.spy(new JdbcTemplate()); - PreparedStatementSetter setter = (ps) -> {}; doReturn(null) .when(template) .query(anyString(), (PreparedStatementSetter) any(), (ResultSetExtractor) any()); @@ -77,7 +76,7 @@ void getCarInformationLevel4_ExpectParamEscaped() throws IOException { unionBasedSQLInjectionVulnerability = Mockito.spy(new UnionBasedSQLInjectionVulnerability(template)); // Act - Map params = new HashMap(); + final Map params = new HashMap<>(); params.put("id", "1' UNION SELECT * FROM cars; --"); unionBasedSQLInjectionVulnerability.getCarInformationLevel4(params); @@ -85,106 +84,4 @@ void getCarInformationLevel4_ExpectParamEscaped() throws IOException { verify(template).query(eq("select * from cars where id=?"), (PreparedStatementSetter) any(), (ResultSetExtractor) any()); } - -// private JdbcTemplate applicationJdbcTemplate; -// -// public UnionBasedSQLInjectionVulnerabilityTest( -// @Qualifier("applicationJdbcTemplate") JdbcTemplate applicationJdbcTemplate) { -// this.applicationJdbcTemplate = applicationJdbcTemplate; -// } -// -// @AttackVector( -// vulnerabilityExposed = VulnerabilityType.UNION_BASED_SQL_INJECTION, -// description = "UNION_SQL_INJECTION_URL_PARAM_APPENDED_DIRECTLY_TO_QUERY", -// payload = "UNION_BASED_SQL_INJECTION_PAYLOAD_LEVEL_1") -// @VulnerableAppRequestMapping( -// value = LevelConstants.LEVEL_1, -// htmlTemplate = "LEVEL_1/SQLInjection_Level1") -// public ResponseEntity getCarInformationLevel1( -// @RequestParam Map queryParams) { -// String id = queryParams.get("id"); -// return applicationJdbcTemplate.query( -// "select * from cars where id=" + id, -// (rs) -> { -// CarInformation carInformation = new CarInformation(); -// if (rs.next()) { -// carInformation.setId(rs.getInt(1)); -// carInformation.setName(rs.getString(2)); -// carInformation.setImagePath(rs.getString(3)); -// } -// return new ResponseEntity(carInformation, HttpStatus.OK); -// }); -// } -// -// @AttackVector( -// vulnerabilityExposed = VulnerabilityType.UNION_BASED_SQL_INJECTION, -// description = -// "UNION_SQL_INJECTION_URL_PARAM_WRAPPED_WITH_SINGLE_QUOTE_APPENDED_TO_QUERY", -// payload = "UNION_BASED_SQL_INJECTION_PAYLOAD_LEVEL_2") -// @VulnerableAppRequestMapping( -// value = LevelConstants.LEVEL_2, -// htmlTemplate = "LEVEL_1/SQLInjection_Level1") -// public ResponseEntity getCarInformationLevel2( -// @RequestParam Map queryParams) { -// String id = queryParams.get("id"); -// CarInformation carInformation = new CarInformation(); -// return applicationJdbcTemplate.query( -// "select * from cars where id='" + id + "'", -// (rs) -> { -// if (rs.next()) { -// carInformation.setId(rs.getInt(1)); -// carInformation.setName(rs.getString(2)); -// carInformation.setImagePath(rs.getString(3)); -// } -// return new ResponseEntity(carInformation, HttpStatus.OK); -// }); -// } -// -// @AttackVector( -// vulnerabilityExposed = VulnerabilityType.UNION_BASED_SQL_INJECTION, -// description = -// "UNION_SQL_INJECTION_URL_PARAM_REMOVES_SINGLE_QUOTE_WITH_SINGLE_QUOTE_APPENDED_TO_QUERY") -// @VulnerableAppRequestMapping( -// value = LevelConstants.LEVEL_3, -// variant = Variant.SECURE, -// htmlTemplate = "LEVEL_1/SQLInjection_Level1") -// public ResponseEntity getCarInformationLevel3( -// @RequestParam Map queryParams) { -// String id = queryParams.get("id").replaceAll("'", ""); -// return applicationJdbcTemplate.query( -// "select * from cars where id='" + id + "'", -// (rs) -> { -// CarInformation carInformation = new CarInformation(); -// if (rs.next()) { -// carInformation.setId(rs.getInt(1)); -// carInformation.setName(rs.getString(2)); -// carInformation.setImagePath(rs.getString(3)); -// } -// return new ResponseEntity(carInformation, HttpStatus.OK); -// }); -// } -// -// @VulnerableAppRequestMapping( -// value = LevelConstants.LEVEL_4, -// variant = Variant.SECURE, -// htmlTemplate = "LEVEL_1/SQLInjection_Level1") -// public ResponseEntity getCarInformationLevel4( -// @RequestParam Map queryParams) { -// String id = queryParams.get("id"); -// -// return applicationJdbcTemplate.query( -// "select * from cars where id=?", -// (prepareStatement) -> { -// prepareStatement.setString(1, id); -// }, -// (rs) -> { -// CarInformation carInformation = new CarInformation(); -// if (rs.next()) { -// carInformation.setId(rs.getInt(1)); -// carInformation.setName(rs.getString(2)); -// carInformation.setImagePath(rs.getString(3)); -// } -// return new ResponseEntity(carInformation, HttpStatus.OK); -// }); -// } } From 10dd8bb08568607e246690433af38006345b8b49 Mon Sep 17 00:00:00 2001 From: Paul Weber Date: Thu, 14 Sep 2023 11:02:59 +0200 Subject: [PATCH 4/6] Cleanup, resolve some issues from review. --- .../UnionBasedSQLInjectionVulnerability.java | 12 ++-- ...ionBasedSQLInjectionVulnerabilityTest.java | 63 +++++++++++-------- 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerability.java b/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerability.java index 27371748..b755b2c5 100644 --- a/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerability.java +++ b/src/main/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerability.java @@ -45,8 +45,7 @@ public ResponseEntity getCarInformationLevel1( @RequestParam final Map queryParams) { final String id = queryParams.get("id"); return applicationJdbcTemplate.query( - "select * from cars where id=" + id, - this::resultSetToResponse); + "select * from cars where id=" + id, this::resultSetToResponse); } @AttackVector( @@ -61,8 +60,7 @@ public ResponseEntity getCarInformationLevel2( @RequestParam final Map queryParams) { final String id = queryParams.get("id"); return applicationJdbcTemplate.query( - "select * from cars where id='" + id + "'", - this::resultSetToResponse); + "select * from cars where id='" + id + "'", this::resultSetToResponse); } @AttackVector( @@ -77,8 +75,7 @@ public ResponseEntity getCarInformationLevel3( @RequestParam final Map queryParams) { final String id = queryParams.get("id").replaceAll("'", ""); return applicationJdbcTemplate.query( - "select * from cars where id='" + id + "'", - this::resultSetToResponse); + "select * from cars where id='" + id + "'", this::resultSetToResponse); } @VulnerableAppRequestMapping( @@ -95,7 +92,8 @@ public ResponseEntity getCarInformationLevel4( this::resultSetToResponse); } - private ResponseEntity resultSetToResponse(final ResultSet rs) throws SQLException { + private ResponseEntity resultSetToResponse(final ResultSet rs) + throws SQLException { final CarInformation carInformation = new CarInformation(); if (rs.next()) { carInformation.setId(rs.getInt(1)); diff --git a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java index fc24740b..714a76b6 100644 --- a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java +++ b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java @@ -1,6 +1,15 @@ package org.sasanlabs.service.vulnerability.sqlInjection; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import java.io.IOException; +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.Mockito; @@ -8,13 +17,6 @@ import org.springframework.jdbc.core.PreparedStatementSetter; import org.springframework.jdbc.core.ResultSetExtractor; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - class UnionBasedSQLInjectionVulnerabilityTest { private UnionBasedSQLInjectionVulnerability unionBasedSQLInjectionVulnerability; @@ -22,47 +24,53 @@ class UnionBasedSQLInjectionVulnerabilityTest { @BeforeEach void setUp() throws IOException { - template = Mockito.spy(new JdbcTemplate()); + template = Mockito.mock(JdbcTemplate.class); + // mock database doReturn(null) .when(template) .query(anyString(), (ResultSetExtractor) any()); - unionBasedSQLInjectionVulnerability = Mockito.spy(new UnionBasedSQLInjectionVulnerability(template)); + unionBasedSQLInjectionVulnerability = new UnionBasedSQLInjectionVulnerability(template); } @Test void getCarInformationLevel1_ExpectParamInjected() throws IOException { // Act - final Map params = new HashMap<>(); - params.put("id", "1 UNION SELECT * FROM cars;"); + final Map params = Collections.singletonMap("id", "1 UNION SELECT * FROM cars;"); unionBasedSQLInjectionVulnerability.getCarInformationLevel1(params); // Assert - verify(template).query(eq("select * from cars where id=1 UNION SELECT * FROM cars;"), (ResultSetExtractor) any()); + verify(template) + .query( + eq("select * from cars where id=1 UNION SELECT * FROM cars;"), + (ResultSetExtractor) any()); } @Test void getCarInformationLevel2_ExpectParamInjected() throws IOException { // Act - final Map params = new HashMap<>(); - params.put("id", "1' UNION SELECT * FROM cars; --"); + final Map params = Collections.singletonMap("id", "1' UNION SELECT * FROM cars; --"); unionBasedSQLInjectionVulnerability.getCarInformationLevel2(params); // Assert - verify(template).query(eq("select * from cars where id='1' UNION SELECT * FROM cars; --'"), (ResultSetExtractor) any()); + verify(template) + .query( + eq("select * from cars where id='1' UNION SELECT * FROM cars; --'"), + (ResultSetExtractor) any()); } @Test void getCarInformationLevel3_ExpectParamEscaped() throws IOException { // Act - final Map params = new HashMap<>(); - params.put("id", "1' UNION SELECT * FROM cars; --"); + final Map params = Collections.singletonMap("id", "1' UNION SELECT * FROM cars; --"); unionBasedSQLInjectionVulnerability.getCarInformationLevel3(params); // Assert - verify(template).query(eq("select * from cars where id='1 UNION SELECT * FROM cars; --'"), (ResultSetExtractor) any()); - + verify(template) + .query( + eq("select * from cars where id='1 UNION SELECT * FROM cars; --'"), + (ResultSetExtractor) any()); } @Test @@ -71,17 +79,22 @@ void getCarInformationLevel4_ExpecParamEscaped() throws IOException { template = Mockito.spy(new JdbcTemplate()); doReturn(null) .when(template) - .query(anyString(), (PreparedStatementSetter) any(), (ResultSetExtractor) any()); + .query( + anyString(), + (PreparedStatementSetter) any(), + (ResultSetExtractor) any()); - unionBasedSQLInjectionVulnerability = Mockito.spy(new UnionBasedSQLInjectionVulnerability(template)); + unionBasedSQLInjectionVulnerability = new UnionBasedSQLInjectionVulnerability(template); // Act - final Map params = new HashMap<>(); - params.put("id", "1' UNION SELECT * FROM cars; --"); + final Map params = Collections.singletonMap("id", "1' UNION SELECT * FROM cars; --"); unionBasedSQLInjectionVulnerability.getCarInformationLevel4(params); // Assert - verify(template).query(eq("select * from cars where id=?"), (PreparedStatementSetter) any(), (ResultSetExtractor) any()); - + verify(template) + .query( + eq("select * from cars where id=?"), + (PreparedStatementSetter) any(), + (ResultSetExtractor) any()); } } From b2e8e058ed9aa2a4b54c5c7f01754936cb58f899 Mon Sep 17 00:00:00 2001 From: Paul Weber Date: Thu, 14 Sep 2023 11:06:55 +0200 Subject: [PATCH 5/6] SpotlessApply --- .../UnionBasedSQLInjectionVulnerabilityTest.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java index 714a76b6..c0dea511 100644 --- a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java +++ b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java @@ -8,7 +8,6 @@ import java.io.IOException; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -37,7 +36,8 @@ void setUp() throws IOException { @Test void getCarInformationLevel1_ExpectParamInjected() throws IOException { // Act - final Map params = Collections.singletonMap("id", "1 UNION SELECT * FROM cars;"); + final Map params = + Collections.singletonMap("id", "1 UNION SELECT * FROM cars;"); unionBasedSQLInjectionVulnerability.getCarInformationLevel1(params); // Assert @@ -50,7 +50,8 @@ void getCarInformationLevel1_ExpectParamInjected() throws IOException { @Test void getCarInformationLevel2_ExpectParamInjected() throws IOException { // Act - final Map params = Collections.singletonMap("id", "1' UNION SELECT * FROM cars; --"); + final Map params = + Collections.singletonMap("id", "1' UNION SELECT * FROM cars; --"); unionBasedSQLInjectionVulnerability.getCarInformationLevel2(params); // Assert @@ -63,7 +64,8 @@ void getCarInformationLevel2_ExpectParamInjected() throws IOException { @Test void getCarInformationLevel3_ExpectParamEscaped() throws IOException { // Act - final Map params = Collections.singletonMap("id", "1' UNION SELECT * FROM cars; --"); + final Map params = + Collections.singletonMap("id", "1' UNION SELECT * FROM cars; --"); unionBasedSQLInjectionVulnerability.getCarInformationLevel3(params); // Assert @@ -87,7 +89,8 @@ void getCarInformationLevel4_ExpecParamEscaped() throws IOException { unionBasedSQLInjectionVulnerability = new UnionBasedSQLInjectionVulnerability(template); // Act - final Map params = Collections.singletonMap("id", "1' UNION SELECT * FROM cars; --"); + final Map params = + Collections.singletonMap("id", "1' UNION SELECT * FROM cars; --"); unionBasedSQLInjectionVulnerability.getCarInformationLevel4(params); // Assert From 9a75a1d998f53d6ad933766e1cc737d9aa8643fc Mon Sep 17 00:00:00 2001 From: Paul Weber Date: Thu, 14 Sep 2023 11:22:00 +0200 Subject: [PATCH 6/6] Move setup to top of tests --- ...UnionBasedSQLInjectionVulnerabilityTest.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java index c0dea511..5d73d7a9 100644 --- a/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java +++ b/src/test/java/org/sasanlabs/service/vulnerability/sqlInjection/UnionBasedSQLInjectionVulnerabilityTest.java @@ -29,6 +29,12 @@ void setUp() throws IOException { doReturn(null) .when(template) .query(anyString(), (ResultSetExtractor) any()); + doReturn(null) + .when(template) + .query( + anyString(), + (PreparedStatementSetter) any(), + (ResultSetExtractor) any()); unionBasedSQLInjectionVulnerability = new UnionBasedSQLInjectionVulnerability(template); } @@ -77,17 +83,6 @@ void getCarInformationLevel3_ExpectParamEscaped() throws IOException { @Test void getCarInformationLevel4_ExpecParamEscaped() throws IOException { - // Setup - template = Mockito.spy(new JdbcTemplate()); - doReturn(null) - .when(template) - .query( - anyString(), - (PreparedStatementSetter) any(), - (ResultSetExtractor) any()); - - unionBasedSQLInjectionVulnerability = new UnionBasedSQLInjectionVulnerability(template); - // Act final Map params = Collections.singletonMap("id", "1' UNION SELECT * FROM cars; --");