From aaefbefdd817f93967e2c9baf9a2e30f6a639c87 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Mon, 16 Dec 2024 14:02:41 +0530 Subject: [PATCH 1/6] Disable url encoding --- .../apache/httpclient/ApacheHttpClientWrapper.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java index 7e9cac4a7..178c0fe6f 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java @@ -245,14 +245,7 @@ private HttpUriRequest buildIastFuzzRequest(HttpRequest httpRequest, String endp if (StringUtils.isBlank(requestUrl)) { throw new ApacheHttpExceptionWrapper("Request URL is empty"); } - String path = StringUtils.substringBefore(requestUrl, SEPARATOR_QUESTION_MARK); - uriBuilder.setPath(path); - String queryString = StringUtils.substringAfter(requestUrl, SEPARATOR_QUESTION_MARK); - if (StringUtils.isNotBlank(queryString)) { - //Use of this deprecated method is intentional as we are building the query string exactly as provided by SE. - uriBuilder.setQuery(queryString); - } - requestBuilder.setUri(uriBuilder.build()); + requestBuilder.setUri(requestUrl); if(StringUtils.startsWith(httpRequest.getContentType(), APPLICATION_X_WWW_FORM_URLENCODED)){ requestBuilder.setEntity(new UrlEncodedFormEntity(buildFormParameters(httpRequest.getParameterMap()))); } From 7275b996d24dddaa93261e267e6a90ba78d5eb4e Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Mon, 16 Dec 2024 14:56:27 +0530 Subject: [PATCH 2/6] Minor log fix --- .../intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java index 178c0fe6f..c53ff2f7b 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java @@ -233,7 +233,7 @@ public ReadResult execute(HttpRequest httpRequest, String endpoint, String fuzzR } catch (IOException hostConnectException) { String message = "IOException Error while executing request %s: %s message : %s"; logger.log(LogLevel.FINE, String.format(message, fuzzRequestId, request, hostConnectException.getMessage()), ApacheHttpClientWrapper.class.getName()); - logger.postLogMessageIfNecessary(LogLevel.WARNING, String.format(message, request, hostConnectException.getMessage()), hostConnectException, ApacheHttpClientWrapper.class.getName()); + logger.postLogMessageIfNecessary(LogLevel.WARNING, String.format(message, fuzzRequestId, request, hostConnectException.getMessage()), hostConnectException, ApacheHttpClientWrapper.class.getName()); throw hostConnectException; } } From c92389415584945c4fdc829f3de1b56a2267ef80 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Mon, 16 Dec 2024 16:28:07 +0530 Subject: [PATCH 3/6] fix endpoint selection --- .../httpclient/ApacheHttpClientWrapper.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java index c53ff2f7b..690a44dda 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java @@ -58,6 +58,7 @@ public class ApacheHttpClientWrapper { public static final String SEPARATOR_QUESTION_MARK = "?"; + public static final String SUFFIX_SLASH = "/"; private final ApacheProxyManager proxyManager; private final PoolingHttpClientConnectionManager connectionManager; private final CloseableHttpClient httpClient; @@ -240,12 +241,11 @@ public ReadResult execute(HttpRequest httpRequest, String endpoint, String fuzzR private HttpUriRequest buildIastFuzzRequest(HttpRequest httpRequest, String endpoint, boolean addEventIgnoreHeader) throws URISyntaxException, UnsupportedEncodingException, ApacheHttpExceptionWrapper { RequestBuilder requestBuilder = getRequestBuilder(httpRequest.getMethod()); - URIBuilder uriBuilder = new URIBuilder(endpoint); String requestUrl = httpRequest.getUrl(); if (StringUtils.isBlank(requestUrl)) { throw new ApacheHttpExceptionWrapper("Request URL is empty"); } - requestBuilder.setUri(requestUrl); + requestBuilder.setUri(createURL(endpoint, requestUrl)); if(StringUtils.startsWith(httpRequest.getContentType(), APPLICATION_X_WWW_FORM_URLENCODED)){ requestBuilder.setEntity(new UrlEncodedFormEntity(buildFormParameters(httpRequest.getParameterMap()))); } @@ -261,6 +261,19 @@ private HttpUriRequest buildIastFuzzRequest(HttpRequest httpRequest, String endp return requestBuilder.build(); } + private URI createURL(String endpoint, String requestUrl) { + if (StringUtils.isBlank(requestUrl)) { + return URI.create(endpoint); + } + if (StringUtils.endsWith(endpoint, SUFFIX_SLASH) && StringUtils.startsWith(requestUrl, SUFFIX_SLASH)) { + return URI.create(endpoint + requestUrl.substring(1)); + } else if (StringUtils.endsWith(endpoint, SUFFIX_SLASH) || StringUtils.startsWith(requestUrl, SUFFIX_SLASH)) { + return URI.create(endpoint + requestUrl); + } else { + return URI.create(endpoint + SUFFIX_SLASH + requestUrl); + } + } + private List buildFormParameters(Map parameterMap) { List formParameters = new ArrayList<>(); for (Map.Entry formData : parameterMap.entrySet()) { From 413c6b7a843613bfbb7f897ad9360ed150048a77 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Mon, 16 Dec 2024 18:56:04 +0530 Subject: [PATCH 4/6] Fix for status code check --- .../intcodeagent/apache/httpclient/IastHttpClient.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/IastHttpClient.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/IastHttpClient.java index 890f4b944..f858ed575 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/IastHttpClient.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/IastHttpClient.java @@ -77,7 +77,8 @@ public void tryToEstablishApplicationEndpoint(HttpRequest request) { for (Map.Entry endpoint : endpoints.entrySet()) { try { ReadResult result = httpClient.execute(request, endpoint.getValue(), null, true); - if(result.getStatusCode() >= 200 && result.getStatusCode() <= 500) { + int statusCode = result.getStatusCode(); + if ((statusCode >= 200 && statusCode < 300) || (statusCode >= 400 && statusCode < 500)) { ServerConnectionConfiguration serverConnectionConfiguration = new ServerConnectionConfiguration(serverPort, endpoint.getKey(), endpoint.getValue(), true); AppServerInfo appServerInfo = AppServerInfoHelper.getAppServerInfo(); appServerInfo.getConnectionConfiguration().put(serverPort, serverConnectionConfiguration); From 49e7eceeb7fa6d754807f89dfb9b1eb78303d881 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Mon, 16 Dec 2024 19:01:42 +0530 Subject: [PATCH 5/6] Fix for status code check in 4xx list --- .../intcodeagent/apache/httpclient/IastHttpClient.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/IastHttpClient.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/IastHttpClient.java index f858ed575..97130132d 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/IastHttpClient.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/IastHttpClient.java @@ -78,7 +78,9 @@ public void tryToEstablishApplicationEndpoint(HttpRequest request) { try { ReadResult result = httpClient.execute(request, endpoint.getValue(), null, true); int statusCode = result.getStatusCode(); - if ((statusCode >= 200 && statusCode < 300) || (statusCode >= 400 && statusCode < 500)) { + if ((statusCode >= 200 && statusCode < 300) || + statusCode == 401 || statusCode == 402 || + statusCode == 406 || statusCode == 409) { ServerConnectionConfiguration serverConnectionConfiguration = new ServerConnectionConfiguration(serverPort, endpoint.getKey(), endpoint.getValue(), true); AppServerInfo appServerInfo = AppServerInfoHelper.getAppServerInfo(); appServerInfo.getConnectionConfiguration().put(serverPort, serverConnectionConfiguration); From a07377180c0db9a1e18a7c80d3e16f7155d13259 Mon Sep 17 00:00:00 2001 From: idawda Date: Mon, 16 Dec 2024 19:33:29 +0530 Subject: [PATCH 6/6] Use NoopHostname verifier in IAST Apache client --- .../apache/httpclient/ApacheHttpClientWrapper.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java index 690a44dda..5e2d549a4 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/apache/httpclient/ApacheHttpClientWrapper.java @@ -25,6 +25,7 @@ import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.DefaultHostnameVerifier; +import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.StringEntity; @@ -98,7 +99,7 @@ public ApacheHttpClientWrapper(int requestTimeoutInMillis) { .disableCookieManagement() .disableAuthCaching() .disableConnectionState() - .setSSLHostnameVerifier(new DefaultHostnameVerifier()) + .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) .setDefaultRequestConfig(RequestConfig.custom() // Timeout in millis until a connection is established. .setConnectTimeout(requestTimeoutInMillis) @@ -137,7 +138,7 @@ private static PoolingHttpClientConnectionManager createHttpClientConnectionMana RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", sslContext != null ? - new SSLConnectionSocketFactory(sslContext) : SSLConnectionSocketFactory.getSocketFactory()) + new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE) : SSLConnectionSocketFactory.getSocketFactory()) .build()); // We only allow one connection at a time to the backend.