From 59021cd95bfff0278fceb1de154a027333017d7a Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Tue, 3 Oct 2023 17:11:02 +0530 Subject: [PATCH 1/3] Support for com.ning:async-http-client (from 1.0.0 to 1.1.0) --- .../ning-async-http-client-1.0.0/build.gradle | 19 +++++ .../ning/http_1_0/NingHelper.java | 85 +++++++++++++++++++ .../AsyncHttpProvider_Instrumentation.java | 47 ++++++++++ .../RequestBuilderBase_Instrumentation.java | 24 ++++++ .../src/main/java/play/CorePlugin.java | 11 +++ settings.gradle | 3 +- 6 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 instrumentation-security/ning-async-http-client-1.0.0/build.gradle create mode 100644 instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_0/NingHelper.java create mode 100644 instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java create mode 100644 instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/ning/http/client/RequestBuilderBase_Instrumentation.java create mode 100644 instrumentation-security/ning-async-http-client-1.0.0/src/main/java/play/CorePlugin.java diff --git a/instrumentation-security/ning-async-http-client-1.0.0/build.gradle b/instrumentation-security/ning-async-http-client-1.0.0/build.gradle new file mode 100644 index 000000000..f1ddb2890 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.0.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.0.0") +} + +jar { + manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.ning-async-http-client-1.0.0' } +} + +verifyInstrumentation { + passesOnly 'com.ning:async-http-client:[1.0,1.1)' +} + +site { + title 'Ning AsyncHttpClient' + type 'Messaging' +} \ No newline at end of file diff --git a/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_0/NingHelper.java b/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_0/NingHelper.java new file mode 100644 index 000000000..53e6dbab7 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_0/NingHelper.java @@ -0,0 +1,85 @@ +package com.newrelic.agent.security.instrumentation.ning.http_1_0; + +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; + +import java.net.URI; +import java.net.URISyntaxException; + +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.0.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java b/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java new file mode 100644 index 000000000..1bfdbbf09 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java @@ -0,0 +1,47 @@ +package com.ning.http.client; + +import com.newrelic.agent.security.instrumentation.ning.http_1_0.NingHelper; +import com.newrelic.api.agent.NewRelic; +import com.newrelic.api.agent.Segment; +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.0.0/src/main/java/com/ning/http/client/RequestBuilderBase_Instrumentation.java b/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/ning/http/client/RequestBuilderBase_Instrumentation.java new file mode 100644 index 000000000..e291f0429 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/ning/http/client/RequestBuilderBase_Instrumentation.java @@ -0,0 +1,24 @@ +/* + * + * * Copyright 2020 New Relic Corporation. All rights reserved. + * * SPDX-License-Identifier: Apache-2.0 + * + */ + +package com.ning.http.client; + +import com.newrelic.api.agent.weaver.Weave; + +@Weave(originalName = "com.ning.http.client.RequestBuilderBase") +abstract class RequestBuilderBase_Instrumentation { + + @Weave(originalName = "com.ning.http.client.RequestBuilderBase$RequestImpl") + private abstract static class RequestImpl_Instrumentation { + private Headers headers; + + // Added this instrumentation to return modifiable headers instead + public Headers getHeaders() { + return headers; + } + } +} diff --git a/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/play/CorePlugin.java b/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/play/CorePlugin.java new file mode 100644 index 000000000..1d68ebdd2 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.0.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 { +} diff --git a/settings.gradle b/settings.gradle index 1837947c2..dabaa5e0b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -149,4 +149,5 @@ include 'instrumentation:commons-jxpath' //include 'instrumentation:spring-webmvc-5.3.0' //include 'instrumentation:apache-wicket-6.4' //include 'instrumentation:apache-wicket-7.0' -//include 'instrumentation:apache-wicket-8.0' \ No newline at end of file +//include 'instrumentation:apache-wicket-8.0' +include 'instrumentation:ning-async-http-client-1.0.0' \ No newline at end of file From 78847946c6e9bbb9d97329adc4ed5d84327a5bbc Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Tue, 3 Oct 2023 17:11:40 +0530 Subject: [PATCH 2/3] Test: Added unit test cases for com.ning:async-http-client (from 1.0.0 to 1.1.0) --- .../http_1_0/NingAsyncHttpClient10Test.java | 428 ++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 instrumentation-security/ning-async-http-client-1.0.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_0/NingAsyncHttpClient10Test.java diff --git a/instrumentation-security/ning-async-http-client-1.0.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_0/NingAsyncHttpClient10Test.java b/instrumentation-security/ning-async-http-client-1.0.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_0/NingAsyncHttpClient10Test.java new file mode 100644 index 000000000..e613e8ed2 --- /dev/null +++ b/instrumentation-security/ning-async-http-client-1.0.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_0/NingAsyncHttpClient10Test.java @@ -0,0 +1,428 @@ +package com.nr.agent.security.instrumentation.ning.http_1_0; + +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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +@RunWith(SecurityInstrumentationTestRunner.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@InstrumentationTestConfig(includePrefixes = { "com.newrelic.agent.security.instrumentation.ning.http_1_0", "com.ning" }) +public class NingAsyncHttpClient10Test { + + 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 3f2ff1778e25c20b361c4be89a03d4788b6c21cd Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Mon, 9 Oct 2023 17:09:15 +0530 Subject: [PATCH 3/3] UTs for csec parent id header in com.ning:async-http-client (from 1.0.0 to 1.1.0) --- .../http_1_0/NingAsyncHttpClient10Test.java | 99 +++++++------------ 1 file changed, 36 insertions(+), 63 deletions(-) diff --git a/instrumentation-security/ning-async-http-client-1.0.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_0/NingAsyncHttpClient10Test.java b/instrumentation-security/ning-async-http-client-1.0.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_0/NingAsyncHttpClient10Test.java index e613e8ed2..e65d77273 100644 --- a/instrumentation-security/ning-async-http-client-1.0.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_0/NingAsyncHttpClient10Test.java +++ b/instrumentation-security/ning-async-http-client-1.0.0/src/test/java/com/nr/agent/security/instrumentation/ning/http_1_0/NingAsyncHttpClient10Test.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; @@ -51,8 +52,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()); @@ -63,11 +63,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 @@ -78,8 +74,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()); @@ -90,11 +85,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 @@ -105,8 +96,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()); @@ -117,11 +107,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 @@ -132,8 +118,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()); @@ -144,11 +129,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 @@ -159,8 +140,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()); @@ -171,11 +151,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 @@ -186,8 +162,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()); @@ -198,11 +173,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 @@ -213,8 +184,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()); @@ -225,11 +195,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 @@ -240,8 +206,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()); @@ -252,11 +217,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 @@ -267,8 +228,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()); @@ -279,11 +239,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) @@ -425,4 +381,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())); + } }