From 978cb4107c8c4ce8d268172b5c84986e75b719fd Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Wed, 4 Oct 2023 16:52:23 +0530 Subject: [PATCH 01/21] Support for com.ning:async-http-client (from 1.1.0 to 1.6.1) --- .../ning-async-http-client-1.1.0/build.gradle | 19 +++++ .../ning/http_1_1/NingHelper.java | 82 +++++++++++++++++++ .../AsyncHttpProvider_Instrumentation.java | 45 ++++++++++ .../src/main/java/play/CorePlugin.java | 11 +++ 4 files changed, 157 insertions(+) create mode 100644 instrumentation-security/ning-async-http-client-1.1.0/build.gradle create mode 100644 instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java create mode 100644 instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java create mode 100644 instrumentation-security/ning-async-http-client-1.1.0/src/main/java/play/CorePlugin.java diff --git a/instrumentation-security/ning-async-http-client-1.1.0/build.gradle b/instrumentation-security/ning-async-http-client-1.1.0/build.gradle new file mode 100644 index 000000000..86197f362 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.1.0/build.gradle @@ -0,0 +1,19 @@ +dependencies { + implementation(project(":newrelic-security-api")) + implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}") + implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}") + implementation("com.ning:async-http-client:1.1.0") +} + +jar { + manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.ning-async-http-client-1.1.0' } +} + +verifyInstrumentation { + passesOnly 'com.ning:async-http-client:[1.1,1.6.1)' +} + +site { + title 'Ning AsyncHttpClient' + type 'Messaging' +} \ No newline at end of file diff --git a/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java new file mode 100644 index 000000000..208c5bd7a --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java @@ -0,0 +1,82 @@ +package com.newrelic.agent.security.instrumentation.ning.http_1_1; + +import com.newrelic.api.agent.security.NewRelicSecurity; +import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; +import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.SecurityMetaData; +import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; +import com.newrelic.api.agent.security.schema.operation.SSRFOperation; +import com.newrelic.api.agent.security.utils.SSRFUtils; +import com.ning.http.client.Request; + +public class NingHelper { + public static final String METHOD_NAME_EXECUTE = "execute"; + public static final String NR_SEC_CUSTOM_ATTRIB_NAME = "SSRF_OPERATION_LOCK_NING-"; + + public static void registerExitOperation(boolean isProcessingAllowed, AbstractOperation operation) { + try { + if (operation == null || !isProcessingAllowed || !NewRelicSecurity.isHookProcessingActive() || NewRelicSecurity.getAgent().getSecurityMetaData().getRequest().isEmpty() + ) { + return; + } + NewRelicSecurity.getAgent().registerExitEvent(operation); + } catch (Throwable ignored) { + } + } + + public static AbstractOperation preprocessSecurityHook(Request request, String uri, String methodName, String className) { + try { + SecurityMetaData securityMetaData = NewRelicSecurity.getAgent().getSecurityMetaData(); + if (!NewRelicSecurity.isHookProcessingActive() || securityMetaData.getRequest().isEmpty() + ) { + return null; + } + + // Add Security IAST header + String iastHeader = NewRelicSecurity.getAgent().getSecurityMetaData().getFuzzRequestIdentifier().getRaw(); + if (iastHeader != null && !iastHeader.trim().isEmpty()) { + request.getHeaders().add(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID, iastHeader); + } + + String csecParaentId = securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class); + if(StringUtils.isNotBlank(csecParaentId)){ + request.getHeaders().add(GenericHelper.CSEC_PARENT_ID, csecParaentId); + } + + SSRFOperation operation = new SSRFOperation(uri, className, methodName); + try { + NewRelicSecurity.getAgent().registerOperation(operation); + } finally { + if (operation.getApiID() != null && !operation.getApiID().trim().isEmpty() && + operation.getExecutionId() != null && !operation.getExecutionId().trim().isEmpty()) { + // Add Security distributed tracing header + request.getHeaders().add(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER, SSRFUtils.generateTracingHeaderValue(securityMetaData.getTracingHeaderValue(), operation.getApiID(), operation.getExecutionId(), NewRelicSecurity.getAgent().getAgentUUID())); + } + } + return operation; + } catch (Throwable e) { + if (e instanceof NewRelicSecurityException) { + e.printStackTrace(); + throw e; + } + } + return null; + } + + public static void releaseLock(int hashCode) { + try { + GenericHelper.releaseLock(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + } catch (Throwable ignored) { + } + } + + public static boolean acquireLockIfPossible(int hashCode) { + try { + return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + } catch (Throwable ignored) { + } + return false; + } +} diff --git a/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java new file mode 100644 index 000000000..04511aa11 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java @@ -0,0 +1,45 @@ +package com.ning.http.client; + +import com.newrelic.agent.security.instrumentation.ning.http_1_1.NingHelper; +import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.weaver.MatchType; +import com.newrelic.api.agent.weaver.Weave; +import com.newrelic.api.agent.weaver.Weaver; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.concurrent.Future; + +@Weave(type = MatchType.Interface, originalName = "com.ning.http.client.AsyncHttpProvider") +public class AsyncHttpProvider_Instrumentation { + + public Future execute(Request request, AsyncHandler handler) throws IOException { + boolean isLockAcquired = NingHelper.acquireLockIfPossible(this.hashCode()); + AbstractOperation operation = null; + URI uri = null; + Future returnObj = null; + + try { + uri = new URI(request.getUrl()); + String scheme = uri.getScheme(); + + if (isLockAcquired && (scheme == null || scheme.equals("http") || scheme.equals("https"))) { + operation = NingHelper.preprocessSecurityHook(request, uri.toString(), NingHelper.METHOD_NAME_EXECUTE, this.getClass().getName()); + } + } catch (URISyntaxException uriSyntaxException) { + // Instrumentation won't work and normal execution will continue + } + + try { + returnObj = Weaver.callOriginal(); + } finally { + if (isLockAcquired) { + NingHelper.releaseLock(this.hashCode()); + } + } + NingHelper.registerExitOperation(isLockAcquired, operation); + + return returnObj; + } +} diff --git a/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/play/CorePlugin.java b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/play/CorePlugin.java new file mode 100644 index 000000000..1d68ebdd2 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/play/CorePlugin.java @@ -0,0 +1,11 @@ +package play; + +import com.newrelic.api.agent.weaver.SkipIfPresent; + +/** + * Play v1 instrumentation is implemented using its own set of pointcuts that don't work well with our async APIs. This + * class is present in Play v1 but not v2, and will cause this module NOT to load if the customer is using Play v1. + */ +@SkipIfPresent +public class CorePlugin { +} From 94572b73787c713187f545de23651e949be63b02 Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Wed, 4 Oct 2023 16:52:46 +0530 Subject: [PATCH 02/21] Test: Added unit test cases for com.ning:async-http-client (from 1.1.0 to 1.6.1) --- .../http_1_1/NingAsyncHttpClient11Test.java | 425 ++++++++++++++++++ 1 file changed, 425 insertions(+) create mode 100644 instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java diff --git a/instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java b/instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java new file mode 100644 index 000000000..0a1a627d7 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java @@ -0,0 +1,425 @@ +package com.nr.agent.security.instrumentation.ning.http_1_1; + +import com.newrelic.agent.security.introspec.InstrumentationTestConfig; +import com.newrelic.agent.security.introspec.SecurityInstrumentationTestRunner; +import com.newrelic.agent.security.introspec.SecurityIntrospector; +import com.newrelic.agent.security.introspec.internal.HttpServerRule; +import com.newrelic.api.agent.Trace; +import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; +import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; +import com.newrelic.api.agent.security.schema.operation.SSRFOperation; +import com.ning.http.client.AsyncCompletionHandler; +import com.ning.http.client.AsyncHttpClient; +import com.ning.http.client.Request; +import com.ning.http.client.RequestBuilder; +import com.ning.http.client.RequestType; +import com.ning.http.client.Response; +import org.junit.Assert; +import org.junit.ClassRule; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; + +import java.io.IOException; +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +@RunWith(SecurityInstrumentationTestRunner.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@InstrumentationTestConfig(includePrefixes = { "com.newrelic.agent.security.instrumentation.ning.http_1_1", "com.ning" }) +public class NingAsyncHttpClient11Test { + + private static final int TIMEOUT = 30000; + + @ClassRule + public static HttpServerRule server = new HttpServerRule(); + + @Test + public void testPrepare() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequest(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPrepareGet() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestGet(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPreparePost() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestPost(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPreparePut() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestPut(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPrepareDelete() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestDelete(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPrepareHead() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestHead(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPrepareOptions() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestOptions(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testExecuteRequest1() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncExecuteRequest1(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testExecuteRequest2() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncExecuteRequest2(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestGet(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.prepareGet(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestPost(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.preparePost(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestPut(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.preparePut(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestDelete(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.prepareDelete(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestHead(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.prepareHead(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestOptions(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.prepareOptions(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequest(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + Request request = new RequestBuilder(RequestType.GET).setUrl(url).build(); + AsyncHttpClient.BoundRequestBuilder builder = client.prepareRequest(request); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + private static void makeAsyncExecuteRequest1(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try{ + Request request = new RequestBuilder(RequestType.GET).setUrl(url).build(); + Future f = client.executeRequest(request); + Response response = f.get(); + response.getStatusCode(); + } catch (InterruptedException | IOException | ExecutionException e) { + } + } + + @Trace(dispatcher = true) + private static void makeAsyncExecuteRequest2(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try{ + Request request = new RequestBuilder(RequestType.GET).setUrl(url).build(); + Future f = client.executeRequest(request, new AsyncCompletionHandler() { + + @Override + public Response onCompleted(Response response) { + return response; + } + + @Override + public void onThrowable(Throwable t) { + } + }); + Response response = f.get(); + response.getStatusCode(); + } catch (InterruptedException | IOException | ExecutionException e) { + } + } +} From d2e3408ea667144d81876c1d610ea3aeb735b52c Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Mon, 15 Jan 2024 12:10:50 +0530 Subject: [PATCH 03/21] Fix: failed dynamodb UTs --- .../instrumentation/dynamodb_212/DynamodbTest.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/instrumentation-security/dynamodb-2.1.2/src/test/java/com/nr/agent/security/instrumentation/dynamodb_212/DynamodbTest.java b/instrumentation-security/dynamodb-2.1.2/src/test/java/com/nr/agent/security/instrumentation/dynamodb_212/DynamodbTest.java index f7fafce30..4ee0c310c 100644 --- a/instrumentation-security/dynamodb-2.1.2/src/test/java/com/nr/agent/security/instrumentation/dynamodb_212/DynamodbTest.java +++ b/instrumentation-security/dynamodb-2.1.2/src/test/java/com/nr/agent/security/instrumentation/dynamodb_212/DynamodbTest.java @@ -187,16 +187,13 @@ public void testTransactGetItems() { Assert.assertEquals("Invalid table name", "test", request.getQuery().getTableName()); Assert.assertNotNull("No such payload detected", query.get("artist")); - Assert.assertNotNull("No such payload detected", query.get("year")); if (i==0) { Assert.assertEquals("Invalid payload value.", "Monu",query.get("artist").s()); - Assert.assertEquals("Invalid payload value.", "1998",query.get("year").n()); } else if (i==1) { Assert.assertEquals("Invalid payload value.", "Red",query.get("artist").s()); - Assert.assertEquals("Invalid payload value.", "1999",query.get("year").n()); } - Assert.assertEquals("Invalid payload value.", "artist",request.getQuery().getProjectionExpression()); + Assert.assertEquals("Invalid payload value.", "artist,Genre",request.getQuery().getProjectionExpression()); Assert.assertEquals("Invalid query-type.", "read", request.getQueryType()); i++; } @@ -854,14 +851,12 @@ public void transactGetItems() { Map key = new HashMap<>(); key.put("artist", AttributeValue.builder().s("Monu").build()); - key.put("year", AttributeValue.builder().n("1998").build()); Map key2 = new HashMap<>(); key2.put("artist", AttributeValue.builder().s("Red").build()); - key2.put("year", AttributeValue.builder().n("1999").build()); TransactGetItemsRequest queryRequest = TransactGetItemsRequest.builder().transactItems( - TransactGetItem.builder().get(Get.builder().tableName(DynamoUtil.TABLE).key(key).projectionExpression("artist").build()).build(), - TransactGetItem.builder().get(Get.builder().tableName(DynamoUtil.TABLE).key(key2).projectionExpression("artist").build()).build()).build(); + TransactGetItem.builder().get(Get.builder().tableName(DynamoUtil.TABLE).key(key).projectionExpression("artist,Genre").build()).build(), + TransactGetItem.builder().get(Get.builder().tableName(DynamoUtil.TABLE).key(key2).projectionExpression("artist,Genre").build()).build()).build(); client.transactGetItems(queryRequest); } From c95ad93a35c628803060434efb90da7279a52e1a Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Wed, 4 Oct 2023 16:52:23 +0530 Subject: [PATCH 04/21] Support for com.ning:async-http-client (from 1.1.0 to 1.6.1) (cherry picked from commit ce18b31acbe49b29e00c87ffe5a1c870083c1920) --- .../ning-async-http-client-1.1.0/build.gradle | 19 +++++ .../ning/http_1_1/NingHelper.java | 82 +++++++++++++++++++ .../AsyncHttpProvider_Instrumentation.java | 45 ++++++++++ .../src/main/java/play/CorePlugin.java | 11 +++ 4 files changed, 157 insertions(+) create mode 100644 instrumentation-security/ning-async-http-client-1.1.0/build.gradle create mode 100644 instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java create mode 100644 instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java create mode 100644 instrumentation-security/ning-async-http-client-1.1.0/src/main/java/play/CorePlugin.java diff --git a/instrumentation-security/ning-async-http-client-1.1.0/build.gradle b/instrumentation-security/ning-async-http-client-1.1.0/build.gradle new file mode 100644 index 000000000..86197f362 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.1.0/build.gradle @@ -0,0 +1,19 @@ +dependencies { + implementation(project(":newrelic-security-api")) + implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}") + implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}") + implementation("com.ning:async-http-client:1.1.0") +} + +jar { + manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.ning-async-http-client-1.1.0' } +} + +verifyInstrumentation { + passesOnly 'com.ning:async-http-client:[1.1,1.6.1)' +} + +site { + title 'Ning AsyncHttpClient' + type 'Messaging' +} \ No newline at end of file diff --git a/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java new file mode 100644 index 000000000..208c5bd7a --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java @@ -0,0 +1,82 @@ +package com.newrelic.agent.security.instrumentation.ning.http_1_1; + +import com.newrelic.api.agent.security.NewRelicSecurity; +import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; +import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.SecurityMetaData; +import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; +import com.newrelic.api.agent.security.schema.operation.SSRFOperation; +import com.newrelic.api.agent.security.utils.SSRFUtils; +import com.ning.http.client.Request; + +public class NingHelper { + public static final String METHOD_NAME_EXECUTE = "execute"; + public static final String NR_SEC_CUSTOM_ATTRIB_NAME = "SSRF_OPERATION_LOCK_NING-"; + + public static void registerExitOperation(boolean isProcessingAllowed, AbstractOperation operation) { + try { + if (operation == null || !isProcessingAllowed || !NewRelicSecurity.isHookProcessingActive() || NewRelicSecurity.getAgent().getSecurityMetaData().getRequest().isEmpty() + ) { + return; + } + NewRelicSecurity.getAgent().registerExitEvent(operation); + } catch (Throwable ignored) { + } + } + + public static AbstractOperation preprocessSecurityHook(Request request, String uri, String methodName, String className) { + try { + SecurityMetaData securityMetaData = NewRelicSecurity.getAgent().getSecurityMetaData(); + if (!NewRelicSecurity.isHookProcessingActive() || securityMetaData.getRequest().isEmpty() + ) { + return null; + } + + // Add Security IAST header + String iastHeader = NewRelicSecurity.getAgent().getSecurityMetaData().getFuzzRequestIdentifier().getRaw(); + if (iastHeader != null && !iastHeader.trim().isEmpty()) { + request.getHeaders().add(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID, iastHeader); + } + + String csecParaentId = securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class); + if(StringUtils.isNotBlank(csecParaentId)){ + request.getHeaders().add(GenericHelper.CSEC_PARENT_ID, csecParaentId); + } + + SSRFOperation operation = new SSRFOperation(uri, className, methodName); + try { + NewRelicSecurity.getAgent().registerOperation(operation); + } finally { + if (operation.getApiID() != null && !operation.getApiID().trim().isEmpty() && + operation.getExecutionId() != null && !operation.getExecutionId().trim().isEmpty()) { + // Add Security distributed tracing header + request.getHeaders().add(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER, SSRFUtils.generateTracingHeaderValue(securityMetaData.getTracingHeaderValue(), operation.getApiID(), operation.getExecutionId(), NewRelicSecurity.getAgent().getAgentUUID())); + } + } + return operation; + } catch (Throwable e) { + if (e instanceof NewRelicSecurityException) { + e.printStackTrace(); + throw e; + } + } + return null; + } + + public static void releaseLock(int hashCode) { + try { + GenericHelper.releaseLock(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + } catch (Throwable ignored) { + } + } + + public static boolean acquireLockIfPossible(int hashCode) { + try { + return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + } catch (Throwable ignored) { + } + return false; + } +} diff --git a/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java new file mode 100644 index 000000000..04511aa11 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java @@ -0,0 +1,45 @@ +package com.ning.http.client; + +import com.newrelic.agent.security.instrumentation.ning.http_1_1.NingHelper; +import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.weaver.MatchType; +import com.newrelic.api.agent.weaver.Weave; +import com.newrelic.api.agent.weaver.Weaver; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.concurrent.Future; + +@Weave(type = MatchType.Interface, originalName = "com.ning.http.client.AsyncHttpProvider") +public class AsyncHttpProvider_Instrumentation { + + public Future execute(Request request, AsyncHandler handler) throws IOException { + boolean isLockAcquired = NingHelper.acquireLockIfPossible(this.hashCode()); + AbstractOperation operation = null; + URI uri = null; + Future returnObj = null; + + try { + uri = new URI(request.getUrl()); + String scheme = uri.getScheme(); + + if (isLockAcquired && (scheme == null || scheme.equals("http") || scheme.equals("https"))) { + operation = NingHelper.preprocessSecurityHook(request, uri.toString(), NingHelper.METHOD_NAME_EXECUTE, this.getClass().getName()); + } + } catch (URISyntaxException uriSyntaxException) { + // Instrumentation won't work and normal execution will continue + } + + try { + returnObj = Weaver.callOriginal(); + } finally { + if (isLockAcquired) { + NingHelper.releaseLock(this.hashCode()); + } + } + NingHelper.registerExitOperation(isLockAcquired, operation); + + return returnObj; + } +} diff --git a/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/play/CorePlugin.java b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/play/CorePlugin.java new file mode 100644 index 000000000..1d68ebdd2 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/play/CorePlugin.java @@ -0,0 +1,11 @@ +package play; + +import com.newrelic.api.agent.weaver.SkipIfPresent; + +/** + * Play v1 instrumentation is implemented using its own set of pointcuts that don't work well with our async APIs. This + * class is present in Play v1 but not v2, and will cause this module NOT to load if the customer is using Play v1. + */ +@SkipIfPresent +public class CorePlugin { +} From 7d4a6f6cf65e05146f6bf90347765e29a5bad47e Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Wed, 4 Oct 2023 16:52:46 +0530 Subject: [PATCH 05/21] Test: Added unit test cases for com.ning:async-http-client (from 1.1.0 to 1.6.1) (cherry picked from commit 68284daa6024bade01df28761af0986eed20f638) --- .../http_1_1/NingAsyncHttpClient11Test.java | 425 ++++++++++++++++++ 1 file changed, 425 insertions(+) create mode 100644 instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java diff --git a/instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java b/instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java new file mode 100644 index 000000000..0a1a627d7 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java @@ -0,0 +1,425 @@ +package com.nr.agent.security.instrumentation.ning.http_1_1; + +import com.newrelic.agent.security.introspec.InstrumentationTestConfig; +import com.newrelic.agent.security.introspec.SecurityInstrumentationTestRunner; +import com.newrelic.agent.security.introspec.SecurityIntrospector; +import com.newrelic.agent.security.introspec.internal.HttpServerRule; +import com.newrelic.api.agent.Trace; +import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; +import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; +import com.newrelic.api.agent.security.schema.operation.SSRFOperation; +import com.ning.http.client.AsyncCompletionHandler; +import com.ning.http.client.AsyncHttpClient; +import com.ning.http.client.Request; +import com.ning.http.client.RequestBuilder; +import com.ning.http.client.RequestType; +import com.ning.http.client.Response; +import org.junit.Assert; +import org.junit.ClassRule; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; + +import java.io.IOException; +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +@RunWith(SecurityInstrumentationTestRunner.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@InstrumentationTestConfig(includePrefixes = { "com.newrelic.agent.security.instrumentation.ning.http_1_1", "com.ning" }) +public class NingAsyncHttpClient11Test { + + private static final int TIMEOUT = 30000; + + @ClassRule + public static HttpServerRule server = new HttpServerRule(); + + @Test + public void testPrepare() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequest(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPrepareGet() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestGet(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPreparePost() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestPost(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPreparePut() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestPut(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPrepareDelete() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestDelete(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPrepareHead() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestHead(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testPrepareOptions() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncRequestOptions(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testExecuteRequest1() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncExecuteRequest1(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Test + public void testExecuteRequest2() throws Exception { + URI endpoint = server.getEndPoint(); + String host = endpoint.getHost(); + + String headerValue = String.valueOf(UUID.randomUUID()); + + SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); + introspector.setK2FuzzRequestId(headerValue); + introspector.setK2TracingData(headerValue); + + makeAsyncExecuteRequest2(endpoint.toURL().toString()); + + List operations = introspector.getOperations(); + Assert.assertTrue("No operations detected", operations.size() > 0); + SSRFOperation operation = (SSRFOperation) operations.get(0); + Map headers = server.getHeaders(); + Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); + Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); + Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestGet(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.prepareGet(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestPost(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.preparePost(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestPut(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.preparePut(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestDelete(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.prepareDelete(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestHead(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.prepareHead(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequestOptions(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + AsyncHttpClient.BoundRequestBuilder builder = client.prepareOptions(url); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + public static int makeAsyncRequest(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try { + Request request = new RequestBuilder(RequestType.GET).setUrl(url).build(); + AsyncHttpClient.BoundRequestBuilder builder = client.prepareRequest(request); + Future future = builder.execute(); + Response response = future.get(); + return response.getStatusCode(); + } catch (Exception e) { + return -1; + } finally { + client.close(); + } + } + + @Trace(dispatcher = true) + private static void makeAsyncExecuteRequest1(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try{ + Request request = new RequestBuilder(RequestType.GET).setUrl(url).build(); + Future f = client.executeRequest(request); + Response response = f.get(); + response.getStatusCode(); + } catch (InterruptedException | IOException | ExecutionException e) { + } + } + + @Trace(dispatcher = true) + private static void makeAsyncExecuteRequest2(String url) { + AsyncHttpClient client = new AsyncHttpClient(); + try{ + Request request = new RequestBuilder(RequestType.GET).setUrl(url).build(); + Future f = client.executeRequest(request, new AsyncCompletionHandler() { + + @Override + public Response onCompleted(Response response) { + return response; + } + + @Override + public void onThrowable(Throwable t) { + } + }); + Response response = f.get(); + response.getStatusCode(); + } catch (InterruptedException | IOException | ExecutionException e) { + } + } +} From 3663ae5e8cf1fa88e7690b7998d479593eac21d4 Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Mon, 9 Oct 2023 17:17:23 +0530 Subject: [PATCH 06/21] UTs for csec parent id header in com.ning:async-http-client (from 1.1.0 to 1.6.1) (cherry picked from commit 2b4768dddc4d41ff310d35f8fb98b61c7ebdcb14) --- .../http_1_1/NingAsyncHttpClient11Test.java | 99 +++++++------------ 1 file changed, 36 insertions(+), 63 deletions(-) diff --git a/instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java b/instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java index 0a1a627d7..c90486c40 100644 --- a/instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java +++ b/instrumentation-security/ning-async-http-client-1.1.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_1/NingAsyncHttpClient11Test.java @@ -5,6 +5,7 @@ import com.newrelic.agent.security.introspec.SecurityIntrospector; import com.newrelic.agent.security.introspec.internal.HttpServerRule; import com.newrelic.api.agent.Trace; +import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; @@ -48,8 +49,7 @@ public void testPrepare() throws Exception { String headerValue = String.valueOf(UUID.randomUUID()); SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); - introspector.setK2FuzzRequestId(headerValue); - introspector.setK2TracingData(headerValue); + setCSECHeaders(headerValue, introspector); makeAsyncRequest(endpoint.toURL().toString()); @@ -60,11 +60,7 @@ public void testPrepare() throws Exception { Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( - ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + verifyHeaders(headerValue, headers); } @Test @@ -75,8 +71,7 @@ public void testPrepareGet() throws Exception { String headerValue = String.valueOf(UUID.randomUUID()); SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); - introspector.setK2FuzzRequestId(headerValue); - introspector.setK2TracingData(headerValue); + setCSECHeaders(headerValue, introspector); makeAsyncRequestGet(endpoint.toURL().toString()); @@ -87,11 +82,7 @@ public void testPrepareGet() throws Exception { Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( - ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + verifyHeaders(headerValue, headers); } @Test @@ -102,8 +93,7 @@ public void testPreparePost() throws Exception { String headerValue = String.valueOf(UUID.randomUUID()); SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); - introspector.setK2FuzzRequestId(headerValue); - introspector.setK2TracingData(headerValue); + setCSECHeaders(headerValue, introspector); makeAsyncRequestPost(endpoint.toURL().toString()); @@ -114,11 +104,7 @@ public void testPreparePost() throws Exception { Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( - ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + verifyHeaders(headerValue, headers); } @Test @@ -129,8 +115,7 @@ public void testPreparePut() throws Exception { String headerValue = String.valueOf(UUID.randomUUID()); SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); - introspector.setK2FuzzRequestId(headerValue); - introspector.setK2TracingData(headerValue); + setCSECHeaders(headerValue, introspector); makeAsyncRequestPut(endpoint.toURL().toString()); @@ -141,11 +126,7 @@ public void testPreparePut() throws Exception { Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( - ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + verifyHeaders(headerValue, headers); } @Test @@ -156,8 +137,7 @@ public void testPrepareDelete() throws Exception { String headerValue = String.valueOf(UUID.randomUUID()); SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); - introspector.setK2FuzzRequestId(headerValue); - introspector.setK2TracingData(headerValue); + setCSECHeaders(headerValue, introspector); makeAsyncRequestDelete(endpoint.toURL().toString()); @@ -168,11 +148,7 @@ public void testPrepareDelete() throws Exception { Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( - ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + verifyHeaders(headerValue, headers); } @Test @@ -183,8 +159,7 @@ public void testPrepareHead() throws Exception { String headerValue = String.valueOf(UUID.randomUUID()); SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); - introspector.setK2FuzzRequestId(headerValue); - introspector.setK2TracingData(headerValue); + setCSECHeaders(headerValue, introspector); makeAsyncRequestHead(endpoint.toURL().toString()); @@ -195,11 +170,7 @@ public void testPrepareHead() throws Exception { Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( - ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + verifyHeaders(headerValue, headers); } @Test @@ -210,8 +181,7 @@ public void testPrepareOptions() throws Exception { String headerValue = String.valueOf(UUID.randomUUID()); SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); - introspector.setK2FuzzRequestId(headerValue); - introspector.setK2TracingData(headerValue); + setCSECHeaders(headerValue, introspector); makeAsyncRequestOptions(endpoint.toURL().toString()); @@ -222,11 +192,7 @@ public void testPrepareOptions() throws Exception { Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( - ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + verifyHeaders(headerValue, headers); } @Test @@ -237,8 +203,7 @@ public void testExecuteRequest1() throws Exception { String headerValue = String.valueOf(UUID.randomUUID()); SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); - introspector.setK2FuzzRequestId(headerValue); - introspector.setK2TracingData(headerValue); + setCSECHeaders(headerValue, introspector); makeAsyncExecuteRequest1(endpoint.toURL().toString()); @@ -249,11 +214,7 @@ public void testExecuteRequest1() throws Exception { Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( - ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + verifyHeaders(headerValue, headers); } @Test @@ -264,8 +225,7 @@ public void testExecuteRequest2() throws Exception { String headerValue = String.valueOf(UUID.randomUUID()); SecurityIntrospector introspector = SecurityInstrumentationTestRunner.getIntrospector(); - introspector.setK2FuzzRequestId(headerValue); - introspector.setK2TracingData(headerValue); + setCSECHeaders(headerValue, introspector); makeAsyncExecuteRequest2(endpoint.toURL().toString()); @@ -276,11 +236,7 @@ public void testExecuteRequest2() throws Exception { Assert.assertEquals("Invalid executed parameters.", server.getEndPoint().toString(), operation.getArg()); Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType()); Assert.assertEquals("Invalid executed method name.", "execute", operation.getMethodName()); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue, headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); - Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); - Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get( - ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + verifyHeaders(headerValue, headers); } @Trace(dispatcher = true) @@ -422,4 +378,21 @@ public void onThrowable(Throwable t) { } catch (InterruptedException | IOException | ExecutionException e) { } } + + private void setCSECHeaders(String headerValue, SecurityIntrospector introspector) { + introspector.setK2FuzzRequestId(headerValue+"a"); + introspector.setK2ParentId(headerValue+"b"); + introspector.setK2TracingData(headerValue); + } + + private void verifyHeaders(String headerValue, Map headers) { + Assert.assertTrue(String.format("Missing K2 header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertEquals(String.format("Invalid K2 header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue+"a", headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); + Assert.assertTrue(String.format("Missing K2 header: %s", GenericHelper.CSEC_PARENT_ID), headers.containsKey(GenericHelper.CSEC_PARENT_ID)); + Assert.assertEquals(String.format("Invalid K2 header value for: %s", GenericHelper.CSEC_PARENT_ID), headerValue+"b", headers.get(GenericHelper.CSEC_PARENT_ID)); + Assert.assertTrue(String.format("Missing K2 header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + Assert.assertEquals(String.format("Invalid K2 header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", + headerValue), headers.get( + ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())); + } } From b910723b0bdb6005c5b21a3d4ad0066b10bdd762 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 22 Feb 2024 10:38:44 +0530 Subject: [PATCH 07/21] Add support for ning-async-http-client, jersey, spring-data-redis, jcache, lettuce, spymemcached, jetty-12 and mule server --- settings.gradle | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/settings.gradle b/settings.gradle index 932f59700..7a020a5ce 100644 --- a/settings.gradle +++ b/settings.gradle @@ -164,17 +164,17 @@ include 'instrumentation:grpc-1.4.0' include 'instrumentation:grpc-1.22.0' include 'instrumentation:grpc-1.40.0' -//include 'instrumentation:ning-async-http-client-1.1.0' -//include 'instrumentation:ning-async-http-client-1.6.1' -//include 'instrumentation:ning-async-http-client-1.0.0' -//include 'instrumentation:jersey-2' -//include 'instrumentation:jersey-2.16' -//include 'instrumentation:jersey-3' -//include 'instrumentation:spring-data-redis' -//include 'instrumentation:jcache-1.0.0' -//include 'instrumentation:lettuce-4.3' -//include 'instrumentation:lettuce-5.0' -//include 'instrumentation:spymemcached-2.12.0' -//include 'instrumentation:jetty-12' -//include 'instrumentation:mule-3.7' -//include 'instrumentation:mule-3.6' +include 'instrumentation:ning-async-http-client-1.1.0' +include 'instrumentation:ning-async-http-client-1.6.1' +include 'instrumentation:ning-async-http-client-1.0.0' +include 'instrumentation:jersey-2' +include 'instrumentation:jersey-2.16' +include 'instrumentation:jersey-3' +include 'instrumentation:spring-data-redis' +include 'instrumentation:jcache-1.0.0' +include 'instrumentation:lettuce-4.3' +include 'instrumentation:lettuce-5.0' +include 'instrumentation:spymemcached-2.12.0' +include 'instrumentation:jetty-12' +include 'instrumentation:mule-3.7' +include 'instrumentation:mule-3.6' From a440cced0989a83ef0d5cdb8f44203a1c5ef7e5e Mon Sep 17 00:00:00 2001 From: idawda Date: Thu, 22 Feb 2024 11:30:21 +0530 Subject: [PATCH 08/21] add test dependency to jersey support build.gradle --- instrumentation-security/jersey-2.16/build.gradle | 3 +++ instrumentation-security/jersey-2/build.gradle | 3 +++ instrumentation-security/jersey-3/build.gradle | 3 +++ 3 files changed, 9 insertions(+) diff --git a/instrumentation-security/jersey-2.16/build.gradle b/instrumentation-security/jersey-2.16/build.gradle index d10b64445..56b302d44 100644 --- a/instrumentation-security/jersey-2.16/build.gradle +++ b/instrumentation-security/jersey-2.16/build.gradle @@ -4,6 +4,9 @@ dependencies { implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}") implementation("org.glassfish.jersey.core:jersey-server:2.16") + testImplementation("org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.28") + testImplementation("org.glassfish.jersey.containers:jersey-container-servlet:2.28") + testImplementation('org.glassfish.jersey.inject:jersey-hk2:2.28') } jar { diff --git a/instrumentation-security/jersey-2/build.gradle b/instrumentation-security/jersey-2/build.gradle index 6b8971009..7c18e6d6b 100644 --- a/instrumentation-security/jersey-2/build.gradle +++ b/instrumentation-security/jersey-2/build.gradle @@ -4,6 +4,9 @@ dependencies { implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}") implementation("org.glassfish.jersey.core:jersey-server:2.0") + testImplementation("org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.0") + testImplementation("org.glassfish.jersey.containers:jersey-container-servlet:2.0") + testImplementation('org.glassfish.hk2:hk2-api:2.1.88') } jar { diff --git a/instrumentation-security/jersey-3/build.gradle b/instrumentation-security/jersey-3/build.gradle index 4f65c91ea..38f1f1aaa 100644 --- a/instrumentation-security/jersey-3/build.gradle +++ b/instrumentation-security/jersey-3/build.gradle @@ -4,6 +4,9 @@ dependencies { implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}") implementation("org.glassfish.jersey.core:jersey-server:3.0.0") + testImplementation("org.glassfish.jersey.containers:jersey-container-grizzly2-http:3.0.0") + testImplementation("org.glassfish.jersey.containers:jersey-container-servlet:3.0.0") + testImplementation('org.glassfish.jersey.inject:jersey-hk2:3.0.0') } jar { From c898b727a87f118f9ced9cfefeab2c73a394bb4d Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Tue, 27 Feb 2024 10:24:09 +0530 Subject: [PATCH 09/21] Add Instrumentention module wildfly-8, extract server port --- .../wildfly-8/build.gradle | 26 ++++++++++++++ .../undertow/HttpListenerService.java | 36 +++++++++++++++++++ settings.gradle | 1 + 3 files changed, 63 insertions(+) create mode 100644 instrumentation-security/wildfly-8/build.gradle create mode 100644 instrumentation-security/wildfly-8/src/main/java/org/wildfly/extension/undertow/HttpListenerService.java diff --git a/instrumentation-security/wildfly-8/build.gradle b/instrumentation-security/wildfly-8/build.gradle new file mode 100644 index 000000000..95fae598e --- /dev/null +++ b/instrumentation-security/wildfly-8/build.gradle @@ -0,0 +1,26 @@ +dependencies { + implementation(project(":newrelic-security-api")) + implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}") + implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}") + implementation("org.wildfly:wildfly-undertow:26.1.1.Final") { + exclude(group: "org.jacorb", module: "jacorb") + } + implementation("org.jboss.xnio:xnio-api:3.8.7.Final") + implementation("org.jboss.logging:jboss-logging:3.5.0.Final") + implementation("org.jboss.msc:jboss-msc:1.4.13.Final") +} + +jar { + manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.wildfly-8' } +} + +verifyInstrumentation { + passesOnly 'org.wildfly:wildfly-undertow:[8.0.0.Final,)' + excludeRegex '.*(Alpha|Beta|CR).*' +} + +site { + title 'Wildfly' + type 'Appserver' + versionOverride '[8.0.0.Final,)' +} diff --git a/instrumentation-security/wildfly-8/src/main/java/org/wildfly/extension/undertow/HttpListenerService.java b/instrumentation-security/wildfly-8/src/main/java/org/wildfly/extension/undertow/HttpListenerService.java new file mode 100644 index 000000000..af34c889c --- /dev/null +++ b/instrumentation-security/wildfly-8/src/main/java/org/wildfly/extension/undertow/HttpListenerService.java @@ -0,0 +1,36 @@ +/* + * + * * Copyright 2020 New Relic Corporation. All rights reserved. + * * SPDX-License-Identifier: Apache-2.0 + * + */ + +package org.wildfly.extension.undertow; + +import java.io.IOException; +import java.net.InetSocketAddress; + +import com.newrelic.api.agent.security.NewRelicSecurity; +import org.xnio.ChannelListener; +import org.xnio.StreamConnection; +import org.xnio.XnioWorker; +import org.xnio.channels.AcceptingChannel; + +import com.newrelic.api.agent.weaver.Weave; +import com.newrelic.api.agent.weaver.Weaver; + +/* + * The CAT point cut for wildfly had to be pulled out because + * the jar was not getting loaded correctly. + */ +@Weave +public abstract class HttpListenerService { + + protected void startListening(XnioWorker worker, InetSocketAddress socketAddress, + ChannelListener> acceptListener) throws IOException { + + NewRelicSecurity.getAgent().setApplicationConnectionConfig(socketAddress.getPort(), "http"); + Weaver.callOriginal(); + } + +} diff --git a/settings.gradle b/settings.gradle index 7a020a5ce..2ae118391 100644 --- a/settings.gradle +++ b/settings.gradle @@ -160,6 +160,7 @@ include 'instrumentation:async-http-client-2.0.0' include 'instrumentation:sun-net-httpserver' include 'instrumentation:tomcat-7' include 'instrumentation:tomcat-8' +include 'instrumentation:wildfly-8' include 'instrumentation:grpc-1.4.0' include 'instrumentation:grpc-1.22.0' include 'instrumentation:grpc-1.40.0' From c6bf0d42a2914a970e600ad2884387f28e7ed647 Mon Sep 17 00:00:00 2001 From: idawda Date: Wed, 6 Mar 2024 11:27:25 +0530 Subject: [PATCH 10/21] disabled spymemcache & jcache support --- settings.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings.gradle b/settings.gradle index 2ae118391..df0e06951 100644 --- a/settings.gradle +++ b/settings.gradle @@ -172,10 +172,10 @@ include 'instrumentation:jersey-2' include 'instrumentation:jersey-2.16' include 'instrumentation:jersey-3' include 'instrumentation:spring-data-redis' -include 'instrumentation:jcache-1.0.0' +//include 'instrumentation:jcache-1.0.0' include 'instrumentation:lettuce-4.3' include 'instrumentation:lettuce-5.0' -include 'instrumentation:spymemcached-2.12.0' +//include 'instrumentation:spymemcached-2.12.0' include 'instrumentation:jetty-12' include 'instrumentation:mule-3.7' include 'instrumentation:mule-3.6' From 644039ef27ba458e9b2c0f099914c679a2169a0c Mon Sep 17 00:00:00 2001 From: idawda Date: Wed, 6 Mar 2024 11:37:14 +0530 Subject: [PATCH 11/21] Changelogs for release v1.1.2 --- Changelog.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Changelog.md b/Changelog.md index 23ab4cec9..287075429 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,16 @@ Noteworthy changes to the agent are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.2] - TO BE DECIDED +### Changes +- Ning Async HTTP client Support: The security agent now also supports com.ning:async-http-client 1.0.0 and above +- Jersey Support: The security agent now also supports Jersey 2.0 and above +- Mule Support: The security agent now also supports Mule server version 3.6 to 3.9.x +- Jetty v12 Support: The security agent now also support Jetty version 12 and above +- Lettuce Support: The security agent now also supports Lettuce 4.4.0.Final and above + +### Fixes +- Extract Server Configuration to resolve IAST localhost connection with application for wildfly server ## [1.1.1] - 2024-2-16 ### Changes From 36c4f3cdd5ce8d59ae2d1ced0cf653814bac4e4f Mon Sep 17 00:00:00 2001 From: idawda Date: Wed, 6 Mar 2024 13:55:36 +0530 Subject: [PATCH 12/21] Updated agent version to 1.1.2 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 91571c63b..765ec9338 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # The agent version. -agentVersion=1.1.1 +agentVersion=1.1.2 jsonVersion=1.1.1 # Updated exposed NR APM API version. nrAPIVersion=8.4.0 From 0e42432f47954eb116cc3db7585144e16caa71ad Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Wed, 6 Mar 2024 17:37:40 +0530 Subject: [PATCH 13/21] NR-234903: Trustboundary events now will have list of string as parameter schema --- .../agent/security/instrumentator/dispatcher/Dispatcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java index b4f7cc258..a2a04577a 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java @@ -438,7 +438,7 @@ private JavaAgentEventBean prepareTrustBoundaryEvent(JavaAgentEventBean eventBea TrustBoundaryOperation trustBoundaryOperationalBean) { JSONArray params = new JSONArray(); params.add(trustBoundaryOperationalBean.getKey()); - params.add(trustBoundaryOperationalBean.getValue()); + params.add(JsonConverter.toJSON(trustBoundaryOperationalBean.getValue())); eventBean.setParameters(params); return eventBean; } From 58eba2c1568e3e236b2ab12b337683d7b2f3bb88 Mon Sep 17 00:00:00 2001 From: Ishika Dawda <112611034+IshikaDawda@users.noreply.github.com> Date: Thu, 7 Mar 2024 16:12:21 +0530 Subject: [PATCH 14/21] Add clear function to clean custom attribute (#199) * Add clear function to clean custom attribute * Fixed lettuce unit tests --------- Co-authored-by: Lovesh Baya --- .../internal/SecurityIntrospectorImpl.java | 20 ++++--------------- .../lettuce_4_3/LettuceTest.java | 8 +++++++- .../lettuce_5/LettuceTest.java | 9 +++++++-- .../security/schema/SecurityMetaData.java | 3 +++ 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/instrumentation-security-test/src/main/java/com/newrelic/agent/security/introspec/internal/SecurityIntrospectorImpl.java b/instrumentation-security-test/src/main/java/com/newrelic/agent/security/introspec/internal/SecurityIntrospectorImpl.java index 91aa1353d..57565f279 100644 --- a/instrumentation-security-test/src/main/java/com/newrelic/agent/security/introspec/internal/SecurityIntrospectorImpl.java +++ b/instrumentation-security-test/src/main/java/com/newrelic/agent/security/introspec/internal/SecurityIntrospectorImpl.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.net.ServerSocket; import java.sql.Statement; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; @@ -134,22 +135,9 @@ public void setRequestInputStreamHash(int hashCode) { @Override public void clear() { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(JDBCVendor.META_CONST_JDBC_VENDOR, null); - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(R2DBCVendor.META_CONST_R2DBC_VENDOR, null); - NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(Agent.OPERATIONS, List.class).clear(); - NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(Agent.EXIT_OPERATIONS, List.class).clear(); - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(REQUEST_READER_HASH, null); - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(REQUEST_INPUTSTREAM_HASH, null); - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(RESPONSE_WRITER_HASH, null); - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(RESPONSE_OUTPUTSTREAM_HASH, null); - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(UserDataTranslationHelper.getAttributeName(Log4JStrSubstitutor.class.getName()), null); - - // used internally by some methods before saving hash code hence cleanup required - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(REQUEST_STREAM_OR_READER_CALLED, null); - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(RESPONSE_STREAM_OR_WRITER_CALLED, null); - - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(GrpcHelper.NR_SEC_GRPC_REQUEST_DATA, null); - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(GrpcHelper.NR_SEC_GRPC_RESPONSE_DATA, null); + NewRelicSecurity.getAgent().getSecurityMetaData().clearCustomAttr(); + NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(Agent.OPERATIONS, new ArrayList<>()); + NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(Agent.EXIT_OPERATIONS, new ArrayList<>()); SecurityMetaData meta = NewRelicSecurity.getAgent().getSecurityMetaData(); meta.setRequest(new HttpRequest()); diff --git a/instrumentation-security/lettuce-4.3/src/test/java/com/nr/agent/instrumentation/lettuce_4_3/LettuceTest.java b/instrumentation-security/lettuce-4.3/src/test/java/com/nr/agent/instrumentation/lettuce_4_3/LettuceTest.java index 444200f2a..66e4af2f0 100644 --- a/instrumentation-security/lettuce-4.3/src/test/java/com/nr/agent/instrumentation/lettuce_4_3/LettuceTest.java +++ b/instrumentation-security/lettuce-4.3/src/test/java/com/nr/agent/instrumentation/lettuce_4_3/LettuceTest.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.net.ServerSocket; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -460,7 +461,12 @@ private static void verifier(CommandType cmd, RedisOperation operation, List T getCustomAttribute(String key, Class klass) { public void removeCustomAttribute(String key) { this.customData.remove(key); } + public void clearCustomAttr(){ + customData.clear(); + } } From 5d577f1021d6f3aca7c94ab22da6ff483e772296 Mon Sep 17 00:00:00 2001 From: Lovesh Baya Date: Fri, 8 Mar 2024 10:36:02 +0530 Subject: [PATCH 15/21] [NR-234870] GHA Update Unit Test Action (#204) GHA Update Unit Test Action for Testing Unit tests with different java-version Run Unit Tests on java version 8, 11, and 17 Mechanism to rerun UTs upto 4 attempts on failure Skip modules which do not have backward compatibility with specific java versions --------- Co-authored-by: idawda --- .../action.yml | 4 +- .github/actions/setup-environment/action.yml | 4 +- .github/actions/unit-test/action.yml | 39 ++++++++++++++++- .../X-Reusable-Build-Security-Agent.yml | 8 +++- .../apache-log4j-3.0.0/build.gradle | 7 +++ .../httpclient-jdk11/build.gradle | 4 +- .../javaio/InputStreamJdk8Test.java | 3 ++ .../java-io-inputstream-jdk9/build.gradle | 6 +-- .../inputstream/jdk9/InputStreamJdk9Test.java | 3 +- .../xpath/javax/XPathTest.java | 3 ++ .../javax/internal/XPathInternalTest.java | 3 ++ .../instrumentation/jersey2/JerseyTests.java | 5 +++ .../instrumentation/jersey2/JerseyTests.java | 5 +++ .../instrumentation/jersey2/JerseyTests.java | 4 ++ .../jetty-11/build.gradle | 8 ++++ .../jetty-12/build.gradle | 7 +++ instrumentation-security/jsp-3/build.gradle | 7 +++ .../ldaptive-2.0/build.gradle | 3 +- .../lettuce-4.3/build.gradle | 2 +- .../lettuce_4_3/LettuceTest.java | 43 ++++++------------- .../lettuce-5.0/build.gradle | 3 +- .../lettuce_5/LettuceTest.java | 38 ++++++---------- .../instrumentation/random/RandomTest.java | 10 ++--- .../servlet-6.0/build.gradle | 8 ++++ .../httpServer/test/HttpServerTest.java | 5 +++ 25 files changed, 157 insertions(+), 75 deletions(-) diff --git a/.github/actions/setup-environment-inst-verifier/action.yml b/.github/actions/setup-environment-inst-verifier/action.yml index 0e307833c..3ec3aadd7 100644 --- a/.github/actions/setup-environment-inst-verifier/action.yml +++ b/.github/actions/setup-environment-inst-verifier/action.yml @@ -17,6 +17,7 @@ runs: with: distribution: 'temurin' java-version: | + 21 20 17 11 @@ -29,7 +30,8 @@ runs: sed -i -e "s|jdk8=8|jdk8=${JAVA_HOME_8_X64}| s|jdk11=11|jdk11=${JAVA_HOME_11_X64}| s|jdk17=17|jdk17=${JAVA_HOME_17_X64}| - s|jdk20=20|jdk20=${JAVA_HOME_20_X64}|" gradle.properties.gha + s|jdk20=20|jdk20=${JAVA_HOME_20_X64}| + s|jdk21=21|jdk20=${JAVA_HOME_21_X64}|" gradle.properties.gha cat gradle.properties.gha >> gradle.properties - name: Setup Gradle diff --git a/.github/actions/setup-environment/action.yml b/.github/actions/setup-environment/action.yml index e8734b4ae..c9971074c 100644 --- a/.github/actions/setup-environment/action.yml +++ b/.github/actions/setup-environment/action.yml @@ -36,6 +36,7 @@ runs: with: distribution: 'temurin' java-version: | + 21 20 17 11 @@ -48,7 +49,8 @@ runs: sed -i -e "s|jdk8=8|jdk8=${JAVA_HOME_8_X64}| s|jdk11=11|jdk11=${JAVA_HOME_11_X64}| s|jdk17=17|jdk17=${JAVA_HOME_17_X64}| - s|jdk20=20|jdk20=${JAVA_HOME_20_X64}|" gradle.properties.gha + s|jdk20=20|jdk20=${JAVA_HOME_20_X64}| + s|jdk21=21|jdk21=${JAVA_HOME_21_X64}|" gradle.properties.gha cat gradle.properties.gha >> gradle.properties - name: Setup Gradle diff --git a/.github/actions/unit-test/action.yml b/.github/actions/unit-test/action.yml index 42e16e7e5..06ab3371d 100644 --- a/.github/actions/unit-test/action.yml +++ b/.github/actions/unit-test/action.yml @@ -1,10 +1,45 @@ name: Instrumentation unit tests description: Run all the instrumentation unit test. +inputs: + java-version: + description: 'The JVM Version to use' + required: true + default: '8' runs: using: composite steps: - - name: Run instrumentation unit tests + - name: Run instrumentation unit tests on Java ${{ inputs.java-version }} attempt 1 + id: run_tests_1 shell: bash - run: ./gradlew ${GRADLE_OPTIONS} --info test \ No newline at end of file + continue-on-error: true + run: | + echo "Running attempt 1" + ./gradlew ${GRADLE_OPTIONS} --info test -Ptest${{ inputs.java-version }} --continue + + - name: Run instrumentation unit tests on Java ${{ inputs.java-version }} attempt 2 + id: run_tests_2 + shell: bash + continue-on-error: true + if: steps.run_tests_1.outcome == 'failure' + run: | + echo "Running attempt 2" + ./gradlew ${GRADLE_OPTIONS} --info test -Ptest${{ inputs.java-version }} --continue + + - name: Run instrumentation unit tests on Java ${{ inputs.java-version }} attempt 3 + id: run_tests_3 + shell: bash + continue-on-error: true + if: steps.run_tests_2.outcome == 'failure' + run: | + echo "Running attempt 3" + ./gradlew ${GRADLE_OPTIONS} --info test -Ptest${{ inputs.java-version }} --continue + + - name: Run instrumentation unit tests on Java ${{ inputs.java-version }} attempt 4 + id: run_tests_4 + shell: bash + if: steps.run_tests_3.outcome == 'failure' + run: | + echo "Running attempt 4" + ./gradlew ${GRADLE_OPTIONS} --info test -Ptest${{ inputs.java-version }} --continue \ No newline at end of file diff --git a/.github/workflows/X-Reusable-Build-Security-Agent.yml b/.github/workflows/X-Reusable-Build-Security-Agent.yml index a084d358d..0d3779123 100644 --- a/.github/workflows/X-Reusable-Build-Security-Agent.yml +++ b/.github/workflows/X-Reusable-Build-Security-Agent.yml @@ -59,6 +59,10 @@ jobs: # this list is paginated and will be used in the verify-module job. build-agent: runs-on: ubuntu-20.04 + strategy: + matrix: + java-version: [ 8, 11, 17 ] + steps: - name: Checkout CSEC Repo uses: actions/checkout@v3 @@ -79,4 +83,6 @@ jobs: - name: Run CSEC unit tests if: ${{ inputs.run-unit-test == 'true' }} - uses: ./.github/actions/unit-test \ No newline at end of file + uses: ./.github/actions/unit-test + with: + java-version: ${{ matrix.java-version }} \ No newline at end of file diff --git a/instrumentation-security/apache-log4j-3.0.0/build.gradle b/instrumentation-security/apache-log4j-3.0.0/build.gradle index bc2e57321..816ac607a 100644 --- a/instrumentation-security/apache-log4j-3.0.0/build.gradle +++ b/instrumentation-security/apache-log4j-3.0.0/build.gradle @@ -23,3 +23,10 @@ java { languageVersion.set(JavaLanguageVersion.of(11)) } } + +test { + // These instrumentation tests only run on Java 11+ regardless of the -PtestN gradle property that is set. + onlyIf { + !project.hasProperty('test8') + } +} diff --git a/instrumentation-security/httpclient-jdk11/build.gradle b/instrumentation-security/httpclient-jdk11/build.gradle index 2b8ffcafa..b04e2464a 100644 --- a/instrumentation-security/httpclient-jdk11/build.gradle +++ b/instrumentation-security/httpclient-jdk11/build.gradle @@ -21,11 +21,13 @@ java { } test { + // These instrumentation tests only run on Java 11+ regardless of the -PtestN gradle property that is set. onlyIf { - inputs.getProperties()["test.jdk"]!="jdk8" + !project.hasProperty('test8') } } + compileJava { options.fork = true options.bootstrapClasspath = null diff --git a/instrumentation-security/java-io-inputstream-jdk8/src/test/java/com/nr/agent/security/instrumentation/javaio/InputStreamJdk8Test.java b/instrumentation-security/java-io-inputstream-jdk8/src/test/java/com/nr/agent/security/instrumentation/javaio/InputStreamJdk8Test.java index 3dacd2124..eaf99a847 100644 --- a/instrumentation-security/java-io-inputstream-jdk8/src/test/java/com/nr/agent/security/instrumentation/javaio/InputStreamJdk8Test.java +++ b/instrumentation-security/java-io-inputstream-jdk8/src/test/java/com/nr/agent/security/instrumentation/javaio/InputStreamJdk8Test.java @@ -5,6 +5,7 @@ import com.newrelic.agent.security.introspec.SecurityInstrumentationTestRunner; import com.newrelic.agent.security.introspec.SecurityIntrospector; import com.newrelic.api.agent.security.schema.SecurityMetaData; +import com.newrelic.security.test.marker.Java17IncompatibleTest; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; @@ -12,6 +13,7 @@ import org.junit.FixMethodOrder; import org.junit.Ignore; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; @@ -31,6 +33,7 @@ @RunWith(SecurityInstrumentationTestRunner.class) @InstrumentationTestConfig(includePrefixes = {"java.io","com.newrelic.agent.security.instrumentation.javaio"}) @FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Category({Java17IncompatibleTest.class}) public class InputStreamJdk8Test { private static String FILE; private static String FILE_TEMP; diff --git a/instrumentation-security/java-io-inputstream-jdk9/build.gradle b/instrumentation-security/java-io-inputstream-jdk9/build.gradle index c3772d271..738cb3c39 100644 --- a/instrumentation-security/java-io-inputstream-jdk9/build.gradle +++ b/instrumentation-security/java-io-inputstream-jdk9/build.gradle @@ -21,8 +21,8 @@ java { } test { -// These instrumentation tests only run on Java 9+ regardless of the -PtestN gradle property that is set. + // These instrumentation tests only run on Java 11+ regardless of the -PtestN gradle property that is set. onlyIf { - java.toolchain.getLanguageVersion().get().asInt() > 10 + !project.hasProperty('test8') } -} \ No newline at end of file +} diff --git a/instrumentation-security/java-io-inputstream-jdk9/src/test/java/com/nr/instrumentation/security/inputstream/jdk9/InputStreamJdk9Test.java b/instrumentation-security/java-io-inputstream-jdk9/src/test/java/com/nr/instrumentation/security/inputstream/jdk9/InputStreamJdk9Test.java index 8b45fda3e..07f481cf4 100644 --- a/instrumentation-security/java-io-inputstream-jdk9/src/test/java/com/nr/instrumentation/security/inputstream/jdk9/InputStreamJdk9Test.java +++ b/instrumentation-security/java-io-inputstream-jdk9/src/test/java/com/nr/instrumentation/security/inputstream/jdk9/InputStreamJdk9Test.java @@ -5,6 +5,7 @@ import com.newrelic.agent.security.introspec.SecurityIntrospector; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.security.test.marker.Java11IncompatibleTest; +import com.newrelic.security.test.marker.Java17IncompatibleTest; import com.newrelic.security.test.marker.Java8IncompatibleTest; import org.junit.AfterClass; import org.junit.Assert; @@ -30,7 +31,7 @@ import java.util.List; import java.util.UUID; -@Category({ Java8IncompatibleTest.class, Java11IncompatibleTest.class }) +@Category({ Java8IncompatibleTest.class, Java11IncompatibleTest.class, Java17IncompatibleTest.class }) @RunWith(SecurityInstrumentationTestRunner.class) @InstrumentationTestConfig(includePrefixes = {"com.newrelic.agent.security.instrumentation.javaio.io","com.newrelic.agent.security.instrumentation.javaio"}) @FixMethodOrder(MethodSorters.NAME_ASCENDING) diff --git a/instrumentation-security/javax-xpath/src/test/java/com/nr/agent/security/instrumentation/xpath/javax/XPathTest.java b/instrumentation-security/javax-xpath/src/test/java/com/nr/agent/security/instrumentation/xpath/javax/XPathTest.java index a897dfdee..37701dd21 100644 --- a/instrumentation-security/javax-xpath/src/test/java/com/nr/agent/security/instrumentation/xpath/javax/XPathTest.java +++ b/instrumentation-security/javax-xpath/src/test/java/com/nr/agent/security/instrumentation/xpath/javax/XPathTest.java @@ -7,10 +7,12 @@ import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.operation.XPathOperation; import com.newrelic.agent.security.instrumentation.xpath.javax.XPATHUtils; +import com.newrelic.security.test.marker.Java17IncompatibleTest; import org.junit.Assert; import org.junit.FixMethodOrder; import org.junit.Ignore; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; import org.w3c.dom.Document; @@ -25,6 +27,7 @@ @FixMethodOrder(MethodSorters.NAME_ASCENDING) @RunWith(SecurityInstrumentationTestRunner.class) @InstrumentationTestConfig(includePrefixes = { "javax.xml.xpath", "com.sun.org.apache.xpath.internal" }) +@Category({ Java17IncompatibleTest.class}) public class XPathTest { private final String XML_DOC = "src/test/resources/Customer.xml"; diff --git a/instrumentation-security/javax-xpath/src/test/java/com/nr/agent/security/instrumentation/xpath/javax/internal/XPathInternalTest.java b/instrumentation-security/javax-xpath/src/test/java/com/nr/agent/security/instrumentation/xpath/javax/internal/XPathInternalTest.java index b0510aa95..b6cb2dd49 100644 --- a/instrumentation-security/javax-xpath/src/test/java/com/nr/agent/security/instrumentation/xpath/javax/internal/XPathInternalTest.java +++ b/instrumentation-security/javax-xpath/src/test/java/com/nr/agent/security/instrumentation/xpath/javax/internal/XPathInternalTest.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.operation.XPathOperation; +import com.newrelic.security.test.marker.Java17IncompatibleTest; import com.sun.org.apache.xml.internal.utils.DefaultErrorHandler; import com.sun.org.apache.xml.internal.utils.PrefixResolver; import com.sun.org.apache.xml.internal.utils.PrefixResolverDefault; @@ -16,6 +17,7 @@ import org.junit.Assert; import org.junit.FixMethodOrder; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; import org.w3c.dom.Document; @@ -32,6 +34,7 @@ @RunWith(SecurityInstrumentationTestRunner.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @InstrumentationTestConfig(includePrefixes = { "javax.xml.xpath", "com.sun.org.apache.xpath.internal" }) +@Category({ Java17IncompatibleTest.class}) public class XPathInternalTest { private final String XML_DOC = "src/test/resources/Customer.xml"; private final String EXPRESSION = "/Customers/Customer"; diff --git a/instrumentation-security/jersey-2.16/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java b/instrumentation-security/jersey-2.16/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java index 0a3e317b1..d3ccc680e 100644 --- a/instrumentation-security/jersey-2.16/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java +++ b/instrumentation-security/jersey-2.16/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java @@ -18,6 +18,9 @@ import com.newrelic.api.agent.security.schema.HttpResponse; import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; +import com.newrelic.security.test.marker.Java11IncompatibleTest; +import com.newrelic.security.test.marker.Java17IncompatibleTest; +import com.newrelic.security.test.marker.Java9IncompatibleTest; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.grizzly.http.util.Header; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; @@ -26,6 +29,7 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import javax.ws.rs.client.Client; @@ -53,6 +57,7 @@ @RunWith(SecurityInstrumentationTestRunner.class) @InstrumentationTestConfig(includePrefixes = {"com.newrelic.agent.security.instrumentation.jersey2", "org.glassfish.jersey"}) +@Category({ Java9IncompatibleTest.class, Java11IncompatibleTest.class, Java17IncompatibleTest.class }) public class JerseyTests { private static HttpServer server; diff --git a/instrumentation-security/jersey-2/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java b/instrumentation-security/jersey-2/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java index 966b910dd..f418c45e8 100644 --- a/instrumentation-security/jersey-2/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java +++ b/instrumentation-security/jersey-2/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java @@ -18,6 +18,9 @@ import com.newrelic.api.agent.security.schema.HttpResponse; import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; +import com.newrelic.security.test.marker.Java11IncompatibleTest; +import com.newrelic.security.test.marker.Java17IncompatibleTest; +import com.newrelic.security.test.marker.Java9IncompatibleTest; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.grizzly.http.util.Header; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; @@ -26,6 +29,7 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import javax.ws.rs.client.Client; @@ -53,6 +57,7 @@ @RunWith(SecurityInstrumentationTestRunner.class) @InstrumentationTestConfig(includePrefixes = {"com.newrelic.agent.security.instrumentation.jersey2", "org.glassfish.jersey"}) +@Category({ Java9IncompatibleTest.class, Java11IncompatibleTest.class, Java17IncompatibleTest.class }) public class JerseyTests { private static HttpServer server; diff --git a/instrumentation-security/jersey-3/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java b/instrumentation-security/jersey-3/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java index 4bba34fb0..85ec2d538 100644 --- a/instrumentation-security/jersey-3/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java +++ b/instrumentation-security/jersey-3/src/test/java/com/nr/agent/security/instrumentation/jersey2/JerseyTests.java @@ -18,6 +18,8 @@ import com.newrelic.api.agent.security.schema.HttpResponse; import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; +import com.newrelic.security.test.marker.Java11IncompatibleTest; +import com.newrelic.security.test.marker.Java8IncompatibleTest; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.grizzly.http.util.Header; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; @@ -26,6 +28,7 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.ws.rs.client.Client; @@ -53,6 +56,7 @@ @RunWith(SecurityInstrumentationTestRunner.class) @InstrumentationTestConfig(includePrefixes = {"com.newrelic.agent.security.instrumentation.jersey2", "org.glassfish.jersey"}) +@Category({Java8IncompatibleTest.class, Java11IncompatibleTest.class}) public class JerseyTests { private static HttpServer server; diff --git a/instrumentation-security/jetty-11/build.gradle b/instrumentation-security/jetty-11/build.gradle index 205e4f419..9752e24f4 100644 --- a/instrumentation-security/jetty-11/build.gradle +++ b/instrumentation-security/jetty-11/build.gradle @@ -21,6 +21,14 @@ java { } } +test { + // These instrumentation tests only run on Java 11+ regardless of the -PtestN gradle property that is set. + onlyIf { + !project.hasProperty('test8') + } +} + + site { title 'Jetty' type 'Appserver' diff --git a/instrumentation-security/jetty-12/build.gradle b/instrumentation-security/jetty-12/build.gradle index 8501cd8aa..d5a7f7742 100644 --- a/instrumentation-security/jetty-12/build.gradle +++ b/instrumentation-security/jetty-12/build.gradle @@ -22,6 +22,13 @@ java { } } +test { + // These instrumentation tests only run on Java 17+ regardless of the -PtestN gradle property that is set. + onlyIf { + !project.hasProperty('test8') && !project.hasProperty('test11') + } +} + site { title 'Jetty' type 'Appserver' diff --git a/instrumentation-security/jsp-3/build.gradle b/instrumentation-security/jsp-3/build.gradle index 9aa2ebb11..8a85b3374 100644 --- a/instrumentation-security/jsp-3/build.gradle +++ b/instrumentation-security/jsp-3/build.gradle @@ -24,6 +24,13 @@ java { } } +test { + // These instrumentation tests only run on Java 11+ regardless of the -PtestN gradle property that is set. + onlyIf { + !project.hasProperty('test8') + } +} + site { title 'JSP' type 'Other' diff --git a/instrumentation-security/ldaptive-2.0/build.gradle b/instrumentation-security/ldaptive-2.0/build.gradle index 1e40179e9..7f6ab5a78 100644 --- a/instrumentation-security/ldaptive-2.0/build.gradle +++ b/instrumentation-security/ldaptive-2.0/build.gradle @@ -25,8 +25,9 @@ java { } test { + // These instrumentation tests only run on Java 11+ regardless of the -PtestN gradle property that is set. onlyIf { - inputs.getProperties()["test.jdk"]!="jdk8" && inputs.getProperties()["test.jdk"]!="jdk9" && inputs.getProperties()["test.jdk"]!="jdk10" + !project.hasProperty('test8') } } diff --git a/instrumentation-security/lettuce-4.3/build.gradle b/instrumentation-security/lettuce-4.3/build.gradle index 8564b18fc..dc25f4434 100644 --- a/instrumentation-security/lettuce-4.3/build.gradle +++ b/instrumentation-security/lettuce-4.3/build.gradle @@ -3,7 +3,7 @@ dependencies { implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}") implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}") implementation("biz.paluch.redis:lettuce:4.4.0.Final") - testImplementation("com.github.codemonstur:embedded-redis:1.0.0") + testImplementation('org.testcontainers:testcontainers:1.17.1') } jar { diff --git a/instrumentation-security/lettuce-4.3/src/test/java/com/nr/agent/instrumentation/lettuce_4_3/LettuceTest.java b/instrumentation-security/lettuce-4.3/src/test/java/com/nr/agent/instrumentation/lettuce_4_3/LettuceTest.java index 66e4af2f0..6c036b8e5 100644 --- a/instrumentation-security/lettuce-4.3/src/test/java/com/nr/agent/instrumentation/lettuce_4_3/LettuceTest.java +++ b/instrumentation-security/lettuce-4.3/src/test/java/com/nr/agent/instrumentation/lettuce_4_3/LettuceTest.java @@ -1,6 +1,5 @@ package com.nr.agent.instrumentation.lettuce_4_3; -import com.lambdaworks.redis.AbstractRedisAsyncCommands; import com.lambdaworks.redis.RedisAsyncCommandsImpl; import com.lambdaworks.redis.RedisClient; import com.lambdaworks.redis.api.StatefulRedisConnection; @@ -19,32 +18,35 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; -import redis.embedded.RedisServer; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import java.io.IOException; import java.net.ServerSocket; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.UUID; -import static com.lambdaworks.redis.protocol.CommandType.SET; - @RunWith(SecurityInstrumentationTestRunner.class) @InstrumentationTestConfig(includePrefixes = "com.lambdaworks.redis") @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class LettuceTest { - private static RedisServer redisServer; private static int PORT = 0; + public static GenericContainer redis; + @BeforeClass - public static void setup() throws Exception { - PORT = getRandomPort(); - redisServer = new RedisServer(PORT); - redisServer.start(); - System.out.println(redisServer); + public static void setup() { + PORT = SecurityInstrumentationTestRunner.getIntrospector().getRandomPort(); + redis = new GenericContainer<>(DockerImageName.parse("redis:5.0.3-alpine")); + redis.setPortBindings(Collections.singletonList(PORT + ":6379")); + redis.start(); + } + @AfterClass + public static void tearDown() { + redis.stop(); } @Test @@ -447,11 +449,6 @@ public void testSadd_Sdiff_Scard_Smove_Srem() { verifier(CommandType.SREM, operation, Arrays.asList(keyValuePair1.getKey(), "test")); } - @AfterClass - public static void tearDown() throws Exception { - redisServer.stop(); - } - private static void opVerifier(List operations, int expected) { Assert.assertTrue("No operations detected.", operations.size() > 0); Assert.assertEquals("Unexpected number of operations detected.", expected, operations.size()); @@ -473,19 +470,7 @@ private static void verifier(CommandType cmd, RedisOperation operation, List redis; + @BeforeClass - public static void setup() throws Exception { - PORT = getRandomPort(); - redisServer = new RedisServer(PORT); - redisServer.start(); - System.out.println(redisServer); + public static void setup() { + PORT = SecurityInstrumentationTestRunner.getIntrospector().getRandomPort(); + redis = new GenericContainer<>(DockerImageName.parse("redis:5.0.3-alpine")); + redis.setPortBindings(Collections.singletonList(PORT + ":6379")); + redis.start(); + } + @AfterClass + public static void tearDown() { + redis.stop(); } @Test @@ -444,11 +450,6 @@ public void testSadd_Sdiff_Scard_Smove_Srem() { verifier(CommandType.SREM, operation, Arrays.asList(keyValuePair1.getKey(), "test")); } - @AfterClass - public static void tearDown() throws Exception { - redisServer.stop(); - } - private static void opVerifier(List operations, int expected) { Assert.assertTrue("No operations detected.", operations.size() > 0); Assert.assertEquals("Unexpected number of operations detected.", expected, operations.size()); @@ -470,19 +471,6 @@ private static void verifier(CommandType cmd, RedisOperation operation, List Date: Fri, 8 Mar 2024 10:58:56 +0530 Subject: [PATCH 16/21] Update change log --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index 287075429..2e1a634ee 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,9 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Mule Support: The security agent now also supports Mule server version 3.6 to 3.9.x - Jetty v12 Support: The security agent now also support Jetty version 12 and above - Lettuce Support: The security agent now also supports Lettuce 4.4.0.Final and above +- [NR-234869](https://new-relic.atlassian.net/browse/NR-234869) GHA Update Unit Test Action for Testing Unit tests with different java-version with re-tries on failure [PR-204](https://github.com/newrelic/csec-java-agent/pull/204) ### Fixes - Extract Server Configuration to resolve IAST localhost connection with application for wildfly server +- [NR-234903](https://new-relic.atlassian.net/browse/NR-234903) Trustboundary events now will have list of string as parameter schema ## [1.1.1] - 2024-2-16 ### Changes From 19ce7bdea8a34d94fdd80dd76cb7ca265f029e44 Mon Sep 17 00:00:00 2001 From: idawda Date: Fri, 8 Mar 2024 11:04:16 +0530 Subject: [PATCH 17/21] updated README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 3a67dae46..51e0ea935 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ The agent automatically instruments the following frameworks. - Jetty 9.3.0.M1 to latest - Mule ESB 3.6 to 3.9.x - gRPC 1.4.0 to latest** +- Jersey 2.0 to latest ** IAST for **gRPC** requires the dependency [protobuf-java-util](https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java-util) for IAST request replay. @@ -64,6 +65,7 @@ The agent automatically instruments the following HTTP clients and messaging ser - Saxpath 1.0 - Xalan XPATH 2.1.0 to latest - Async Http Client from 2.0 to latest +- Ning Async HTTP Client 1.0.0 to latest ### Datastores From c0244dc350b6650b1c9c878ac5bc8d0a3c0c25af Mon Sep 17 00:00:00 2001 From: idawda Date: Fri, 8 Mar 2024 11:13:52 +0530 Subject: [PATCH 18/21] updated Changelog.md with PR and jira links --- Changelog.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Changelog.md b/Changelog.md index 2e1a634ee..8b8a75e1e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,15 +5,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [1.1.2] - TO BE DECIDED ### Changes -- Ning Async HTTP client Support: The security agent now also supports com.ning:async-http-client 1.0.0 and above -- Jersey Support: The security agent now also supports Jersey 2.0 and above -- Mule Support: The security agent now also supports Mule server version 3.6 to 3.9.x -- Jetty v12 Support: The security agent now also support Jetty version 12 and above -- Lettuce Support: The security agent now also supports Lettuce 4.4.0.Final and above +- [NR-174177](https://new-relic.atlassian.net/browse/NR-174177) Ning Async HTTP client Support: The security agent now also supports com.ning:async-http-client 1.0.0 and above [PR-152](https://github.com/newrelic/csec-java-agent/pull/152), [PR-118](https://github.com/newrelic/csec-java-agent/pull/118), [PR-116](https://github.com/newrelic/csec-java-agent/pull/116) +- [NR-181375](https://new-relic.atlassian.net/browse/NR-181375) Jersey Support: The security agent now also supports Jersey 2.0 and above [PR-150](https://github.com/newrelic/csec-java-agent/pull/150), [PR-149](https://github.com/newrelic/csec-java-agent/pull/149) +- [NR-187224](https://new-relic.atlassian.net/browse/NR-187224) Mule Support: The security agent now also supports Mule server version 3.6 to 3.9.x [PR-144](https://github.com/newrelic/csec-java-agent/pull/144), [PR-143](https://github.com/newrelic/csec-java-agent/pull/143) +- Jetty v12 Support: The security agent now also support Jetty version 12 and above [PR-106](https://github.com/newrelic/csec-java-agent/pull/106) +- [NR-174175](https://new-relic.atlassian.net/browse/NR-174175) Lettuce Support: The security agent now also supports Lettuce 4.4.0.Final and above [PR-125](https://github.com/newrelic/csec-java-agent/pull/125) - [NR-234869](https://new-relic.atlassian.net/browse/NR-234869) GHA Update Unit Test Action for Testing Unit tests with different java-version with re-tries on failure [PR-204](https://github.com/newrelic/csec-java-agent/pull/204) ### Fixes -- Extract Server Configuration to resolve IAST localhost connection with application for wildfly server +- [NR-223811](https://new-relic.atlassian.net/browse/NR-223811) Extract Server Configuration to resolve IAST localhost connection with application for wildfly server [PR-192](https://github.com/newrelic/csec-java-agent/pull/192) - [NR-234903](https://new-relic.atlassian.net/browse/NR-234903) Trustboundary events now will have list of string as parameter schema ## [1.1.1] - 2024-2-16 From 900b0990332635f7bedc69848be72612d65f197e Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Fri, 8 Mar 2024 12:30:00 +0530 Subject: [PATCH 19/21] Publish CSEC to local in Integrated build job --- .github/workflows/build-integrated-jar.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-integrated-jar.yml b/.github/workflows/build-integrated-jar.yml index 6d5fc9751..6be5d6d80 100644 --- a/.github/workflows/build-integrated-jar.yml +++ b/.github/workflows/build-integrated-jar.yml @@ -71,6 +71,9 @@ jobs: apm-aws-secret-access-key: ${{ secrets.APM_AWS_SECRET_ACCESS_KEY }} apm-aws-region: us-east-2 + - name: Publish CSEC to local + uses: ./.github/actions/publish-csec-local + - name: Build Integrated Agent Jar uses: ./.github/actions/build-apm-jar From 03c3d0f1859298a8cdd272812c4e88348a758a3e Mon Sep 17 00:00:00 2001 From: Lovesh Baya Date: Mon, 11 Mar 2024 16:59:49 +0530 Subject: [PATCH 20/21] Update build-integrated-jar.yml Remove rebuilding of agent --- .github/workflows/build-integrated-jar.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/build-integrated-jar.yml b/.github/workflows/build-integrated-jar.yml index 6be5d6d80..6d5fc9751 100644 --- a/.github/workflows/build-integrated-jar.yml +++ b/.github/workflows/build-integrated-jar.yml @@ -71,9 +71,6 @@ jobs: apm-aws-secret-access-key: ${{ secrets.APM_AWS_SECRET_ACCESS_KEY }} apm-aws-region: us-east-2 - - name: Publish CSEC to local - uses: ./.github/actions/publish-csec-local - - name: Build Integrated Agent Jar uses: ./.github/actions/build-apm-jar From cb5c691947e2768ae69e3791ab3e2d7a6451583b Mon Sep 17 00:00:00 2001 From: Lovesh Baya Date: Mon, 11 Mar 2024 17:03:48 +0530 Subject: [PATCH 21/21] Changelog.md update release date --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 8b8a75e1e..367a24675 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,7 +3,7 @@ Noteworthy changes to the agent are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.1.2] - TO BE DECIDED +## [1.1.2] - 2024-3-11 ### Changes - [NR-174177](https://new-relic.atlassian.net/browse/NR-174177) Ning Async HTTP client Support: The security agent now also supports com.ning:async-http-client 1.0.0 and above [PR-152](https://github.com/newrelic/csec-java-agent/pull/152), [PR-118](https://github.com/newrelic/csec-java-agent/pull/118), [PR-116](https://github.com/newrelic/csec-java-agent/pull/116) - [NR-181375](https://new-relic.atlassian.net/browse/NR-181375) Jersey Support: The security agent now also supports Jersey 2.0 and above [PR-150](https://github.com/newrelic/csec-java-agent/pull/150), [PR-149](https://github.com/newrelic/csec-java-agent/pull/149)