diff --git a/agent_api/src/main/java/dev/aikido/agent_api/collectors/CommandCollector.java b/agent_api/src/main/java/dev/aikido/agent_api/collectors/CommandCollector.java index 719deb570..058469bcd 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/collectors/CommandCollector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/collectors/CommandCollector.java @@ -22,8 +22,7 @@ public static void report(Object command) { StatisticsStore.registerCall("runtime.Exec", OperationKind.EXEC_OP); // scan - Vulnerabilities.Vulnerability vulnerability = new Vulnerabilities.ShellInjectionVulnerability(); - Scanner.scanForGivenVulnerability(vulnerability, "runtime.Exec", new String[]{commandStr}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SHELL_INJECTION, "runtime.Exec", new String[]{commandStr}); } } } diff --git a/agent_api/src/main/java/dev/aikido/agent_api/collectors/DNSRecordCollector.java b/agent_api/src/main/java/dev/aikido/agent_api/collectors/DNSRecordCollector.java index 5b2b0211f..d92b8e924 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/collectors/DNSRecordCollector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/collectors/DNSRecordCollector.java @@ -44,7 +44,7 @@ public static void report(String hostname, InetAddress[] inetAddresses) { } logger.debug("Hostname: %s, Port: %s, IPs: %s", hostnameEntry.getHostname(), hostnameEntry.getPort(), ipAddresses); - Attack attack = new SSRFDetector().run( + Attack attack = SSRFDetector.run( hostname, hostnameEntry.getPort(), ipAddresses, OPERATION_NAME ); if (attack == null) { diff --git a/agent_api/src/main/java/dev/aikido/agent_api/collectors/FileCollector.java b/agent_api/src/main/java/dev/aikido/agent_api/collectors/FileCollector.java index 79698edb4..4996ec318 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/collectors/FileCollector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/collectors/FileCollector.java @@ -31,18 +31,17 @@ public static void report(Object filePath, String operation, int depth) { logger.trace("Scan on %s for file: %s", operation, filePath); StatisticsStore.registerCall(operation, OperationKind.FS_OP); - Vulnerabilities.Vulnerability vulnerability = new Vulnerabilities.PathTraversalVulnerability(); if (filePath instanceof String filePathString) { - Scanner.scanForGivenVulnerability(vulnerability, operation, new String[]{filePathString}); + Scanner.scanForGivenVulnerability(Vulnerabilities.PATH_TRAVERSAL, operation, new String[]{filePathString}); } else if (filePath instanceof URI filePathURI) { // File(...) Constructor also accepts URI objects, but path remains the same // So we just extract the path here : (i.e. new File("file:///../test.txt") --> "/../test.txt") String filePathString = filePathURI.getPath(); - Scanner.scanForGivenVulnerability(vulnerability, operation, new String[]{filePathString}); + Scanner.scanForGivenVulnerability(Vulnerabilities.PATH_TRAVERSAL, operation, new String[]{filePathString}); } else if (filePath instanceof Path filePathAsPath) { // Some functions on Path also accept other paths String filePathString = filePathAsPath.toString(); - Scanner.scanForGivenVulnerability(vulnerability, operation, new String[]{filePathString}); + Scanner.scanForGivenVulnerability(Vulnerabilities.PATH_TRAVERSAL, operation, new String[]{filePathString}); } else if (filePath instanceof Object[] filePaths) { // In Paths.get() sometimes you can have multiple paths provided, scan them individually : if (depth >= MAX_RECURSION_DEPTH) { diff --git a/agent_api/src/main/java/dev/aikido/agent_api/collectors/SQLCollector.java b/agent_api/src/main/java/dev/aikido/agent_api/collectors/SQLCollector.java index e167d3a94..227feb9f2 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/collectors/SQLCollector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/collectors/SQLCollector.java @@ -15,7 +15,6 @@ public static void report(String sql, String dialect, String operation) { StatisticsStore.registerCall(operation, OperationKind.SQL_OP); // scan - Vulnerabilities.Vulnerability vulnerability = new Vulnerabilities.SQLInjectionVulnerability(); - Scanner.scanForGivenVulnerability(vulnerability, operation, new String[]{sql, dialect}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, operation, new String[]{sql, dialect}); } } diff --git a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/Vulnerabilities.java b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/Vulnerabilities.java index dd1d1dcf5..e6e7c4527 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/Vulnerabilities.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/Vulnerabilities.java @@ -3,7 +3,6 @@ import dev.aikido.agent_api.vulnerabilities.path_traversal.PathTraversalDetector; import dev.aikido.agent_api.vulnerabilities.shell_injection.ShellInjectionDetector; import dev.aikido.agent_api.vulnerabilities.sql_injection.SqlDetector; -import dev.aikido.agent_api.vulnerabilities.ssrf.SSRFDetector; public final class Vulnerabilities { private Vulnerabilities() {} @@ -11,27 +10,32 @@ public interface Vulnerability { Detector getDetector(); String getKind(); } - public static final class SQLInjectionVulnerability implements Vulnerability { + + private static final class SQLInjectionVulnerability implements Vulnerability { @Override public Detector getDetector() { - return new SqlDetector(); + return SqlDetector.INSTANCE; } @Override public String getKind() { return "sql_injection"; } } - public static final class PathTraversalVulnerability implements Vulnerability { + public static final Vulnerability SQL_INJECTION = new SQLInjectionVulnerability(); + + private static final class PathTraversalVulnerability implements Vulnerability { @Override public Detector getDetector() { - return new PathTraversalDetector(); + return PathTraversalDetector.INSTANCE; } @Override public String getKind() { return "path_traversal"; } } - public static final class SSRFVulnerability implements Vulnerability { + public static final Vulnerability PATH_TRAVERSAL = new PathTraversalVulnerability(); + + private static final class SSRFVulnerability implements Vulnerability { @Override public Detector getDetector() { return null; } @Override @@ -39,7 +43,9 @@ public String getKind() { return "ssrf"; } } - public static final class StoredSSRFVulnerability implements Vulnerability { + public static final Vulnerability SSRF = new SSRFVulnerability(); + + private static final class StoredSSRFVulnerability implements Vulnerability { @Override public Detector getDetector() { return null; } @Override @@ -47,12 +53,15 @@ public String getKind() { return "stored_ssrf"; } } - public static final class ShellInjectionVulnerability implements Vulnerability { + public static final Vulnerability STORED_SSRF = new StoredSSRFVulnerability(); + + private static final class ShellInjectionVulnerability implements Vulnerability { @Override - public Detector getDetector() { return new ShellInjectionDetector(); } + public Detector getDetector() { return ShellInjectionDetector.INSTANCE; } @Override public String getKind() { return "shell_injection"; } } + public static final Vulnerability SHELL_INJECTION = new ShellInjectionVulnerability(); } diff --git a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/path_traversal/PathTraversalDetector.java b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/path_traversal/PathTraversalDetector.java index 5e793beef..5103b45bf 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/path_traversal/PathTraversalDetector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/path_traversal/PathTraversalDetector.java @@ -8,6 +8,8 @@ import static dev.aikido.agent_api.vulnerabilities.path_traversal.UnsafePathPartsChecker.containsUnsafePathParts; public class PathTraversalDetector implements Detector { + public static final PathTraversalDetector INSTANCE = new PathTraversalDetector(); + /** * @param userInput, this is the user input which we will evaluate * @param arguments, Includes one element : filename diff --git a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/shell_injection/ShellInjectionDetector.java b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/shell_injection/ShellInjectionDetector.java index 89cbe1a8d..e024880e9 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/shell_injection/ShellInjectionDetector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/shell_injection/ShellInjectionDetector.java @@ -9,6 +9,8 @@ import static dev.aikido.agent_api.vulnerabilities.shell_injection.ShellSyntaxChecker.containsShellSyntax; public class ShellInjectionDetector implements Detector { + public static final ShellInjectionDetector INSTANCE = new ShellInjectionDetector(); + @Override public DetectorResult run(String userInput, String[] arguments) { if (userInput.isEmpty() || arguments == null || arguments.length == 0 || arguments[0] == null) { diff --git a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/sql_injection/SqlDetector.java b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/sql_injection/SqlDetector.java index ba99b0325..288a49529 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/sql_injection/SqlDetector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/sql_injection/SqlDetector.java @@ -8,7 +8,9 @@ import java.util.regex.Pattern; public class SqlDetector implements Detector { + public static final SqlDetector INSTANCE = new SqlDetector(); private static final Logger logger = LogManager.getLogger(SqlDetector.class); + /** * @param userInput contains the user input which we want to scan * @param arguments contains: [query, dialect] diff --git a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/ssrf/SSRFDetector.java b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/ssrf/SSRFDetector.java index 749b1d10d..3a2cf6e47 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/ssrf/SSRFDetector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/ssrf/SSRFDetector.java @@ -3,22 +3,18 @@ import dev.aikido.agent_api.context.Context; import dev.aikido.agent_api.context.ContextObject; import dev.aikido.agent_api.vulnerabilities.Attack; -import dev.aikido.agent_api.vulnerabilities.Detector; import dev.aikido.agent_api.vulnerabilities.Vulnerabilities; -import java.util.HashSet; import java.util.List; import java.util.Map; -import static dev.aikido.agent_api.helpers.ShouldBlockHelper.shouldBlock; import static dev.aikido.agent_api.helpers.StackTrace.getCurrentStackTrace; import static dev.aikido.agent_api.vulnerabilities.ssrf.FindHostnameInContext.findHostnameInContext; import static dev.aikido.agent_api.vulnerabilities.ssrf.IsPrivateIP.containsPrivateIP; import static dev.aikido.agent_api.vulnerabilities.ssrf.PrivateIPRedirectFinder.isRedirectToPrivateIP; -import static dev.aikido.agent_api.vulnerabilities.ssrf.imds.Resolver.resolvesToImdsIp; -public class SSRFDetector { - public Attack run(String hostname, int port, List ipAddresses, String operation) { +public final class SSRFDetector { + public static Attack run(String hostname, int port, List ipAddresses, String operation) { if(hostname == null || hostname.isEmpty()) { return null; } @@ -39,7 +35,7 @@ public Attack run(String hostname, int port, List ipAddresses, String op if(attackFindings != null) { return new Attack( operation, - new Vulnerabilities.SSRFVulnerability(), + Vulnerabilities.SSRF, attackFindings.source(), attackFindings.pathToPayload(), /*metadata*/ Map.of( diff --git a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/ssrf/StoredSSRFDetector.java b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/ssrf/StoredSSRFDetector.java index 8053f588a..f63e83d98 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/ssrf/StoredSSRFDetector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/ssrf/StoredSSRFDetector.java @@ -23,7 +23,7 @@ public Attack run(String hostname, List ipAddresses, String operation) { return new Attack( operation, - new Vulnerabilities.StoredSSRFVulnerability(), + Vulnerabilities.STORED_SSRF, null, // source is null for stored attacks "", // path is empty Map.of( diff --git a/agent_api/src/test/java/vulnerabilities/AttackTest.java b/agent_api/src/test/java/vulnerabilities/AttackTest.java index 67677b1f9..c2562b40b 100644 --- a/agent_api/src/test/java/vulnerabilities/AttackTest.java +++ b/agent_api/src/test/java/vulnerabilities/AttackTest.java @@ -16,7 +16,6 @@ public class AttackTest { public void testAttackConstructor() { // Arrange String operation = "SQL Injection"; - Vulnerabilities.Vulnerability vulnerability = new Vulnerabilities.SQLInjectionVulnerability(); String source = "User Input"; String pathToPayload = "/api/vulnerable"; Map metadata = new HashMap<>(); @@ -26,11 +25,11 @@ public void testAttackConstructor() { User user = new User("id", "name", "1.1.1.1", 0); // Act - Attack attack = new Attack(operation, vulnerability, source, pathToPayload, metadata, payload, stack, user); + Attack attack = new Attack(operation, Vulnerabilities.SQL_INJECTION, source, pathToPayload, metadata, payload, stack, user); // Assert assertEquals(operation, attack.operation); - assertEquals(vulnerability.getKind(), attack.kind); + assertEquals("sql_injection", attack.kind); assertEquals(source, attack.source); assertEquals(pathToPayload, attack.pathToPayload); assertEquals(metadata, attack.metadata); @@ -47,7 +46,6 @@ public void testAttackConstructor() { public void testAttackWithEmptyMetadata() { // Arrange String operation = "XSS Attack"; - Vulnerabilities.Vulnerability vulnerability = new Vulnerabilities.SQLInjectionVulnerability(); String source = "User Input"; String pathToPayload = "/api/vulnerable"; Map metadata = new HashMap<>(); // Empty metadata @@ -56,11 +54,11 @@ public void testAttackWithEmptyMetadata() { User user = new User("123", "name", "1.1.1.1", 0); // Act - Attack attack = new Attack(operation, vulnerability, source, pathToPayload, metadata, payload, stack, user); + Attack attack = new Attack(operation, Vulnerabilities.SQL_INJECTION, source, pathToPayload, metadata, payload, stack, user); // Assert assertEquals(operation, attack.operation); - assertEquals(vulnerability.getKind(), attack.kind); + assertEquals("sql_injection", attack.kind); assertEquals(source, attack.source); assertEquals(pathToPayload, attack.pathToPayload); assertEquals(metadata, attack.metadata); diff --git a/agent_api/src/test/java/vulnerabilities/ScannerTest.java b/agent_api/src/test/java/vulnerabilities/ScannerTest.java index 4c03df13d..f33370935 100644 --- a/agent_api/src/test/java/vulnerabilities/ScannerTest.java +++ b/agent_api/src/test/java/vulnerabilities/ScannerTest.java @@ -78,15 +78,15 @@ void testScanForGivenVulnerability_ContextIsNull() { void testScanSafeSQLCode() throws InterruptedException { ServiceConfigStore.updateBlocking(true); // Safe : - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT", "postgresql"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT", "postgresql"}); // Argument-mismatch, safe : - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM"}); - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM", "1", "2", "3"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM", "1", "2", "3"}); // Unsafe : AttackQueue.clear(); assertThrows(SQLInjectionException.class, () -> { - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM", "postgresql"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM", "postgresql"}); }); DetectedAttack.DetectedAttackEvent attackEvent = (DetectedAttack.DetectedAttackEvent) AttackQueue.get(); assertEquals("SELECT * FRO", attackEvent.attack().payload()); @@ -98,14 +98,14 @@ void testScanSafeSQLCode() throws InterruptedException { void testScanSafeSQLCodeButBlockingFalse() { ServiceConfigStore.updateBlocking(false); // Safe : - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT", "postgresql"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT", "postgresql"}); // Argument-mismatch, safe : - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM"}); - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM", "1", "2", "3"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM", "1", "2", "3"}); // Unsafe : assertDoesNotThrow(() -> { - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM", "postgresql"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM", "postgresql"}); }); } @@ -114,22 +114,22 @@ void testForceProtectionOff() { ServiceConfigStore.updateBlocking(true); // Thread cache does not force any protection off : assertThrows(SQLInjectionException.class, () -> { - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM", "postgresql"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM", "postgresql"}); }); // Set to protection forced off route : Context.set(new SampleContextObject3("/api2/test/2/4")); assertDoesNotThrow(() -> { - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM", "postgresql"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM", "postgresql"}); }); Context.set(new SampleContextObject3("/api2/")); assertDoesNotThrow(() -> { - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM", "postgresql"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM", "postgresql"}); }); // Set to IP where route exists but protection is not forced off : Context.set(new SampleContextObject3("/api3/test")); assertThrows(SQLInjectionException.class, () -> { - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM", "postgresql"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM", "postgresql"}); }); } @@ -138,7 +138,7 @@ void testDoesNotRunWithContextNull() { ServiceConfigStore.updateBlocking(true); Context.set(null); assertDoesNotThrow(() -> { - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM", "postgresql"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM", "postgresql"}); }); } @@ -148,7 +148,7 @@ void TestStillThrowsWithConfigStoreEmptyButBlockingEnabled() { ServiceConfigStore.updateFromAPIResponse(emptyAPIResponse); ServiceConfigStore.updateBlocking(true); assertThrows(SQLInjectionException.class, () -> { - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM", "postgresql"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM", "postgresql"}); }); } @@ -156,7 +156,7 @@ void TestStillThrowsWithConfigStoreEmptyButBlockingEnabled() { void TestDoesNotThrowWithEmptyAPIResponse() { ServiceConfigStore.updateFromAPIResponse(emptyAPIResponse); assertDoesNotThrow(() -> { - Scanner.scanForGivenVulnerability(new Vulnerabilities.SQLInjectionVulnerability(), "operation", new String[]{"SELECT * FROM", "postgresql"}); + Scanner.scanForGivenVulnerability(Vulnerabilities.SQL_INJECTION, "operation", new String[]{"SELECT * FROM", "postgresql"}); }); } } diff --git a/agent_api/src/test/java/vulnerabilities/path_traversal/PathTraversalDetectorTest.java b/agent_api/src/test/java/vulnerabilities/path_traversal/PathTraversalDetectorTest.java index e24bbc20b..514a019f7 100644 --- a/agent_api/src/test/java/vulnerabilities/path_traversal/PathTraversalDetectorTest.java +++ b/agent_api/src/test/java/vulnerabilities/path_traversal/PathTraversalDetectorTest.java @@ -7,7 +7,6 @@ import static org.junit.jupiter.api.Assertions.*; public class PathTraversalDetectorTest { - private final PathTraversalDetector pathTraversalDetector = new PathTraversalDetector(); private void assertNotAttack(Detector.DetectorResult detectorResult) { assertFalse(detectorResult.isDetectedAttack()); } @@ -16,199 +15,199 @@ private void assertAttack(Detector.DetectorResult detectorResult) { } @Test public void testEmptyUserInput() { - assertNotAttack(pathTraversalDetector.run("", new String[]{"test.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("", new String[]{"test.txt"})); } @Test public void testEmptyFileInput() { - assertNotAttack(pathTraversalDetector.run("test", new String[]{""})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("test", new String[]{""})); } @Test public void testEmptyUserInputAndFileInput() { - assertNotAttack(pathTraversalDetector.run("", new String[]{""})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("", new String[]{""})); } @Test public void testUserInputIsASingleCharacter() { - assertNotAttack(pathTraversalDetector.run("t", new String[]{"test.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("t", new String[]{"test.txt"})); } @Test public void testFileInputIsASingleCharacter() { - assertNotAttack(pathTraversalDetector.run("test", new String[]{"t"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("test", new String[]{"t"})); } @Test public void testSameAsUserInput() { - assertNotAttack(pathTraversalDetector.run("text.txt", new String[]{"text.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("text.txt", new String[]{"text.txt"})); } @Test public void testWithDirectoryBefore() { - assertNotAttack(pathTraversalDetector.run("text.txt", new String[]{"directory/text.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("text.txt", new String[]{"directory/text.txt"})); } @Test public void testWithBothDirectoryBefore() { - assertNotAttack(pathTraversalDetector.run("directory/text.txt", new String[]{"directory/text.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("directory/text.txt", new String[]{"directory/text.txt"})); } @Test public void testUserInputAndFileInputAreSingleCharacters() { - assertNotAttack(pathTraversalDetector.run("t", new String[]{"t"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("t", new String[]{"t"})); } @Test public void testItFlagsDotDotSlash() { - assertAttack(pathTraversalDetector.run("../", new String[]{"../test.txt"})); + assertAttack(PathTraversalDetector.INSTANCE.run("../", new String[]{"../test.txt"})); } @Test public void testItFlagsDotDotSlashSlash() { - assertAttack(pathTraversalDetector.run("..//", new String[]{"..//test.txt"})); + assertAttack(PathTraversalDetector.INSTANCE.run("..//", new String[]{"..//test.txt"})); } @Test public void testItFlagsMoreComplexPaths() { - assertAttack(pathTraversalDetector.run("..//secrets/key.txt", new String[]{"resources/blog/..//secrets/key.txt"})); - assertAttack(pathTraversalDetector.run(".././/secrets/key.txt", new String[]{"resources/blog/.././/secrets/key.txt"})); - assertAttack(pathTraversalDetector.run("////../secrets/key.txt", new String[]{"resources/blog/////../secrets/key.txt"})); + assertAttack(PathTraversalDetector.INSTANCE.run("..//secrets/key.txt", new String[]{"resources/blog/..//secrets/key.txt"})); + assertAttack(PathTraversalDetector.INSTANCE.run(".././/secrets/key.txt", new String[]{"resources/blog/.././/secrets/key.txt"})); + assertAttack(PathTraversalDetector.INSTANCE.run("////../secrets/key.txt", new String[]{"resources/blog/////../secrets/key.txt"})); } @Test public void testItFlagsBackslashDotDot() { - assertAttack(pathTraversalDetector.run("..\\", new String[]{"..\\test.txt",})); + assertAttack(PathTraversalDetector.INSTANCE.run("..\\", new String[]{"..\\test.txt",})); } @Test public void testItFlagsDoubleDotSlash() { - assertAttack(pathTraversalDetector.run("../../", new String[]{"../../test.txt"})); + assertAttack(PathTraversalDetector.INSTANCE.run("../../", new String[]{"../../test.txt"})); } @Test public void testItFlagsDoubleDotBackslash() { - assertAttack(pathTraversalDetector.run("..\\..\\", new String[]{"..\\..\\test.txt",})); + assertAttack(PathTraversalDetector.INSTANCE.run("..\\..\\", new String[]{"..\\..\\test.txt",})); } @Test public void testItFlagsFourDotSlash() { - assertAttack(pathTraversalDetector.run("../../../../", new String[]{"../../../../test.txt"})); + assertAttack(PathTraversalDetector.INSTANCE.run("../../../../", new String[]{"../../../../test.txt"})); } @Test public void testItFlagsThreeDotBackslash() { - assertAttack(pathTraversalDetector.run("..\\..\\..\\", new String[]{"..\\..\\..\\test.txt",})); + assertAttack(PathTraversalDetector.INSTANCE.run("..\\..\\..\\", new String[]{"..\\..\\..\\test.txt",})); } @Test public void testUserInputIsLongerThanFilePath() { - assertNotAttack(pathTraversalDetector.run("../../file.txt", new String[]{"../file.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("../../file.txt", new String[]{"../file.txt"})); } @Test public void testAbsoluteLinuxPath() { - assertAttack(pathTraversalDetector.run("/etc/passwd", new String[]{"/etc/passwd"})); + assertAttack(PathTraversalDetector.INSTANCE.run("/etc/passwd", new String[]{"/etc/passwd"})); } @Test public void testLinuxUserDirectory() { - assertAttack(pathTraversalDetector.run("/home/user/", new String[]{"/home/user/file.txt"})); + assertAttack(PathTraversalDetector.INSTANCE.run("/home/user/", new String[]{"/home/user/file.txt"})); } @Test public void testWindowsDriveLetter() { - assertAttack(pathTraversalDetector.run("C:\\", new String[]{"C:\\file.txt"})); + assertAttack(PathTraversalDetector.INSTANCE.run("C:\\", new String[]{"C:\\file.txt"})); } @Test public void testNoPathTraversal() { - assertNotAttack(pathTraversalDetector.run("/storage/file.txt", new String[]{"/appdata/storage/file.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("/storage/file.txt", new String[]{"/appdata/storage/file.txt"})); } @Test public void testDoesNotFlagTest() { - assertNotAttack(pathTraversalDetector.run("test", new String[]{"/app/test.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("test", new String[]{"/app/test.txt"})); } @Test public void testDoesNotFlagExampleTestTxt() { - assertNotAttack(pathTraversalDetector.run("example/test.txt", new String[]{"/app/data/example/test.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("example/test.txt", new String[]{"/app/data/example/test.txt"})); } @Test public void testDoesNotAbsolutePathWithDifferentFolder() { - assertNotAttack(pathTraversalDetector.run("/etc/hack/config", new String[]{"/etc/app/config"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("/etc/hack/config", new String[]{"/etc/app/config"})); } @Test public void testDoesNotAbsolutePathInsideAnotherFolder() { - assertNotAttack(pathTraversalDetector.run("/etc/config", new String[]{"/etc/app/data/etc/config"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("/etc/config", new String[]{"/etc/app/data/etc/config"})); } @Test public void testUserInputContainsMultipleUnsafePathParts() { - assertNotAttack(pathTraversalDetector.run("../../../", new String[]{"directory/../../file.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("../../../", new String[]{"directory/../../file.txt"})); } @Test public void testUserInputWithMixedPathSeparators() { - assertNotAttack(pathTraversalDetector.run("..\\..\\", new String[]{"directory/../file.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("..\\..\\", new String[]{"directory/../file.txt"})); } @Test public void testUserInputWithEncodedCharacters() { - assertAttack(pathTraversalDetector.run("%2E%2E/../", new String[]{"directory/%2E%2E/../file.txt"})); + assertAttack(PathTraversalDetector.INSTANCE.run("%2E%2E/../", new String[]{"directory/%2E%2E/../file.txt"})); } @Test public void testUserInputWithEncodedBackslash() { - assertNotAttack(pathTraversalDetector.run("%5C%5C", new String[]{"directory/%5C%5Cfile.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("%5C%5C", new String[]{"directory/%5C%5Cfile.txt"})); } @Test public void testUserInputWithSpaces() { - assertNotAttack(pathTraversalDetector.run("test file", new String[]{"directory/test file.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("test file", new String[]{"directory/test file.txt"})); } @Test public void testUserInputWithLeadingSpaces() { - assertNotAttack(pathTraversalDetector.run(" test.txt", new String[]{"directory/test.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run(" test.txt", new String[]{"directory/test.txt"})); } @Test public void testUserInputWithTrailingSpaces() { - assertNotAttack(pathTraversalDetector.run("test.txt ", new String[]{"directory/test.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("test.txt ", new String[]{"directory/test.txt"})); } @Test public void testUserInputWithSpecialCharacters() { - assertNotAttack(pathTraversalDetector.run("test@file.txt", new String[]{"directory/test@file.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("test@file.txt", new String[]{"directory/test@file.txt"})); } @Test public void testUserInputWithAbsolutePath() { - assertAttack(pathTraversalDetector.run("/etc/passwd", new String[]{"/etc/passwd"})); + assertAttack(PathTraversalDetector.INSTANCE.run("/etc/passwd", new String[]{"/etc/passwd"})); } @Test public void testUserInputWithMixedCase() { - assertNotAttack(pathTraversalDetector.run("Test.txt", new String[]{"directory/test.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("Test.txt", new String[]{"directory/test.txt"})); } @Test public void testUserInputWithLongPath() { String longUserInput = "a".repeat(260); // Assuming a long input - assertNotAttack(pathTraversalDetector.run(longUserInput, new String[]{"directory/test.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run(longUserInput, new String[]{"directory/test.txt"})); } @Test public void testUserInputWithEmptyFilePath() { - assertNotAttack(pathTraversalDetector.run("test", new String[]{""})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("test", new String[]{""})); } @Test public void testUserInputWithFilePathContainingSpaces() { - assertNotAttack(pathTraversalDetector.run("test file", new String[]{"directory/test file.txt"})); + assertNotAttack(PathTraversalDetector.INSTANCE.run("test file", new String[]{"directory/test file.txt"})); } } diff --git a/agent_api/src/test/java/vulnerabilities/ssrf/SSRFDetectorTest.java b/agent_api/src/test/java/vulnerabilities/ssrf/SSRFDetectorTest.java index 8cf258549..46e3ee37f 100644 --- a/agent_api/src/test/java/vulnerabilities/ssrf/SSRFDetectorTest.java +++ b/agent_api/src/test/java/vulnerabilities/ssrf/SSRFDetectorTest.java @@ -44,7 +44,7 @@ public void testSsrfDetectorWithRedirectTo127IP() throws MalformedURLException { URLCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test")); RedirectCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test"), new URL("http://127.0.0.1:8080")); - Attack attackData = new SSRFDetector().run( + Attack attackData = SSRFDetector.run( "127.0.0.1", 8080, List.of("127.0.0.1"), "testop" @@ -68,7 +68,7 @@ public void testSsrfDetectorWithRedirectTo127IPButHostnameCapitalizationDifferen URLCollector.report(new URL("http://Ssrf-redirects.testssandbox.com/ssrf-test")); RedirectCollector.report(new URL("http://ssrf-Redirects.testssandbox.com/ssrf-test"), new URL("http://127.0.0.1:8080")); - Attack attackData = new SSRFDetector().run( + Attack attackData = SSRFDetector.run( "127.0.0.1", 8080, List.of("127.0.0.1"), "testop" @@ -92,7 +92,7 @@ public void testSsrfDetectorWithRedirectToLocalhost() throws MalformedURLExcepti URLCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test")); RedirectCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test"), new URL("http://localhost")); - Attack attackData = new SSRFDetector().run( + Attack attackData = SSRFDetector.run( "localhost", 80, List.of("127.0.0.1"), "test2nd_op" @@ -119,7 +119,7 @@ public void testSsrfDetectorWithRedirectToLocalhostButIsRequestToItself() throws URLCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test")); RedirectCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test"), new URL("http://localhost")); - Attack attackData = new SSRFDetector().run( + Attack attackData = SSRFDetector.run( "localhost", 80, List.of("127.0.0.1"), "test2nd_op" @@ -136,7 +136,7 @@ public void testSsrfDetectorWithServiceHostnameInRedirect() throws MalformedURLE URLCollector.report(new URL("http://mysql-database/ssrf-test")); RedirectCollector.report(new URL("http://mysql-database/ssrf-test"), new URL("http://127.0.0.1:8080")); - Attack attackData = new SSRFDetector().run( + Attack attackData = SSRFDetector.run( "127.0.0.1", 8080, List.of("127.0.0.1"), "testop"