From 5bda90e1c391fcf97f5a6640c6be5cb14112425d Mon Sep 17 00:00:00 2001 From: rai-sandeep <36532643+rai-sandeep@users.noreply.github.com> Date: Sat, 14 Jan 2023 14:37:27 +0530 Subject: [PATCH] Add SSRF Vulnerability tests (#429) Add SSRF Vulnerability tests --- .../ssrf/SSRFVulnerabilityTest.java | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 src/test/java/org/sasanlabs/service/vulnerability/ssrf/SSRFVulnerabilityTest.java diff --git a/src/test/java/org/sasanlabs/service/vulnerability/ssrf/SSRFVulnerabilityTest.java b/src/test/java/org/sasanlabs/service/vulnerability/ssrf/SSRFVulnerabilityTest.java new file mode 100644 index 00000000..271eebbf --- /dev/null +++ b/src/test/java/org/sasanlabs/service/vulnerability/ssrf/SSRFVulnerabilityTest.java @@ -0,0 +1,158 @@ +package org.sasanlabs.service.vulnerability.ssrf; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Collections; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.sasanlabs.service.vulnerability.bean.GenericVulnerabilityResponseBean; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +class SSRFVulnerabilityTest { + + private static final String INVALID_URL = "invalidUrl"; + private static final String INVALID_URL_MESSAGE = "Provided URL not valid"; + private static final String TEMP_FILE_CONTENT = "Temp file content"; + private static final String METADATA_URL_AWS = "http://169.254.169.254/1.0"; + private static final String METADATA_URL_OTHER = "http://[::ffff:169.254.169.254]/1.0"; + private static final String METADATA_URL_CONTENT = "meta-data"; + private static final String OTHER_URL = "https://github.com/SasanLabs/VulnerableApp"; + private static final String OTHER_URL_CONTENT = "VulnerableApp"; + private static final String GIST_ID = "bbf2e2183b8f6252061663ce0ddee79b"; + private static final String GIST_URL = "https://gist.githubusercontent.com/raw/" + GIST_ID; + private static final String GIST_URL_CONTENT = "OWASP VulnerableApp"; + + @TempDir static File tempDir; + + private static String tempFileUrl; + + private final SSRFVulnerability ssrfVulnerability = new SSRFVulnerability(GIST_ID); + + @BeforeAll + static void setUp() throws IOException { + File tempFile = new File(tempDir, "temp.txt"); + Files.write(tempFile.toPath(), Collections.singletonList(TEMP_FILE_CONTENT)); + tempFileUrl = "file:///" + tempFile.getAbsolutePath(); + } + + private static Stream testParamsForLevel1() { + return Stream.of( + // Arguments: Input URL, Expected isValid response, Expected response body content + Arguments.of(INVALID_URL, false, INVALID_URL_MESSAGE), + Arguments.of(tempFileUrl, true, TEMP_FILE_CONTENT), + Arguments.of(METADATA_URL_AWS, true, METADATA_URL_CONTENT), + Arguments.of(METADATA_URL_OTHER, true, METADATA_URL_CONTENT), + Arguments.of(OTHER_URL, true, OTHER_URL_CONTENT), + Arguments.of(GIST_URL, true, GIST_URL_CONTENT)); + } + + @ParameterizedTest + @MethodSource("testParamsForLevel1") + void getVulnerablePayloadLevel1(String url, boolean isValid, String content) + throws IOException { + ResponseEntity> responseEntity = + ssrfVulnerability.getVulnerablePayloadLevel1(url); + validateResponse(responseEntity, isValid, content); + } + + private static Stream testParamsForLevel2() { + return Stream.of( + // Arguments: Input URL, Expected isValid response, Expected response body content + Arguments.of(INVALID_URL, false, INVALID_URL_MESSAGE), + Arguments.of(tempFileUrl, false, INVALID_URL_MESSAGE), + Arguments.of(METADATA_URL_AWS, true, METADATA_URL_CONTENT), + Arguments.of(METADATA_URL_OTHER, true, METADATA_URL_CONTENT), + Arguments.of(OTHER_URL, true, OTHER_URL_CONTENT), + Arguments.of(GIST_URL, true, GIST_URL_CONTENT)); + } + + @ParameterizedTest + @MethodSource("testParamsForLevel2") + void getVulnerablePayloadLevel2(String url, boolean isValid, String content) + throws IOException { + ResponseEntity> responseEntity = + ssrfVulnerability.getVulnerablePayloadLevel2(url); + validateResponse(responseEntity, isValid, content); + } + + private static Stream testParamsForLevel3() { + return Stream.of( + // Arguments: Input URL, Expected isValid response, Expected response body content + Arguments.of(INVALID_URL, false, INVALID_URL_MESSAGE), + Arguments.of(tempFileUrl, false, INVALID_URL_MESSAGE), + Arguments.of(METADATA_URL_AWS, false, INVALID_URL_MESSAGE), + Arguments.of(METADATA_URL_OTHER, true, METADATA_URL_CONTENT), + Arguments.of(OTHER_URL, true, OTHER_URL_CONTENT), + Arguments.of(GIST_URL, true, GIST_URL_CONTENT)); + } + + @ParameterizedTest + @MethodSource("testParamsForLevel3") + void getVulnerablePayloadLevel3(String url, boolean isValid, String content) + throws IOException { + ResponseEntity> responseEntity = + ssrfVulnerability.getVulnerablePayloadLevel3(url); + validateResponse(responseEntity, isValid, content); + } + + private static Stream testParamsForLevel4() { + return Stream.of( + // Arguments: Input URL, Expected isValid response, Expected response body content + Arguments.of(INVALID_URL, false, INVALID_URL_MESSAGE), + Arguments.of(tempFileUrl, false, INVALID_URL_MESSAGE), + Arguments.of(METADATA_URL_AWS, false, INVALID_URL_MESSAGE), + Arguments.of(METADATA_URL_OTHER, false, INVALID_URL_MESSAGE), + Arguments.of(OTHER_URL, true, OTHER_URL_CONTENT), + Arguments.of(GIST_URL, true, GIST_URL_CONTENT)); + } + + @ParameterizedTest + @MethodSource("testParamsForLevel4") + void getVulnerablePayloadLevel4(String url, boolean isValid, String content) + throws IOException { + ResponseEntity> responseEntity = + ssrfVulnerability.getVulnerablePayloadLevel4(url); + validateResponse(responseEntity, isValid, content); + } + + private static Stream testParamsForLevel5() { + return Stream.of( + // Arguments: Input URL, Expected isValid response, Expected response body content + Arguments.of(INVALID_URL, false, INVALID_URL_MESSAGE), + Arguments.of(tempFileUrl, false, INVALID_URL_MESSAGE), + Arguments.of(METADATA_URL_AWS, false, INVALID_URL_MESSAGE), + Arguments.of(METADATA_URL_OTHER, false, INVALID_URL_MESSAGE), + Arguments.of(OTHER_URL, false, INVALID_URL_MESSAGE), + Arguments.of(GIST_URL, true, GIST_URL_CONTENT)); + } + + @ParameterizedTest + @MethodSource("testParamsForLevel5") + void getVulnerablePayloadLevel5(String url, boolean isValid, String content) + throws IOException { + ResponseEntity> responseEntity = + ssrfVulnerability.getVulnerablePayloadLevel5(url); + validateResponse(responseEntity, isValid, content); + } + + private void validateResponse( + ResponseEntity> responseEntity, + boolean isValid, + String content) { + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + GenericVulnerabilityResponseBean responseBody = responseEntity.getBody(); + assertNotNull(responseBody); + assertEquals(isValid, responseBody.getIsValid()); + assertTrue(responseBody.getContent().contains(content)); + } +}