From 38ab7333472583f34025b2955939b24b2a7e142f Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Tue, 2 Dec 2025 02:20:24 +0100 Subject: [PATCH 01/17] e2e: update to new core standard --- end2end/server/mock_aikido_core.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/end2end/server/mock_aikido_core.py b/end2end/server/mock_aikido_core.py index 7bb2cff4..6238f574 100644 --- a/end2end/server/mock_aikido_core.py +++ b/end2end/server/mock_aikido_core.py @@ -44,6 +44,8 @@ } ], "blockedUserIds": ["12345"], + "blockNewOutgoingRequests": False, + "domains": [], "block": True, }, "lists": { From 74823ae3ca26f530ec00fae31383f68494684748 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Tue, 2 Dec 2025 02:28:09 +0100 Subject: [PATCH 02/17] Add Domain class & update APIEvent --- .../agent_api/background/cloud/api/APIResponse.java | 3 +++ .../agent_api/storage/service_configuration/Domain.java | 8 ++++++++ 2 files changed, 11 insertions(+) create mode 100644 agent_api/src/main/java/dev/aikido/agent_api/storage/service_configuration/Domain.java diff --git a/agent_api/src/main/java/dev/aikido/agent_api/background/cloud/api/APIResponse.java b/agent_api/src/main/java/dev/aikido/agent_api/background/cloud/api/APIResponse.java index 052e1589..07dc9f69 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/background/cloud/api/APIResponse.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/background/cloud/api/APIResponse.java @@ -1,6 +1,7 @@ package dev.aikido.agent_api.background.cloud.api; import dev.aikido.agent_api.background.Endpoint; +import dev.aikido.agent_api.storage.service_configuration.Domain; import java.util.List; @@ -11,6 +12,8 @@ public record APIResponse( List endpoints, List blockedUserIds, List allowedIPAddresses, + boolean blockNewOutgoingRequests, + List domains, boolean receivedAnyStats, boolean block ) { diff --git a/agent_api/src/main/java/dev/aikido/agent_api/storage/service_configuration/Domain.java b/agent_api/src/main/java/dev/aikido/agent_api/storage/service_configuration/Domain.java new file mode 100644 index 00000000..ac6d5eea --- /dev/null +++ b/agent_api/src/main/java/dev/aikido/agent_api/storage/service_configuration/Domain.java @@ -0,0 +1,8 @@ +package dev.aikido.agent_api.storage.service_configuration; + +public record Domain(String hostname, String mode) { + public boolean isBlockingMode() { + // mode can either be "allow" or "block" + return this.mode.equals("block"); + } +} From 7d6b71d60097ec7d140241bea5b8d6af1cd77051 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Tue, 2 Dec 2025 02:32:15 +0100 Subject: [PATCH 03/17] Store domains & block boolean in Service Config --- .../dev/aikido/agent_api/storage/ServiceConfiguration.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfiguration.java b/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfiguration.java index 3a7a7c3b..604f0fd6 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfiguration.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfiguration.java @@ -4,6 +4,7 @@ import dev.aikido.agent_api.background.cloud.api.APIResponse; import dev.aikido.agent_api.background.cloud.api.ReportingApi; import dev.aikido.agent_api.helpers.net.IPList; +import dev.aikido.agent_api.storage.service_configuration.Domain; import dev.aikido.agent_api.storage.service_configuration.ParsedFirewallLists; import dev.aikido.agent_api.storage.statistics.StatisticsStore; @@ -26,6 +27,8 @@ public class ServiceConfiguration { private IPList bypassedIPs = new IPList(); private HashSet blockedUserIDs = new HashSet<>(); private List endpoints = new ArrayList<>(); + private List domains = new ArrayList<>(); + private boolean blockNewOutgoingRequests = false; public ServiceConfiguration() { this.receivedAnyStats = true; // true by default, waiting for the startup event @@ -46,6 +49,10 @@ public void updateConfig(APIResponse apiResponse) { if (apiResponse.endpoints() != null) { this.endpoints = apiResponse.endpoints(); } + if (apiResponse.domains() != null) { + this.domains = apiResponse.domains(); + } + this.blockNewOutgoingRequests = apiResponse.blockNewOutgoingRequests(); this.receivedAnyStats = apiResponse.receivedAnyStats(); } From 6dac7ed6f122b893e1d04dbf7263918d0c020630 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Tue, 2 Dec 2025 02:38:10 +0100 Subject: [PATCH 04/17] ServiceConfig: add shouldBlockOutgoingRequests --- .../storage/ServiceConfiguration.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfiguration.java b/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfiguration.java index 604f0fd6..b782f92e 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfiguration.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfiguration.java @@ -8,9 +8,7 @@ import dev.aikido.agent_api.storage.service_configuration.ParsedFirewallLists; import dev.aikido.agent_api.storage.statistics.StatisticsStore; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; +import java.util.*; import static dev.aikido.agent_api.helpers.IPListBuilder.createIPList; import static dev.aikido.agent_api.vulnerabilities.ssrf.IsPrivateIP.isPrivateIp; @@ -27,7 +25,7 @@ public class ServiceConfiguration { private IPList bypassedIPs = new IPList(); private HashSet blockedUserIDs = new HashSet<>(); private List endpoints = new ArrayList<>(); - private List domains = new ArrayList<>(); + private Map domains = new HashMap<>(); private boolean blockNewOutgoingRequests = false; public ServiceConfiguration() { @@ -50,7 +48,12 @@ public void updateConfig(APIResponse apiResponse) { this.endpoints = apiResponse.endpoints(); } if (apiResponse.domains() != null) { - this.domains = apiResponse.domains(); + for (Domain domain : apiResponse.domains()) { + if (this.domains.get(domain.hostname()) != null) { + continue; // use first provided domain value + } + this.domains.put(domain.hostname(), domain); + } } this.blockNewOutgoingRequests = apiResponse.blockNewOutgoingRequests(); this.receivedAnyStats = apiResponse.receivedAnyStats(); @@ -134,4 +137,18 @@ public boolean isBlockedUserAgent(String userAgent) { public record BlockedResult(boolean blocked, String description) { } + + public boolean shouldBlockOutgoingRequest(String hostname) { + Domain matchingDomain = this.domains.get(hostname); + if (matchingDomain == null) { + return false; + } + + boolean isDomainBlocked = matchingDomain.isBlockingMode(); + if (this.blockNewOutgoingRequests) { + return isDomainBlocked; + } + + return isDomainBlocked; + } } From 2c23906d03de7be54093a03c24624f6b20d442d0 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Tue, 2 Dec 2025 02:40:50 +0100 Subject: [PATCH 05/17] ServiceConfigStore: add shouldBlockOutgoingRequest --- .../dev/aikido/agent_api/storage/ServiceConfigStore.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfigStore.java b/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfigStore.java index 41986919..472a4f72 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfigStore.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/storage/ServiceConfigStore.java @@ -90,4 +90,13 @@ public static void setMiddlewareInstalled(boolean middlewareInstalled) { mutex.writeLock().unlock(); } } + + public static boolean shouldBlockOutgoingRequest(String hostname) { + mutex.readLock().lock(); + try { + return config.shouldBlockOutgoingRequest(hostname); + } finally { + mutex.readLock().unlock(); + } + } } From c41d12b9455ca3922af87dd93146c138ee4c401b Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Tue, 2 Dec 2025 02:49:58 +0100 Subject: [PATCH 06/17] URLCollector: block based on hostname --- .../collectors/DNSRecordCollector.java | 1 + .../agent_api/collectors/URLCollector.java | 45 +++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) 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 d92b8e92..fa78c4e4 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 @@ -2,6 +2,7 @@ import dev.aikido.agent_api.context.Context; import dev.aikido.agent_api.storage.Hostnames; +import dev.aikido.agent_api.storage.ServiceConfigStore; import dev.aikido.agent_api.storage.statistics.OperationKind; import dev.aikido.agent_api.storage.statistics.StatisticsStore; import dev.aikido.agent_api.vulnerabilities.Attack; diff --git a/agent_api/src/main/java/dev/aikido/agent_api/collectors/URLCollector.java b/agent_api/src/main/java/dev/aikido/agent_api/collectors/URLCollector.java index d612d92d..a6b5b0e3 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/collectors/URLCollector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/collectors/URLCollector.java @@ -2,22 +2,31 @@ import dev.aikido.agent_api.context.Context; import dev.aikido.agent_api.context.ContextObject; +import dev.aikido.agent_api.context.User; import dev.aikido.agent_api.storage.HostnamesStore; import dev.aikido.agent_api.helpers.logging.LogManager; import dev.aikido.agent_api.helpers.logging.Logger; +import dev.aikido.agent_api.storage.ServiceConfigStore; +import dev.aikido.agent_api.vulnerabilities.Attack; +import dev.aikido.agent_api.vulnerabilities.Vulnerabilities; +import dev.aikido.agent_api.vulnerabilities.ssrf.SSRFException; import java.net.URL; +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.helpers.url.PortParser.getPortFromURL; +import static dev.aikido.agent_api.storage.AttackQueue.attackDetected; public final class URLCollector { private static final Logger logger = LogManager.getLogger(URLCollector.class); private URLCollector() {} - public static void report(URL url) { + public static void report(URL url, String operation) { if(url != null) { if (!url.getProtocol().startsWith("http")) { - return; // Non-HTTP(S) URL + return; // Non-HTTP(S) URL } logger.trace("Adding a new URL to the cache: %s", url); int port = getPortFromURL(url); @@ -25,13 +34,41 @@ public static void report(URL url) { // We store hostname and port in two places, HostnamesStore and Context. HostnamesStore is for reporting // outbound domains. Context is to have a map of hostnames with used port numbers to detect SSRF attacks. + // hostname blocking : + String hostname = url.getHost(); + if (ServiceConfigStore.shouldBlockOutgoingRequest(hostname)) { + ContextObject ctx = Context.get(); + + User currentUser = null; + if (ctx != null) { + currentUser = ctx.getUser(); + } + + Attack attack = new Attack( + operation, + Vulnerabilities.SSRF, + "", + "", + Map.of(), + /* payload */ hostname, + getCurrentStackTrace(), + currentUser + ); + + attackDetected(attack, ctx); + if (shouldBlock()) { + logger.debug("Blocking request to domain: %s", hostname); + throw SSRFException.get(); + } + }; + // Store (new) hostname hits - HostnamesStore.incrementHits(url.getHost(), port); + HostnamesStore.incrementHits(hostname, port); // Add to context : ContextObject context = Context.get(); if (context != null) { - context.getHostnames().add(url.getHost(), port); + context.getHostnames().add(hostname, port); Context.set(context); } } From f77d1ebe13f15f093776961631c8519bec5ff0e6 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Thu, 4 Dec 2025 01:19:49 +0100 Subject: [PATCH 07/17] fix bug in ReportingAPiHTTP after changes --- .../aikido/agent_api/background/cloud/api/ReportingApiHTTP.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent_api/src/main/java/dev/aikido/agent_api/background/cloud/api/ReportingApiHTTP.java b/agent_api/src/main/java/dev/aikido/agent_api/background/cloud/api/ReportingApiHTTP.java index 5f658fb1..190da623 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/background/cloud/api/ReportingApiHTTP.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/background/cloud/api/ReportingApiHTTP.java @@ -152,7 +152,7 @@ private static APIResponse getUnsuccessfulAPIResponse(String error) { return new APIResponse( false, // Success error, - 0, null, null, null, false, false // Unimportant values. + 0, null, null, null, false, null, false, false // Unimportant values. ); } } From 3ab05572c4e5725e124208b6d91c69a076d7cfff Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Thu, 4 Dec 2025 01:20:50 +0100 Subject: [PATCH 08/17] Add string operation param to RedirectCollector --- .../collectors/RedirectCollector.java | 6 +- .../ssrf/RedirectOriginFinderTest.java | 89 ++++++++++--------- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/agent_api/src/main/java/dev/aikido/agent_api/collectors/RedirectCollector.java b/agent_api/src/main/java/dev/aikido/agent_api/collectors/RedirectCollector.java index aca216ea..1cd48499 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/collectors/RedirectCollector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/collectors/RedirectCollector.java @@ -14,11 +14,11 @@ public final class RedirectCollector { private static final Logger logger = LogManager.getLogger(RedirectCollector.class); private RedirectCollector() {} - public static void report(URL origin, URL dest) { + public static void report(URL origin, URL dest, String operation) { logger.trace("Redirect detected: [Origin]<%s> -> [Destination]<%s>", origin, dest); ContextObject context = Context.get(); // Report destination URL : - URLCollector.report(dest); + URLCollector.report(dest, operation); // Add as a node : List redirectStarterNodes = context.getRedirectStartNodes(); @@ -41,4 +41,4 @@ public static void report(URL origin, URL dest) { context.addRedirectNode(starterNode); Context.set(context); // Update context. } -} \ No newline at end of file +} diff --git a/agent_api/src/test/java/vulnerabilities/ssrf/RedirectOriginFinderTest.java b/agent_api/src/test/java/vulnerabilities/ssrf/RedirectOriginFinderTest.java index 1f8428d4..5b694470 100644 --- a/agent_api/src/test/java/vulnerabilities/ssrf/RedirectOriginFinderTest.java +++ b/agent_api/src/test/java/vulnerabilities/ssrf/RedirectOriginFinderTest.java @@ -22,15 +22,15 @@ public void setup() { @Test public void testGetRedirectOrigin() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com"), "test-op"); assertNotNull(getRedirectOrigin("hackers.com", 443)); assertEquals("https://example.com", getRedirectOrigin("hackers.com", 443).toString()); } @Test public void testGetRedirectOrigin2() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com/2")); - RedirectCollector.report(new URL("https://example.com/2"), new URL("https://hackers.com/test")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com/2"), "test-op"); + RedirectCollector.report(new URL("https://example.com/2"), new URL("https://hackers.com/test"), "test-op"); assertEquals(1, Context.get().getRedirectStartNodes().size()); assertNotNull(getRedirectOrigin("hackers.com", 443)); assertEquals("https://example.com", getRedirectOrigin("hackers.com", 443).toString()); @@ -43,113 +43,113 @@ public void testGetRedirectNoRedirects() { @Test public void testGetRedirectOriginNotADestination() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com"), "test-op"); assertNull(getRedirectOrigin("example.com", 443)); } @Test public void testGetRedirectOriginNotInRedirects() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com"), "test-op"); assertNull(getRedirectOrigin("example.com", 443)); } @Test public void testGetRedirectOriginMultipleRedirects() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com/2")); - RedirectCollector.report(new URL("https://example.com/2"), new URL("https://hackers.com/test")); - RedirectCollector.report(new URL("https://hackers.com/test"), new URL("https://another.com")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com/2"), "test-op"); + RedirectCollector.report(new URL("https://example.com/2"), new URL("https://hackers.com/test"), "test-op"); + RedirectCollector.report(new URL("https://hackers.com/test"), new URL("https://another.com"), "test-op"); assertEquals("https://example.com", getRedirectOrigin("hackers.com", 443).toString()); } @Test public void testAvoidsInfiniteLoopsWithUnrelatedCyclicRedirects() throws MalformedURLException { - RedirectCollector.report(new URL("https://cycle.com/a"), new URL("https://cycle.com/b")); - RedirectCollector.report(new URL("https://cycle.com/b"), new URL("https://cycle.com/c")); - RedirectCollector.report(new URL("https://cycle.com/c"), new URL("https://cycle.com/a")); // Unrelated cycle - RedirectCollector.report(new URL("https://start.com"), new URL("https://middle.com")); // Relevant redirect - RedirectCollector.report(new URL("https://middle.com"), new URL("https://end.com")); // Relevant redirect + RedirectCollector.report(new URL("https://cycle.com/a"), new URL("https://cycle.com/b"), "test-op"); + RedirectCollector.report(new URL("https://cycle.com/b"), new URL("https://cycle.com/c"), "test-op"); + RedirectCollector.report(new URL("https://cycle.com/c"), new URL("https://cycle.com/a"), "test-op"); // Unrelated cycle + RedirectCollector.report(new URL("https://start.com"), new URL("https://middle.com"), "test-op"); // Relevant redirect + RedirectCollector.report(new URL("https://middle.com"), new URL("https://end.com"), "test-op"); // Relevant redirect assertEquals("https://start.com", getRedirectOrigin("end.com", 443).toString()); } @Test public void testHandlesMultipleRequestsWithOverlappingRedirects() throws MalformedURLException { - RedirectCollector.report(new URL("https://site1.com"), new URL("https://site2.com")); - RedirectCollector.report(new URL("https://site2.com"), new URL("https://site3.com")); - RedirectCollector.report(new URL("https://site3.com"), new URL("https://site1.com")); // Cycle - RedirectCollector.report(new URL("https://origin.com"), new URL("https://destination.com")); // Relevant redirect + RedirectCollector.report(new URL("https://site1.com"), new URL("https://site2.com"), "test-op"); + RedirectCollector.report(new URL("https://site2.com"), new URL("https://site3.com"), "test-op"); + RedirectCollector.report(new URL("https://site3.com"), new URL("https://site1.com"), "test-op"); // Cycle + RedirectCollector.report(new URL("https://origin.com"), new URL("https://destination.com"), "test-op"); // Relevant redirect assertEquals("https://origin.com", getRedirectOrigin("destination.com", 443).toString()); } @Test public void testAvoidsInfiniteLoopsWhenCyclesArePartOfTheRedirectChain() throws MalformedURLException { - RedirectCollector.report(new URL("https://start.com"), new URL("https://loop.com/a")); - RedirectCollector.report(new URL("https://loop.com/a"), new URL("https://loop.com/b")); - RedirectCollector.report(new URL("https://loop.com/b"), new URL("https://loop.com/c")); - RedirectCollector.report(new URL("https://loop.com/c"), new URL("https://loop.com/a")); // Cycle here + RedirectCollector.report(new URL("https://start.com"), new URL("https://loop.com/a"), "test-op"); + RedirectCollector.report(new URL("https://loop.com/a"), new URL("https://loop.com/b"), "test-op"); + RedirectCollector.report(new URL("https://loop.com/b"), new URL("https://loop.com/c"), "test-op"); + RedirectCollector.report(new URL("https://loop.com/c"), new URL("https://loop.com/a"), "test-op"); // Cycle here assertEquals("https://start.com", getRedirectOrigin("loop.com", 443).toString()); } @Test public void testRedirectsWithQueryParameters() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com?param=value")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com?param=value"), "test-op"); assertEquals("https://example.com", getRedirectOrigin("example.com", 443).toString()); } @Test public void testRedirectsWithFragmentIdentifiers() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com#section")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com#section"), "test-op"); assertEquals("https://example.com", getRedirectOrigin("example.com", 443).toString()); } @Test public void testRedirectsWithDifferentProtocols() throws MalformedURLException { - RedirectCollector.report(new URL("http://example.com"), new URL("https://example.com")); + RedirectCollector.report(new URL("http://example.com"), new URL("https://example.com"), "test-op"); assertEquals("http://example.com", getRedirectOrigin("example.com", 443).toString()); } @Test public void testRedirectsWithDifferentPorts() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com:8080")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com:8080"), "test-op"); assertEquals("https://example.com", getRedirectOrigin("example.com", 8080).toString()); } @Test public void testRedirectsWithPaths() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com/home")); - RedirectCollector.report(new URL("https://example.com/home"), new URL("https://example.com/home/welcome")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com/home"), "test-op"); + RedirectCollector.report(new URL("https://example.com/home"), new URL("https://example.com/home/welcome"), "test-op"); assertEquals("https://example.com", getRedirectOrigin("example.com", 443).toString()); } @Test public void testMultipleRedirectsToSameDestination() throws MalformedURLException { - RedirectCollector.report(new URL("https://a.com"), new URL("https://d.com")); - RedirectCollector.report(new URL("https://b.com"), new URL("https://d.com")); - RedirectCollector.report(new URL("https://c.com"), new URL("https://d.com")); + RedirectCollector.report(new URL("https://a.com"), new URL("https://d.com"), "test-op"); + RedirectCollector.report(new URL("https://b.com"), new URL("https://d.com"), "test-op"); + RedirectCollector.report(new URL("https://c.com"), new URL("https://d.com"), "test-op"); assertEquals("https://a.com", getRedirectOrigin("d.com", 443).toString()); } @Test public void testMultipleRedirectPathsToSameUrl() throws MalformedURLException { - RedirectCollector.report(new URL("https://x.com"), new URL("https://y.com")); - RedirectCollector.report(new URL("https://y.com"), new URL("https://z.com")); - RedirectCollector.report(new URL("https://a.com"), new URL("https://b.com")); - RedirectCollector.report(new URL("https://b.com"), new URL("https://z.com")); + RedirectCollector.report(new URL("https://x.com"), new URL("https://y.com"), "test-op"); + RedirectCollector.report(new URL("https://y.com"), new URL("https://z.com"), "test-op"); + RedirectCollector.report(new URL("https://a.com"), new URL("https://b.com"), "test-op"); + RedirectCollector.report(new URL("https://b.com"), new URL("https://z.com"), "test-op"); assertEquals("https://x.com", getRedirectOrigin("z.com", 443).toString()); } @Test public void testReturnsUndefinedWhenSourceAndDestinationAreSameUrl() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com"), "test-op"); assertEquals("https://example.com", getRedirectOrigin("example.com", 443).toString()); } @@ -159,7 +159,8 @@ public void testHandlesVeryLongRedirectChains() throws MalformedURLException { for (int i = 0; i < 100; i++) { RedirectCollector.report( new URL("https://example.com/" + i), - new URL("https://example.com/" + (i + 1)) + new URL("https://example.com/" + (i + 1)), + , "test-op" ); } @@ -168,35 +169,35 @@ public void testHandlesVeryLongRedirectChains() throws MalformedURLException { @Test public void testHandlesRedirectsWithCyclesLongerThanOneRedirect() throws MalformedURLException { - RedirectCollector.report(new URL("https://a.com"), new URL("https://b.com")); - RedirectCollector.report(new URL("https://b.com"), new URL("https://c.com")); - RedirectCollector.report(new URL("https://c.com"), new URL("https://a.com")); // Cycle + RedirectCollector.report(new URL("https://a.com"), new URL("https://b.com"), "test-op"); + RedirectCollector.report(new URL("https://b.com"), new URL("https://c.com"), "test-op"); + RedirectCollector.report(new URL("https://c.com"), new URL("https://a.com"), "test-op"); // Cycle assertEquals("https://a.com", getRedirectOrigin("a.com", 443).toString()); } @Test public void testHandlesRedirectsWithDifferentQueryParameters() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com?param=1")); - RedirectCollector.report(new URL("https://example.com?param=1"), new URL("https://example.com?param=2")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://example.com?param=1"), "test-op"); + RedirectCollector.report(new URL("https://example.com?param=1"), new URL("https://example.com?param=2"), "test-op"); assertEquals("https://example.com", getRedirectOrigin("example.com", 443).toString()); } @Test public void testRedirectWithMatchingPort() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com:443")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com:443"), "test-op"); assertNotNull(getRedirectOrigin("hackers.com", 443)); assertEquals("https://example.com", getRedirectOrigin("hackers.com", 443).toString()); } @Test public void testRedirectWithNonMatchingPort() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com:442")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com:442"), "test-op"); assertNull(getRedirectOrigin("hackers.com", 443)); } @Test public void testRedirectWithNonMatchingPort2() throws MalformedURLException { - RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com")); + RedirectCollector.report(new URL("https://example.com"), new URL("https://hackers.com"), "test-op"); assertNull(getRedirectOrigin("hackers.com", 442)); } } From c08c0071b4a57e559ac81f9e591ae6129d32dd83 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Thu, 4 Dec 2025 01:23:11 +0100 Subject: [PATCH 09/17] OkHttp & Apache: pass along operation --- .../java/dev/aikido/agent/wrappers/ApacheHttpClientWrapper.java | 2 +- .../src/main/java/dev/aikido/agent/wrappers/OkHttpWrapper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/agent/src/main/java/dev/aikido/agent/wrappers/ApacheHttpClientWrapper.java b/agent/src/main/java/dev/aikido/agent/wrappers/ApacheHttpClientWrapper.java index 5b73db4b..d6db0373 100644 --- a/agent/src/main/java/dev/aikido/agent/wrappers/ApacheHttpClientWrapper.java +++ b/agent/src/main/java/dev/aikido/agent/wrappers/ApacheHttpClientWrapper.java @@ -49,7 +49,7 @@ public static void before( } if (uri != null) { // Report the URL : - URLCollector.report(uri.toURL()); + URLCollector.report(uri.toURL(), "org.apache.http.HttpClient.execute"); } } } diff --git a/agent/src/main/java/dev/aikido/agent/wrappers/OkHttpWrapper.java b/agent/src/main/java/dev/aikido/agent/wrappers/OkHttpWrapper.java index ee4f30c6..cd9a18eb 100644 --- a/agent/src/main/java/dev/aikido/agent/wrappers/OkHttpWrapper.java +++ b/agent/src/main/java/dev/aikido/agent/wrappers/OkHttpWrapper.java @@ -50,7 +50,7 @@ public static void before( URL url = (URL) toUrlMethod.invoke(urlObject); // Report the URL - URLCollector.report(url); + URLCollector.report(url, "okhttp3.OkHttpClient.newCall"); } } } From 713685b495e656febad921a9b1b35999662d8ec1 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Thu, 4 Dec 2025 01:24:11 +0100 Subject: [PATCH 10/17] HttpURLConnectionWrapper: report operation --- .../dev/aikido/agent/wrappers/HttpURLConnectionWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/src/main/java/dev/aikido/agent/wrappers/HttpURLConnectionWrapper.java b/agent/src/main/java/dev/aikido/agent/wrappers/HttpURLConnectionWrapper.java index fde7530f..a376bd1c 100644 --- a/agent/src/main/java/dev/aikido/agent/wrappers/HttpURLConnectionWrapper.java +++ b/agent/src/main/java/dev/aikido/agent/wrappers/HttpURLConnectionWrapper.java @@ -53,7 +53,7 @@ public static void before( // Run report with "argument" for (Method method2: clazz.getMethods()) { if(method2.getName().equals("report")) { - method2.invoke(null, url); + method2.invoke(null, url, "HttpUrlConnection"); break; } } From 4d11503f2d0800c4612230e1b3b323651bd78894 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Thu, 4 Dec 2025 01:26:48 +0100 Subject: [PATCH 11/17] fix broken test case due to two , in RedirectOriginFinderTest.java --- .../java/vulnerabilities/ssrf/RedirectOriginFinderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent_api/src/test/java/vulnerabilities/ssrf/RedirectOriginFinderTest.java b/agent_api/src/test/java/vulnerabilities/ssrf/RedirectOriginFinderTest.java index 5b694470..c804ca72 100644 --- a/agent_api/src/test/java/vulnerabilities/ssrf/RedirectOriginFinderTest.java +++ b/agent_api/src/test/java/vulnerabilities/ssrf/RedirectOriginFinderTest.java @@ -160,7 +160,7 @@ public void testHandlesVeryLongRedirectChains() throws MalformedURLException { RedirectCollector.report( new URL("https://example.com/" + i), new URL("https://example.com/" + (i + 1)), - , "test-op" + "test-op" ); } From 4ae3d7e9ee319968126bce732ff20febf86f9cd7 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Thu, 4 Dec 2025 01:30:28 +0100 Subject: [PATCH 12/17] Fix test cases in ShouldBlockRequestTest --- agent_api/src/test/java/ShouldBlockRequestTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent_api/src/test/java/ShouldBlockRequestTest.java b/agent_api/src/test/java/ShouldBlockRequestTest.java index a03f6294..92b3cb89 100644 --- a/agent_api/src/test/java/ShouldBlockRequestTest.java +++ b/agent_api/src/test/java/ShouldBlockRequestTest.java @@ -87,7 +87,7 @@ public void testUserSet() throws SQLException { ServiceConfigStore.updateFromAPIResponse(new APIResponse( true, "", getUnixTimeMS(), List.of(), /* blockedUserIds */ List.of("ID1", "ID2", "ID3"), List.of(), - false, true + false, null, false, true )); var res2 = ShouldBlockRequest.shouldBlockRequest(); assertTrue(res2.block()); @@ -227,7 +227,7 @@ public void testBlockedUserWithMultipleEndpoints() throws SQLException { ); List blockedUserIds = List.of("ID1"); ServiceConfigStore.updateFromAPIResponse(new APIResponse( - true, "", getUnixTimeMS(), endpoints, blockedUserIds, List.of(), true, false + true, "", getUnixTimeMS(), endpoints, blockedUserIds, List.of(), false, null,true, false )); // Call the method From 503a961866b763bbfbd6a67c1356663a141a35eb Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Thu, 4 Dec 2025 01:32:43 +0100 Subject: [PATCH 13/17] Fix test cases for SSRFDetectorTest --- .../ssrf/SSRFDetectorTest.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/agent_api/src/test/java/vulnerabilities/ssrf/SSRFDetectorTest.java b/agent_api/src/test/java/vulnerabilities/ssrf/SSRFDetectorTest.java index 1d013535..3e94d62e 100644 --- a/agent_api/src/test/java/vulnerabilities/ssrf/SSRFDetectorTest.java +++ b/agent_api/src/test/java/vulnerabilities/ssrf/SSRFDetectorTest.java @@ -55,8 +55,8 @@ public void testSsrfDetectorWithRedirectTo127IP() throws MalformedURLException { // Setup context : setContextAndLifecycle("http://ssrf-redirects.testssandbox.com/ssrf-test"); - 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")); + URLCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test"), "test"); + RedirectCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test"), new URL("http://127.0.0.1:8080"), "test"); Attack attackData = SSRFDetector.run( "127.0.0.1", 8080, List.of("127.0.0.1"), @@ -79,8 +79,8 @@ public void testSsrfDetectorWithRedirectTo127IPButHostnameCapitalizationDifferen // Setup context : setContextAndLifecycle("http://Ssrf-redirects.testssandbox.com/ssrf-test"); - 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")); + URLCollector.report(new URL("http://Ssrf-redirects.testssandbox.com/ssrf-test"), "test"); + RedirectCollector.report(new URL("http://ssrf-Redirects.testssandbox.com/ssrf-test"), new URL("http://127.0.0.1:8080"), "test"); Attack attackData = SSRFDetector.run( "127.0.0.1", 8080, List.of("127.0.0.1"), @@ -103,8 +103,8 @@ public void testSsrfDetectorWithRedirectToLocalhost() throws MalformedURLExcepti // Setup context : setContextAndLifecycle("http://ssrf-redirects.testssandbox.com/"); - 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")); + URLCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test"), "test"); + RedirectCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test"), new URL("http://localhost"), "test"); Attack attackData = SSRFDetector.run( "localhost", 80, List.of("127.0.0.1"), @@ -130,8 +130,8 @@ public void testSsrfDetectorWithRedirectToLocalhostButIsRequestToItself() throws "http://ssrf-redirects.testssandbox.com/examplesite")); // url - 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")); + URLCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test"), "test"); + RedirectCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test"), new URL("http://localhost"), "test"); Attack attackData = SSRFDetector.run( "localhost", 80, List.of("127.0.0.1"), @@ -147,8 +147,8 @@ public void testSsrfDetectorWithServiceHostnameInRedirect() throws MalformedURLE // Setup context : setContextAndLifecycle("http://mysql-database/ssrf-test"); - 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")); + URLCollector.report(new URL("http://mysql-database/ssrf-test"), "test"); + RedirectCollector.report(new URL("http://mysql-database/ssrf-test"), new URL("http://127.0.0.1:8080"), "test"); Attack attackData = SSRFDetector.run( "127.0.0.1", 8080, List.of("127.0.0.1"), @@ -164,8 +164,8 @@ public void testSsrfDetectorForcedProtectionOff() throws MalformedURLException { // Setup context : setContextAndLifecycle("http://ssrf-redirects.testssandbox.com/", "/api2/forced-off-route"); - 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")); + URLCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test"), "test"); + RedirectCollector.report(new URL("http://ssrf-redirects.testssandbox.com/ssrf-test"), new URL("http://localhost"), "test"); Attack attackData = SSRFDetector.run( "localhost", 80, List.of("127.0.0.1"), From 6faea11ff57fcb6df5c9b2575e63e3027d711f40 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Thu, 4 Dec 2025 01:34:20 +0100 Subject: [PATCH 14/17] Fix test cases for URLCollectorTest --- .../test/java/collectors/URLCollectorTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/agent_api/src/test/java/collectors/URLCollectorTest.java b/agent_api/src/test/java/collectors/URLCollectorTest.java index cc6551c4..c0699fa5 100644 --- a/agent_api/src/test/java/collectors/URLCollectorTest.java +++ b/agent_api/src/test/java/collectors/URLCollectorTest.java @@ -38,8 +38,8 @@ private void setContextAndLifecycle(String url) { @Test public void testNewUrlConnectionWithPort() throws IOException { setContextAndLifecycle(""); - - URLCollector.report(new URL("http://localhost:8080")); + + URLCollector.report(new URL("http://localhost:8080"), "test"); Hostnames.HostnameEntry[] hostnameArray = HostnamesStore.getHostnamesAsList(); assertEquals(1, hostnameArray.length); assertEquals(8080, hostnameArray[0].getPort()); @@ -49,7 +49,7 @@ public void testNewUrlConnectionWithPort() throws IOException { @Test public void testNewUrlConnectionWithHttp() throws IOException { setContextAndLifecycle(""); - URLCollector.report(new URL("http://app.local.aikido.io")); + URLCollector.report(new URL("http://app.local.aikido.io"), "test"); Hostnames.HostnameEntry[] hostnameArray = HostnamesStore.getHostnamesAsList(); assertEquals(1, hostnameArray.length); assertEquals(80, hostnameArray[0].getPort()); @@ -64,7 +64,7 @@ public void testNewUrlConnectionWithHttp() throws IOException { @Test public void testNewUrlConnectionHttps() throws IOException { setContextAndLifecycle(""); - URLCollector.report(new URL("https://aikido.dev")); + URLCollector.report(new URL("https://aikido.dev"), "test"); Hostnames.HostnameEntry[] hostnameArray = HostnamesStore.getHostnamesAsList(); assertEquals(1, hostnameArray.length); assertEquals(443, hostnameArray[0].getPort()); @@ -79,7 +79,7 @@ public void testNewUrlConnectionHttps() throws IOException { @Test public void testNewUrlConnectionFaultyProtocol() throws IOException { setContextAndLifecycle(""); - URLCollector.report(new URL("ftp://localhost:8080")); + URLCollector.report(new URL("ftp://localhost:8080"), "test"); Hostnames.HostnameEntry[] hostnameArray = HostnamesStore.getHostnamesAsList(); assertEquals(0, hostnameArray.length); Hostnames.HostnameEntry[] hostnameArray2 = Context.get().getHostnames().asArray(); @@ -89,7 +89,7 @@ public void testNewUrlConnectionFaultyProtocol() throws IOException { @Test public void testWithNullURL() throws IOException { setContextAndLifecycle(""); - URLCollector.report(null); + URLCollector.report(null, "test"); Hostnames.HostnameEntry[] hostnameArray = HostnamesStore.getHostnamesAsList(); assertEquals(0, hostnameArray.length); Hostnames.HostnameEntry[] hostnameArray2 = Context.get().getHostnames().asArray(); @@ -100,7 +100,7 @@ public void testWithNullURL() throws IOException { public void testWithNullContext() throws IOException { setContextAndLifecycle(""); Context.reset(); - URLCollector.report(new URL("https://aikido.dev")); + URLCollector.report(new URL("https://aikido.dev"), "test"); Hostnames.HostnameEntry[] hostnameArray = HostnamesStore.getHostnamesAsList(); assertEquals(1, hostnameArray.length); assertEquals(443, hostnameArray[0].getPort()); @@ -112,10 +112,10 @@ public void testWithNullContext() throws IOException { public void testOnlyContext() throws IOException { setContextAndLifecycle(""); HostnamesStore.clear(); - URLCollector.report(new URL("https://aikido.dev")); + URLCollector.report(new URL("https://aikido.dev"), "test"); Hostnames.HostnameEntry[] hostnameArray = Context.get().getHostnames().asArray(); assertEquals(1, hostnameArray.length); assertEquals(443, hostnameArray[0].getPort()); assertEquals("aikido.dev", hostnameArray[0].getHostname()); } -} \ No newline at end of file +} From 4383c6eb2db6cfde159a15d13746588a4fec8d02 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Thu, 4 Dec 2025 01:36:16 +0100 Subject: [PATCH 15/17] Fix test cases for WebRequestCollectorTest --- .../src/test/java/collectors/WebRequestCollectorTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/agent_api/src/test/java/collectors/WebRequestCollectorTest.java b/agent_api/src/test/java/collectors/WebRequestCollectorTest.java index 75999d50..b7d04e9f 100644 --- a/agent_api/src/test/java/collectors/WebRequestCollectorTest.java +++ b/agent_api/src/test/java/collectors/WebRequestCollectorTest.java @@ -212,7 +212,7 @@ void testReport_userAgentBlocked_Ip_Bypassed() { List bypassedIps = List.of("192.168.1.1"); ServiceConfigStore.updateFromAPIResponse(new APIResponse( - true, "", getUnixTimeMS(), List.of(), List.of(), bypassedIps, true, false + true, "", getUnixTimeMS(), List.of(), List.of(), bypassedIps, false, null, true, false )); @@ -231,7 +231,7 @@ void testReport_ipBlockedUsingLists_Ip_Bypassed() { List bypassedIps = List.of("192.168.1.1"); ServiceConfigStore.updateFromAPIResponse(new APIResponse( - true, "", getUnixTimeMS(), List.of(), List.of(), bypassedIps, true, false + true, "", getUnixTimeMS(), List.of(), List.of(), bypassedIps, false, null, true, false )); WebRequestCollector.Res response = WebRequestCollector.report(contextObject); @@ -251,7 +251,7 @@ void testReport_ipNotAllowedUsingLists_Ip_Bypassed() { List bypassedIps = List.of("192.168.1.1"); ServiceConfigStore.updateFromAPIResponse(new APIResponse( - true, "", getUnixTimeMS(), List.of(), List.of(), bypassedIps, true, false + true, "", getUnixTimeMS(), List.of(), List.of(), bypassedIps, false, null, true, false )); From b4199a48afb7e46ebf774260029880c9b83fff9f Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Thu, 4 Dec 2025 07:38:58 +0100 Subject: [PATCH 16/17] Fix ServiceConfigurationTest test cases --- .../java/storage/ServiceConfigurationTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/agent_api/src/test/java/storage/ServiceConfigurationTest.java b/agent_api/src/test/java/storage/ServiceConfigurationTest.java index c1703c30..99fd276e 100644 --- a/agent_api/src/test/java/storage/ServiceConfigurationTest.java +++ b/agent_api/src/test/java/storage/ServiceConfigurationTest.java @@ -33,6 +33,8 @@ public void testUpdateConfig() { List.of(mock(Endpoint.class)), List.of("user1", "user2"), List.of("192.168.1.1"), + false, + null, true, true ); @@ -62,6 +64,8 @@ public void testUpdateConfigWithUnsuccessfulResponse() { null, null, false, + null, + false, false ); @@ -301,6 +305,8 @@ public void testReceivedAnyStats() { null, null, false, + null, + false, true ); @@ -318,6 +324,8 @@ public void testIsIpBypassedWithEmptyBypassedList() { null, null, Collections.emptyList(), + false, + null, true, true )); @@ -334,6 +342,8 @@ public void testIsIpBypassedWithMultipleBypassedEntries() { null, null, List.of("192.168.1.1", "192.168.1.2"), + false, + null, true, true ); @@ -354,6 +364,8 @@ public void testIsUserBlockedWithEmptyBlockedUserList() { null, Collections.emptyList(), null, + false, + null, true, true )); @@ -370,6 +382,8 @@ public void testIsUserBlockedWithMultipleBlockedUsers() { null, List.of("user1", "user2"), null, + false, + null, true, true ); @@ -389,6 +403,8 @@ public void testGetEndpoints() { List.of(mock(Endpoint.class)), null, null, + false, + null, true, true ); @@ -407,6 +423,8 @@ public void testGetEndpointsWithEmptyList() { Collections.emptyList(), null, null, + false, + null, true, true ); From bf4ccd7835f5050d7f1127fffe3ec5a511943240 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Thu, 4 Dec 2025 07:46:22 +0100 Subject: [PATCH 17/17] Fix EmptyAPIResponses: add empty bool & domains --- agent_api/src/test/java/utils/EmptyAPIResponses.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent_api/src/test/java/utils/EmptyAPIResponses.java b/agent_api/src/test/java/utils/EmptyAPIResponses.java index 091631a8..ea98520c 100644 --- a/agent_api/src/test/java/utils/EmptyAPIResponses.java +++ b/agent_api/src/test/java/utils/EmptyAPIResponses.java @@ -12,14 +12,14 @@ public class EmptyAPIResponses { public final static APIResponse emptyAPIResponse = new APIResponse( - true, "", UnixTimeMS.getUnixTimeMS(), List.of(), List.of(), List.of(), true, false + true, "", UnixTimeMS.getUnixTimeMS(), List.of(), List.of(), List.of(), false, null,true, false ); public final static ReportingApi.APIListsResponse emptyAPIListsResponse = new ReportingApi.APIListsResponse( List.of(), List.of(), List.of(), null, null, List.of() ); public static void setEmptyConfigWithEndpointList(List endpoints) { ServiceConfigStore.updateFromAPIResponse(new APIResponse( - true, "", getUnixTimeMS(), endpoints, List.of(), List.of(), true, false + true, "", getUnixTimeMS(), endpoints, List.of(), List.of(), false, null, true, false )); } }