From 3d2a72458d5ec7dbb87e354dd5f4eb312c895f7b Mon Sep 17 00:00:00 2001 From: BitterPanda Date: Mon, 15 Sep 2025 16:36:49 +0200 Subject: [PATCH 1/2] remove brackets from IPv6 address --- .../helpers/extraction/IPV6BracketsHelper.java | 10 ++++++++++ .../dev/aikido/agent_api/helpers/net/IPValidator.java | 3 +++ .../agent_api/helpers/net/ProxyForwardedParser.java | 11 ++++++++--- .../test/java/helpers/ProxyForwardedParserTest.java | 7 +++++++ 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 agent_api/src/main/java/dev/aikido/agent_api/helpers/extraction/IPV6BracketsHelper.java diff --git a/agent_api/src/main/java/dev/aikido/agent_api/helpers/extraction/IPV6BracketsHelper.java b/agent_api/src/main/java/dev/aikido/agent_api/helpers/extraction/IPV6BracketsHelper.java new file mode 100644 index 000000000..8c0a101a5 --- /dev/null +++ b/agent_api/src/main/java/dev/aikido/agent_api/helpers/extraction/IPV6BracketsHelper.java @@ -0,0 +1,10 @@ +package dev.aikido.agent_api.helpers.extraction; + +public class IPV6BracketsHelper { + public static String removeIfExistsIPv6Brackets(String ip) { + if (ip.startsWith("[") && ip.endsWith("]")) { + return ip.substring(1, ip.length()-1); + } + return ip; + } +} diff --git a/agent_api/src/main/java/dev/aikido/agent_api/helpers/net/IPValidator.java b/agent_api/src/main/java/dev/aikido/agent_api/helpers/net/IPValidator.java index 16acf9c44..875fb49ee 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/helpers/net/IPValidator.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/helpers/net/IPValidator.java @@ -2,6 +2,8 @@ import java.util.regex.Pattern; +import static dev.aikido.agent_api.helpers.extraction.IPV6BracketsHelper.removeIfExistsIPv6Brackets; + /** * Validates IP Addresses * Copied over from : https://github.com/validatorjs/validator.js/blob/master/src/lib/isIP.js @@ -57,6 +59,7 @@ public static boolean isIP(String str, String version) { if (str == null || str.isEmpty()) { return false; } + str = removeIfExistsIPv6Brackets(str); if (version == null || version.isEmpty()) { return isIP(str, "4") || isIP(str, "6"); } diff --git a/agent_api/src/main/java/dev/aikido/agent_api/helpers/net/ProxyForwardedParser.java b/agent_api/src/main/java/dev/aikido/agent_api/helpers/net/ProxyForwardedParser.java index 3ec7b80fb..a22b33b30 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/helpers/net/ProxyForwardedParser.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/helpers/net/ProxyForwardedParser.java @@ -6,20 +6,25 @@ import java.util.List; import static dev.aikido.agent_api.context.ContextObject.getHeader; +import static dev.aikido.agent_api.helpers.extraction.IPV6BracketsHelper.removeIfExistsIPv6Brackets; public class ProxyForwardedParser { public static String getIpFromRequest(String rawIp, HashMap> headers) { + String ip = rawIp; + String ipHeader = getHeader(headers, getIpHeaderName()); if (ipHeader != null && !ipHeader.isEmpty() && trustProxy()) { // Parse ip header and return the correct IP : String ipHeaderValue = extractIpFromHeader(ipHeader); if (ipHeaderValue != null) { - return ipHeaderValue; + ip = ipHeaderValue; } } - // If no valid IP was found, or if X-Forwarded-For was not present, default to raw ip: - return rawIp; + // Aikido core cannot handle the [ ] in the request's IP, so we parse them away here : + ip = removeIfExistsIPv6Brackets(ip); + + return ip; } /** diff --git a/agent_api/src/test/java/helpers/ProxyForwardedParserTest.java b/agent_api/src/test/java/helpers/ProxyForwardedParserTest.java index 22ee0b884..9467738a8 100644 --- a/agent_api/src/test/java/helpers/ProxyForwardedParserTest.java +++ b/agent_api/src/test/java/helpers/ProxyForwardedParserTest.java @@ -39,6 +39,13 @@ void testGetIpFromRequest_ValidXForwardedForWithIPv6() { assertEquals("2001:db8::1", result); } + @Test + void testGetIpFromRequest_ValidXForwardedForWithIPv6AndBrackets() { + headers.put("X-Forwarded-For", List.of("[2001:db8::1], 203.0.113.5")); + String result = getIpFromRequest("10.0.0.1", headers); + assertEquals("2001:db8::1", result); + } + @Test void testGetIpFromRequest_InvalidXForwardedFor() { headers.put("X-Forwarded-For", List.of("invalid.ip.address, 203.0.113.5")); From 4ba9be86254a939ca326465b5a2d9ee818e900f7 Mon Sep 17 00:00:00 2001 From: BitterPanda Date: Mon, 15 Sep 2025 16:37:55 +0200 Subject: [PATCH 2/2] add some extra test cases for the half brackets --- .../java/helpers/ProxyForwardedParserTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/agent_api/src/test/java/helpers/ProxyForwardedParserTest.java b/agent_api/src/test/java/helpers/ProxyForwardedParserTest.java index 9467738a8..7ba430211 100644 --- a/agent_api/src/test/java/helpers/ProxyForwardedParserTest.java +++ b/agent_api/src/test/java/helpers/ProxyForwardedParserTest.java @@ -46,6 +46,20 @@ void testGetIpFromRequest_ValidXForwardedForWithIPv6AndBrackets() { assertEquals("2001:db8::1", result); } + @Test + void testGetIpFromRequest_ValidXForwardedForWithIPv6AndBracketsHalf() { + headers.put("X-Forwarded-For", List.of("[2001:db8::1, 203.0.113.5")); + String result = getIpFromRequest("10.0.0.1", headers); + assertEquals("203.0.113.5", result); + } + + @Test + void testGetIpFromRequest_ValidXForwardedForWithIPv6AndBracketsHalf2() { + headers.put("X-Forwarded-For", List.of("2001:db8::1], 203.0.113.5")); + String result = getIpFromRequest("10.0.0.1", headers); + assertEquals("203.0.113.5", result); + } + @Test void testGetIpFromRequest_InvalidXForwardedFor() { headers.put("X-Forwarded-For", List.of("invalid.ip.address, 203.0.113.5"));