diff --git a/gradle.properties b/gradle.properties index 73364766c..60f520ebb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # The agent version. agentVersion=1.4.0 -jsonVersion=1.2.1 +jsonVersion=2.0.0 # Updated exposed NR APM API version. nrAPIVersion=8.4.0 diff --git a/instrumentation-security/akka-http-2.11_10.0.0/src/main/scala/akka/http/scaladsl/server/AkkaCoreUtils.java b/instrumentation-security/akka-http-2.11_10.0.0/src/main/scala/akka/http/scaladsl/server/AkkaCoreUtils.java index b1a26e7bd..aaae2af25 100644 --- a/instrumentation-security/akka-http-2.11_10.0.0/src/main/scala/akka/http/scaladsl/server/AkkaCoreUtils.java +++ b/instrumentation-security/akka-http-2.11_10.0.0/src/main/scala/akka/http/scaladsl/server/AkkaCoreUtils.java @@ -9,6 +9,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; +import com.newrelic.api.agent.security.schema.RequestCategory; 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; @@ -17,7 +18,6 @@ import com.newrelic.api.agent.security.utils.logging.LogLevel; import java.util.Iterator; -import java.util.Map; import java.util.NoSuchElementException; public class AkkaCoreUtils { @@ -115,7 +115,9 @@ public static void preProcessHttpRequest (Boolean isServletLockAcquired, HttpReq processHttpRequestHeader(httpRequest, securityRequest); - securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(getProtocol(httpRequest.protocol().value())); @@ -146,17 +148,6 @@ public static void preProcessHttpRequest (Boolean isServletLockAcquired, HttpReq } } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static void processHttpRequestHeader(HttpRequest request, com.newrelic.api.agent.security.schema.HttpRequest securityRequest){ Iterator headers = request.getHeaders().iterator(); while (headers.hasNext()) { diff --git a/instrumentation-security/akka-http-core-10.0/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java b/instrumentation-security/akka-http-core-10.0/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java index 284d64b7a..2bfda3fef 100644 --- a/instrumentation-security/akka-http-core-10.0/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java +++ b/instrumentation-security/akka-http-core-10.0/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java @@ -9,6 +9,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; +import com.newrelic.api.agent.security.schema.RequestCategory; 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; @@ -119,7 +120,10 @@ public static void preProcessHttpRequest (Boolean isServletLockAcquired, HttpReq processHttpRequestHeader(httpRequest, securityRequest); - securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), + securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(getProtocol(httpRequest.protocol().value())); @@ -149,17 +153,6 @@ public static void preProcessHttpRequest (Boolean isServletLockAcquired, HttpReq } } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static void processHttpRequestHeader(HttpRequest request, com.newrelic.api.agent.security.schema.HttpRequest securityRequest){ Iterator headers = request.getHeaders().iterator(); while (headers.hasNext()) { diff --git a/instrumentation-security/akka-http-core-2.11_10.0.11/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java b/instrumentation-security/akka-http-core-2.11_10.0.11/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java index 0a0d4fb68..e567e7fa2 100644 --- a/instrumentation-security/akka-http-core-2.11_10.0.11/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java +++ b/instrumentation-security/akka-http-core-2.11_10.0.11/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java @@ -9,6 +9,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; +import com.newrelic.api.agent.security.schema.RequestCategory; 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; @@ -119,7 +120,9 @@ public static void preProcessHttpRequest (Boolean isServletLockAcquired, HttpReq processHttpRequestHeader(httpRequest, securityRequest); - securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(getProtocol(httpRequest.protocol().value())); @@ -149,17 +152,6 @@ public static void preProcessHttpRequest (Boolean isServletLockAcquired, HttpReq } } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static void processHttpRequestHeader(HttpRequest request, com.newrelic.api.agent.security.schema.HttpRequest securityRequest){ Iterator headers = request.getHeaders().iterator(); while (headers.hasNext()) { diff --git a/instrumentation-security/akka-http-core-2.13_10.2.0/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java b/instrumentation-security/akka-http-core-2.13_10.2.0/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java index 1f3e651c8..b5e40e2ae 100644 --- a/instrumentation-security/akka-http-core-2.13_10.2.0/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java +++ b/instrumentation-security/akka-http-core-2.13_10.2.0/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java @@ -1,6 +1,5 @@ package akka.http.scaladsl; -import akka.Done; import akka.http.javadsl.model.HttpHeader; import akka.http.scaladsl.model.HttpRequest; import com.newrelic.api.agent.Token; @@ -10,6 +9,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; +import com.newrelic.api.agent.security.schema.RequestCategory; 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; @@ -119,7 +119,9 @@ public static void preProcessHttpRequest (Boolean isServletLockAcquired, HttpReq processHttpRequestHeader(httpRequest, securityRequest); - securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(getProtocol(httpRequest.protocol().value())); @@ -159,17 +161,6 @@ private static String getProtocol(String value) { } } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static void processHttpRequestHeader(HttpRequest request, com.newrelic.api.agent.security.schema.HttpRequest securityRequest){ Iterator headers = request.getHeaders().iterator(); while (headers.hasNext()) { diff --git a/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/GrpcServerUtils.java b/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/GrpcServerUtils.java index 711c0c23d..79b550e06 100644 --- a/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/GrpcServerUtils.java +++ b/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/GrpcServerUtils.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.*; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -67,7 +68,9 @@ public static void preprocessSecurityHook(ServerStream_Instrumentat processGRPCRequestMetadata(meta, securityRequest); - securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.GRPC); if (call.getAttributes().get(Grpc.TRANSPORT_ATTR_SSL_SESSION) != null) { securityRequest.setProtocol("https"); @@ -157,17 +160,6 @@ private static boolean isLockAcquired(String nrSecCustomAttrName) { return false; } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static void processGRPCRequestMetadata(Metadata metadata, HttpRequest securityRequest) { Set headerNames = metadata.keys(); for (String headerKey : headerNames) { diff --git a/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/client/GrpcClient.java b/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/client/GrpcClient.java index 54e02b882..1e66f55ef 100644 --- a/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/client/GrpcClient.java +++ b/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/client/GrpcClient.java @@ -7,6 +7,7 @@ import com.google.protobuf.Message; import com.google.protobuf.util.JsonFormat; import com.newrelic.agent.security.instrumentation.grpc1220.GrpcServerUtils; +import com.newrelic.agent.security.instrumentation.grpc1220.processor.GrpcRequestProcessor; import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GrpcHelper; import com.newrelic.api.agent.security.schema.ControlCommandDto; @@ -55,7 +56,9 @@ protected ManagedChannel initialValue() { } }; - public Object fireRequest(ControlCommandDto controlCommandDto, int repeatCount) { + public Object fireRequest(GrpcRequestProcessor grpcRequestProcessor) { + ControlCommandDto controlCommandDto = grpcRequestProcessor.getControlCommandDto(); + int repeatCount = grpcRequestProcessor.getRepeatCount(); try { FuzzRequestBean requestBean = controlCommandDto.getRequestBean(); List payloads = controlCommandDto.getRequestPayloads(); @@ -82,13 +85,20 @@ public Object fireRequest(ControlCommandDto controlCommandDto, int repeatCount) isSuccess = customBiDiStream(channel, requestBean, payloads); break; } + grpcRequestProcessor.setSuccessful(true); + return isSuccess; } catch (InterruptedException e) { + grpcRequestProcessor.setExceptionRaised(true); + grpcRequestProcessor.setError(e); + if (repeatCount >= 0) { - return fireRequest(controlCommandDto, --repeatCount); + return fireRequest(grpcRequestProcessor); } return false; } catch (Throwable e) { + grpcRequestProcessor.setExceptionRaised(true); + grpcRequestProcessor.setError(e); return e; } } diff --git a/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/processor/GrpcRequestProcessor.java b/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/processor/GrpcRequestProcessor.java index 2964fb0bd..e47918f99 100644 --- a/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/processor/GrpcRequestProcessor.java +++ b/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/processor/GrpcRequestProcessor.java @@ -1,13 +1,9 @@ package com.newrelic.agent.security.instrumentation.grpc1220.processor; import com.newrelic.agent.security.instrumentation.grpc1220.client.GrpcClient; -import com.newrelic.api.agent.security.NewRelicSecurity; -import com.newrelic.api.agent.security.instrumentation.helpers.GrpcClientRequestReplayHelper; import com.newrelic.api.agent.security.schema.ControlCommandDto; -import com.newrelic.api.agent.security.utils.logging.LogLevel; import java.util.concurrent.Callable; -import java.util.concurrent.Future; public class GrpcRequestProcessor implements Callable { public static final String CALL_FAILED_REQUEST_S_REASON = "Call failed : request %s reason : %s "; @@ -15,6 +11,14 @@ public class GrpcRequestProcessor implements Callable { private int repeatCount; private static final int MAX_REPETITION = 3; + private boolean isSuccessful = false; + + private int responseCode; + + private boolean exceptionRaised = false; + + private Throwable error; + public GrpcRequestProcessor(ControlCommandDto controlCommandDto, int repeatCount) { this.controlCommandDto = controlCommandDto; this.repeatCount = repeatCount; @@ -22,33 +26,55 @@ public GrpcRequestProcessor(ControlCommandDto controlCommandDto, int repeatCount @Override public Object call() throws Exception { - return GrpcClient.getInstance().fireRequest(controlCommandDto, repeatCount); + return GrpcClient.getInstance().fireRequest(this); } public static void executeGrpcRequest(ControlCommandDto controlCommandDto) { - Future future = GrpcRequestThreadPool.getInstance().executor + GrpcRequestThreadPool.getInstance().executor .submit(new GrpcRequestProcessor(controlCommandDto, MAX_REPETITION)); - try { - Object futureResult = future.get(); - if (futureResult instanceof Throwable) { - NewRelicSecurity.getAgent().log(LogLevel.FINER, String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getRequestBean(), ((Throwable) futureResult).getMessage()), (Throwable) futureResult, GrpcClient.class.getName()); - NewRelicSecurity.getAgent().reportIncident(LogLevel.WARNING, - String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getId(), ((Throwable) futureResult).getMessage()), - (Throwable) futureResult, GrpcClient.class.getName()); - GrpcClientRequestReplayHelper.getInstance().addFuzzFailEventToQueue(controlCommandDto.getRequestBean(), (Throwable) futureResult); - } else { - GrpcClientRequestReplayHelper.getInstance().getPendingIds().remove(controlCommandDto.getId()); - } - } catch (Throwable e) { - NewRelicSecurity.getAgent().log(LogLevel.SEVERE, String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getRequestBean(), e.getMessage()), e, GrpcRequestProcessor.class.getName()); - NewRelicSecurity.getAgent().reportIncident(LogLevel.SEVERE, - String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getId(), e.getMessage()), - e, GrpcRequestProcessor.class.getName()); - GrpcClientRequestReplayHelper.getInstance().addFuzzFailEventToQueue(controlCommandDto.getRequestBean(), e); - } } public ControlCommandDto getPartialControlCommand() { return controlCommandDto; } + + public boolean isSuccessful() { + return isSuccessful; + } + + public void setSuccessful(boolean successful) { + isSuccessful = successful; + } + + public int getResponseCode() { + return responseCode; + } + + public void setResponseCode(int responseCode) { + this.responseCode = responseCode; + } + + public boolean isExceptionRaised() { + return exceptionRaised; + } + + public void setExceptionRaised(boolean exceptionRaised) { + this.exceptionRaised = exceptionRaised; + } + + public Throwable getError() { + return error; + } + + public void setError(Throwable error) { + this.error = error; + } + + public ControlCommandDto getControlCommandDto() { + return controlCommandDto; + } + + public int getRepeatCount() { + return repeatCount; + } } \ No newline at end of file diff --git a/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/processor/GrpcRequestThreadPool.java b/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/processor/GrpcRequestThreadPool.java index 178defe2c..50b133570 100644 --- a/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/processor/GrpcRequestThreadPool.java +++ b/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/processor/GrpcRequestThreadPool.java @@ -5,10 +5,9 @@ import com.newrelic.api.agent.security.schema.StringUtils; import com.newrelic.api.agent.security.utils.logging.LogLevel; -import java.util.HashSet; +import java.io.InterruptedIOException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RunnableFuture; import java.util.concurrent.ThreadFactory; @@ -50,21 +49,28 @@ protected void afterExecute(Runnable r, Throwable t) { GrpcClientRequestReplayHelper.getInstance().setInProcessRequestQueue(getQueue()); controlCommandId = null; if (r instanceof CustomFutureTask && ((CustomFutureTask) r).getTask() instanceof GrpcRequestProcessor) { - Object result = (Object) ((CustomFutureTask) r).get(); + GrpcClientRequestReplayHelper.getInstance().incrementReplayRequestExecuted(); GrpcRequestProcessor task = (GrpcRequestProcessor) ((CustomFutureTask) r).getTask(); controlCommandId = task.getPartialControlCommand().getId(); - if (t != null || result != null) { - if (StringUtils.isNotBlank(controlCommandId)) { - GrpcClientRequestReplayHelper.getInstance().getRejectedIds().add(controlCommandId); - } + + if (task.isSuccessful()) { + GrpcClientRequestReplayHelper.getInstance().incrementReplayRequestSucceeded(); + GrpcClientRequestReplayHelper.getInstance().getCompletedReplay().add(controlCommandId); + } else if (task.isExceptionRaised() && task.getError() instanceof InterruptedIOException) { + GrpcClientRequestReplayHelper.getInstance().getClearFromPending().add(controlCommandId); + } else if(task.isExceptionRaised()) { + GrpcClientRequestReplayHelper.getInstance().getErrorInReplay().add(controlCommandId); } else { - GrpcClientRequestReplayHelper.getInstance().getProcessedIds().putIfAbsent(controlCommandId, new HashSet<>()); + GrpcClientRequestReplayHelper.getInstance().getClearFromPending().add(controlCommandId); + } + if (StringUtils.isBlank(controlCommandId)) { + GrpcClientRequestReplayHelper.getInstance().getRejectedIds().add(controlCommandId); + } + if (!task.isSuccessful()){ + GrpcClientRequestReplayHelper.getInstance().incrementReplayRequestFailed(); } } - if (StringUtils.isNotBlank(controlCommandId)) { - GrpcClientRequestReplayHelper.getInstance().getPendingIds().remove(controlCommandId); - } - } catch (InterruptedException | ExecutionException ignored) { + } catch (Exception ignored) { } } diff --git a/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/GrpcServerUtils.java b/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/GrpcServerUtils.java index 7e05eb8d5..efdd4b87e 100644 --- a/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/GrpcServerUtils.java +++ b/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/GrpcServerUtils.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.*; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -19,7 +20,6 @@ import java.net.URISyntaxException; import java.util.Arrays; import java.util.HashSet; -import java.util.Map; import java.util.Set; public class GrpcServerUtils { @@ -67,7 +67,9 @@ public static void preprocessSecurityHook(ServerStream_Instrumentat processGRPCRequestMetadata(meta, securityRequest); - securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.GRPC); if (call.getAttributes().get(Grpc.TRANSPORT_ATTR_SSL_SESSION) != null) { securityRequest.setProtocol("https"); @@ -161,17 +163,6 @@ private static boolean isLockAcquired(String nrSecCustomAttrName) { return false; } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static void processGRPCRequestMetadata(Metadata metadata, HttpRequest securityRequest) { Set headerNames = metadata.keys(); for (String headerKey : headerNames) { diff --git a/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/client/GrpcClient.java b/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/client/GrpcClient.java index 774550bf5..ce19b06c6 100644 --- a/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/client/GrpcClient.java +++ b/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/client/GrpcClient.java @@ -7,6 +7,7 @@ import com.google.protobuf.Message; import com.google.protobuf.util.JsonFormat; import com.newrelic.agent.security.instrumentation.grpc140.GrpcServerUtils; +import com.newrelic.agent.security.instrumentation.grpc140.processor.GrpcRequestProcessor; import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GrpcHelper; import com.newrelic.api.agent.security.schema.ControlCommandDto; @@ -55,7 +56,9 @@ protected ManagedChannel initialValue() { } }; - public Object fireRequest(ControlCommandDto controlCommandDto, int repeatCount) { + public Object fireRequest(GrpcRequestProcessor grpcRequestProcessor) { + ControlCommandDto controlCommandDto = grpcRequestProcessor.getControlCommandDto(); + int repeatCount = grpcRequestProcessor.getRepeatCount(); try { FuzzRequestBean requestBean = controlCommandDto.getRequestBean(); List payloads = controlCommandDto.getRequestPayloads(); @@ -82,13 +85,20 @@ public Object fireRequest(ControlCommandDto controlCommandDto, int repeatCount) isSuccess = customBiDiStream(channel, requestBean, payloads); break; } + grpcRequestProcessor.setSuccessful(true); + return isSuccess; } catch (InterruptedException e) { + grpcRequestProcessor.setExceptionRaised(true); + grpcRequestProcessor.setError(e); + if (repeatCount >= 0) { - return fireRequest(controlCommandDto, --repeatCount); + return fireRequest(grpcRequestProcessor); } return false; } catch (Throwable e) { + grpcRequestProcessor.setExceptionRaised(true); + grpcRequestProcessor.setError(e); return e; } } diff --git a/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/processor/GrpcRequestProcessor.java b/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/processor/GrpcRequestProcessor.java index b42863147..736809573 100644 --- a/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/processor/GrpcRequestProcessor.java +++ b/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/processor/GrpcRequestProcessor.java @@ -15,6 +15,14 @@ public class GrpcRequestProcessor implements Callable { private int repeatCount; private static final int MAX_REPETITION = 3; + private boolean isSuccessful = false; + + private int responseCode; + + private boolean exceptionRaised = false; + + private Throwable error; + public GrpcRequestProcessor(ControlCommandDto controlCommandDto, int repeatCount) { this.controlCommandDto = controlCommandDto; this.repeatCount = repeatCount; @@ -22,33 +30,55 @@ public GrpcRequestProcessor(ControlCommandDto controlCommandDto, int repeatCount @Override public Object call() throws Exception { - return GrpcClient.getInstance().fireRequest(controlCommandDto, repeatCount); + return GrpcClient.getInstance().fireRequest(this); } public static void executeGrpcRequest(ControlCommandDto controlCommandDto) { - Future future = GrpcRequestThreadPool.getInstance().executor + GrpcRequestThreadPool.getInstance().executor .submit(new GrpcRequestProcessor(controlCommandDto, MAX_REPETITION)); - try { - Object futureResult = future.get(); - if (futureResult instanceof Throwable) { - NewRelicSecurity.getAgent().log(LogLevel.FINER, String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getRequestBean(), ((Throwable) futureResult).getMessage()), (Throwable) futureResult, GrpcClient.class.getName()); - NewRelicSecurity.getAgent().reportIncident(LogLevel.WARNING, - String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getId(), ((Throwable) futureResult).getMessage()), - (Throwable) futureResult, GrpcClient.class.getName()); - GrpcClientRequestReplayHelper.getInstance().addFuzzFailEventToQueue(controlCommandDto.getRequestBean(), (Throwable) futureResult); - } else { - GrpcClientRequestReplayHelper.getInstance().getPendingIds().remove(controlCommandDto.getId()); - } - } catch (Throwable e) { - NewRelicSecurity.getAgent().log(LogLevel.SEVERE, String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getRequestBean(), e.getMessage()), e, GrpcRequestProcessor.class.getName()); - NewRelicSecurity.getAgent().reportIncident(LogLevel.SEVERE, - String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getId(), e.getMessage()), - e, GrpcRequestProcessor.class.getName()); - GrpcClientRequestReplayHelper.getInstance().addFuzzFailEventToQueue(controlCommandDto.getRequestBean(), e); - } } public ControlCommandDto getPartialControlCommand() { return controlCommandDto; } + + public boolean isSuccessful() { + return isSuccessful; + } + + public void setSuccessful(boolean successful) { + isSuccessful = successful; + } + + public int getResponseCode() { + return responseCode; + } + + public void setResponseCode(int responseCode) { + this.responseCode = responseCode; + } + + public boolean isExceptionRaised() { + return exceptionRaised; + } + + public void setExceptionRaised(boolean exceptionRaised) { + this.exceptionRaised = exceptionRaised; + } + + public Throwable getError() { + return error; + } + + public void setError(Throwable error) { + this.error = error; + } + + public ControlCommandDto getControlCommandDto() { + return controlCommandDto; + } + + public int getRepeatCount() { + return repeatCount; + } } \ No newline at end of file diff --git a/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/processor/GrpcRequestThreadPool.java b/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/processor/GrpcRequestThreadPool.java index a2e8fceef..6ab7d2bf9 100644 --- a/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/processor/GrpcRequestThreadPool.java +++ b/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/processor/GrpcRequestThreadPool.java @@ -5,10 +5,9 @@ import com.newrelic.api.agent.security.schema.StringUtils; import com.newrelic.api.agent.security.utils.logging.LogLevel; -import java.util.HashSet; +import java.io.InterruptedIOException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RunnableFuture; import java.util.concurrent.ThreadFactory; @@ -50,21 +49,27 @@ protected void afterExecute(Runnable r, Throwable t) { GrpcClientRequestReplayHelper.getInstance().setInProcessRequestQueue(getQueue()); controlCommandId = null; if (r instanceof CustomFutureTask && ((CustomFutureTask) r).getTask() instanceof GrpcRequestProcessor) { - Object result = (Object) ((CustomFutureTask) r).get(); + GrpcClientRequestReplayHelper.getInstance().incrementReplayRequestExecuted(); GrpcRequestProcessor task = (GrpcRequestProcessor) ((CustomFutureTask) r).getTask(); controlCommandId = task.getPartialControlCommand().getId(); - if (t != null || result != null) { - if (StringUtils.isNotBlank(controlCommandId)) { - GrpcClientRequestReplayHelper.getInstance().getRejectedIds().add(controlCommandId); - } + if (task.isSuccessful()) { + GrpcClientRequestReplayHelper.getInstance().incrementReplayRequestSucceeded(); + GrpcClientRequestReplayHelper.getInstance().getCompletedReplay().add(controlCommandId); + } else if (task.isExceptionRaised() && task.getError() instanceof InterruptedIOException) { + GrpcClientRequestReplayHelper.getInstance().getClearFromPending().add(controlCommandId); + } else if(task.isExceptionRaised()) { + GrpcClientRequestReplayHelper.getInstance().getErrorInReplay().add(controlCommandId); } else { - GrpcClientRequestReplayHelper.getInstance().getProcessedIds().putIfAbsent(controlCommandId, new HashSet<>()); + GrpcClientRequestReplayHelper.getInstance().getClearFromPending().add(controlCommandId); + } + if (StringUtils.isBlank(controlCommandId)) { + GrpcClientRequestReplayHelper.getInstance().getRejectedIds().add(controlCommandId); + } + if (!task.isSuccessful()){ + GrpcClientRequestReplayHelper.getInstance().incrementReplayRequestFailed(); } } - if (StringUtils.isNotBlank(controlCommandId)) { - GrpcClientRequestReplayHelper.getInstance().getPendingIds().remove(controlCommandId); - } - } catch (InterruptedException | ExecutionException ignored) { + } catch (Exception ignored) { } } diff --git a/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/GrpcServerUtils.java b/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/GrpcServerUtils.java index 92fe00a3d..d9709391e 100644 --- a/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/GrpcServerUtils.java +++ b/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/GrpcServerUtils.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.*; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -18,7 +19,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.HashSet; -import java.util.Map; import java.util.Set; public class GrpcServerUtils { @@ -66,7 +66,10 @@ public static void preprocessSecurityHook(ServerStream_Instrumentat processGRPCRequestMetadata(meta, securityRequest); - securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)) + , RequestCategory.GRPC); if (call.getAttributes().get(Grpc.TRANSPORT_ATTR_SSL_SESSION) != null) { securityRequest.setProtocol("https"); @@ -155,17 +158,6 @@ private static boolean isLockAcquired(String nrSecCustomAttrName) { return false; } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static void processGRPCRequestMetadata(Metadata metadata, HttpRequest securityRequest) { Set headerNames = metadata.keys(); for (String headerKey : headerNames) { diff --git a/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/client/GrpcClient.java b/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/client/GrpcClient.java index cc544b482..2cdccc1db 100644 --- a/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/client/GrpcClient.java +++ b/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/client/GrpcClient.java @@ -7,6 +7,7 @@ import com.google.protobuf.Message; import com.google.protobuf.util.JsonFormat; import com.newrelic.agent.security.instrumentation.grpc1400.GrpcServerUtils; +import com.newrelic.agent.security.instrumentation.grpc1400.processor.GrpcRequestProcessor; import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GrpcHelper; import com.newrelic.api.agent.security.schema.ControlCommandDto; @@ -56,8 +57,10 @@ protected ManagedChannel initialValue() { } }; - public Object fireRequest(ControlCommandDto controlCommandDto, int repeatCount) { + public void fireRequest(GrpcRequestProcessor grpcRequestProcessor) { FuzzRequestBean requestBean = null; + ControlCommandDto controlCommandDto = grpcRequestProcessor.getControlCommandDto(); + int repeatCount = grpcRequestProcessor.getRepeatCount(); try { requestBean = controlCommandDto.getRequestBean(); List payloads = controlCommandDto.getRequestPayloads(); @@ -69,29 +72,31 @@ public Object fireRequest(ControlCommandDto controlCommandDto, int repeatCount) NewRelicSecurity.getAgent().log(LogLevel.FINER, String.format(FIRING_REQUEST_URL_S, requestBean.getUrl()), GrpcClient.class.getName()); NewRelicSecurity.getAgent().log(LogLevel.FINER, String.format(FIRING_REQUEST_HEADERS_S, requestBean.getHeaders()), GrpcClient.class.getName()); - Object isSuccess = false; switch (requestBean.getReflectedMetaData().get(GrpcHelper.REQUEST_TYPE)) { case unary: - isSuccess = customUnaryCall(channel, requestBean, payloads); + customUnaryCall(channel, requestBean, payloads); break; case client_streaming: - isSuccess = customClientStream(channel, requestBean, payloads); + customClientStream(channel, requestBean, payloads); break; case server_streaming: - isSuccess = customServerStream(channel, requestBean, payloads); + customServerStream(channel, requestBean, payloads); break; case bidi_streaming: - isSuccess = customBiDiStream(channel, requestBean, payloads); + customBiDiStream(channel, requestBean, payloads); break; } - return isSuccess; + grpcRequestProcessor.setSuccessful(true); } catch (InterruptedException e) { + grpcRequestProcessor.setExceptionRaised(true); + grpcRequestProcessor.setError(e); + if (repeatCount >= 0) { - return fireRequest(controlCommandDto, --repeatCount); + fireRequest(grpcRequestProcessor); } - return false; } catch (Throwable e) { - return e; + grpcRequestProcessor.setExceptionRaised(true); + grpcRequestProcessor.setError(e); } } @@ -105,7 +110,7 @@ public static GrpcClient getInstance() { } } - private Object customUnaryCall(ManagedChannel channel, FuzzRequestBean requestBean, List payloads) { + private void customUnaryCall(ManagedChannel channel, FuzzRequestBean requestBean, List payloads) { GrpcStubs.CustomStub stub = GrpcStubs.newStub(channel); String[] methodSplitData = requestBean.getMethod().split("/"); String serviceName = methodSplitData[0]; @@ -118,20 +123,14 @@ private Object customUnaryCall(ManagedChannel channel, FuzzRequestBean requestBe } for (String requestData : payloads) { - try { - Any pack = getMessageOfTypeAny(requestData, requestClass); - Any response = stub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(headers)) - .unaryCall(pack, serviceName, methodName); - NewRelicSecurity.getAgent().log(LogLevel.FINER, String.format(REQUEST_SUCCESS_S_RESPONSE_S_S, requestBean, response, response.toString()), GrpcClient.class.getName()); - } catch (Throwable e) { - return e; -// GrpcClientRequestReplayHelper.getInstance().addFuzzFailEventToQueue(requestBean, e); - } + Any pack = getMessageOfTypeAny(requestData, requestClass); + Any response = stub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(headers)) + .unaryCall(pack, serviceName, methodName); + NewRelicSecurity.getAgent().log(LogLevel.FINER, String.format(REQUEST_SUCCESS_S_RESPONSE_S_S, requestBean, response, response.toString()), GrpcClient.class.getName()); } - return null; } - private static Object customClientStream(ManagedChannel channel, FuzzRequestBean requestBean, List payloads) throws InterruptedException { + private static void customClientStream(ManagedChannel channel, FuzzRequestBean requestBean, List payloads) throws InterruptedException { StreamObserver responseObserver = new StreamObserver() { @Override @@ -163,19 +162,13 @@ public void onCompleted() { StreamObserver requestObserver = stub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(headers)).clientStream(responseObserver, serviceName, methodName); for (String requestData : payloads) { - try { - Any pack = getMessageOfTypeAny(requestData, requestClass); - requestObserver.onNext(pack); - } catch (Throwable e) { - return e; -// GrpcClientRequestReplayHelper.getInstance().addFuzzFailEventToQueue(requestBean, e); - } + Any pack = getMessageOfTypeAny(requestData, requestClass); + requestObserver.onNext(pack); } requestObserver.onCompleted(); - return null; } - private static Object customServerStream(ManagedChannel channel, FuzzRequestBean requestBean, List payloads) { + private static void customServerStream(ManagedChannel channel, FuzzRequestBean requestBean, List payloads) { GrpcStubs.CustomStub stub = GrpcStubs.newBlockingStub(channel); String[] methodSplitData = requestBean.getMethod().split("/"); String serviceName = methodSplitData[0]; @@ -188,23 +181,17 @@ private static Object customServerStream(ManagedChannel channel, FuzzRequestBean } for (String requestData : payloads) { - try { - Any pack = getMessageOfTypeAny(requestData, requestClass); - Iterator responses = stub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(headers)) - .serverStream(pack, serviceName, methodName); - while (responses.hasNext()) { - Any response = responses.next(); - NewRelicSecurity.getAgent().log(LogLevel.FINER, String.format(REQUEST_SUCCESS_S_RESPONSE_S_S, requestBean, response, response.toString()), GrpcClient.class.getName()); - } - } catch (Throwable e) { - return e; -// GrpcClientRequestReplayHelper.getInstance().addFuzzFailEventToQueue(requestBean, e); + Any pack = getMessageOfTypeAny(requestData, requestClass); + Iterator responses = stub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(headers)) + .serverStream(pack, serviceName, methodName); + while (responses.hasNext()) { + Any response = responses.next(); + NewRelicSecurity.getAgent().log(LogLevel.FINER, String.format(REQUEST_SUCCESS_S_RESPONSE_S_S, requestBean, response, response.toString()), GrpcClient.class.getName()); } } - return null; } - public static Object customBiDiStream(ManagedChannel channel, FuzzRequestBean requestBean, List payloads) throws InterruptedException { + public static void customBiDiStream(ManagedChannel channel, FuzzRequestBean requestBean, List payloads) { GrpcStubs.CustomStub stub = GrpcStubs.newStub(channel); StringBuilder body = requestBean.getBody(); String[] methodSplitData = requestBean.getMethod().split("/"); @@ -237,16 +224,10 @@ public void onCompleted() { .biDiStream(responseObserver, serviceName, methodName); for (String requestData : payloads) { - try{ - Any pack = getMessageOfTypeAny(requestData, requestClass); - requestObserver.onNext(pack); - } catch (Throwable e) { - return e; -// GrpcClientRequestReplayHelper.getInstance().addFuzzFailEventToQueue(requestBean, e); - } + Any pack = getMessageOfTypeAny(requestData, requestClass); + requestObserver.onNext(pack); } requestObserver.onCompleted(); - return null; } diff --git a/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/processor/GrpcRequestProcessor.java b/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/processor/GrpcRequestProcessor.java index 8d232c7e6..57b04c1c5 100644 --- a/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/processor/GrpcRequestProcessor.java +++ b/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/processor/GrpcRequestProcessor.java @@ -1,13 +1,9 @@ package com.newrelic.agent.security.instrumentation.grpc1400.processor; import com.newrelic.agent.security.instrumentation.grpc1400.client.GrpcClient; -import com.newrelic.api.agent.security.NewRelicSecurity; -import com.newrelic.api.agent.security.instrumentation.helpers.GrpcClientRequestReplayHelper; import com.newrelic.api.agent.security.schema.ControlCommandDto; -import com.newrelic.api.agent.security.utils.logging.LogLevel; import java.util.concurrent.Callable; -import java.util.concurrent.Future; public class GrpcRequestProcessor implements Callable { public static final String CALL_FAILED_REQUEST_S_REASON = "Call failed : request %s reason : %s "; @@ -15,6 +11,14 @@ public class GrpcRequestProcessor implements Callable { private int repeatCount; private static final int MAX_REPETITION = 3; + private boolean isSuccessful = false; + + private int responseCode; + + private boolean exceptionRaised = false; + + private Throwable error; + public GrpcRequestProcessor(ControlCommandDto controlCommandDto, int repeatCount) { this.controlCommandDto = controlCommandDto; this.repeatCount = repeatCount; @@ -22,33 +26,56 @@ public GrpcRequestProcessor(ControlCommandDto controlCommandDto, int repeatCount @Override public Object call() throws Exception { - return GrpcClient.getInstance().fireRequest(controlCommandDto, repeatCount); + GrpcClient.getInstance().fireRequest(this); + return this; } public static void executeGrpcRequest(ControlCommandDto controlCommandDto) { - Future future = GrpcRequestThreadPool.getInstance().executor + GrpcRequestThreadPool.getInstance().executor .submit(new GrpcRequestProcessor(controlCommandDto, MAX_REPETITION)); - try { - Object futureResult = future.get(); - if (futureResult instanceof Throwable) { - NewRelicSecurity.getAgent().log(LogLevel.FINER, String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getRequestBean(), ((Throwable) futureResult).getMessage()), (Throwable) futureResult, GrpcClient.class.getName()); - NewRelicSecurity.getAgent().reportIncident(LogLevel.WARNING, - String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getId(), ((Throwable) futureResult).getMessage()), - (Throwable) futureResult, GrpcClient.class.getName()); - GrpcClientRequestReplayHelper.getInstance().addFuzzFailEventToQueue(controlCommandDto.getRequestBean(), (Throwable) futureResult); - } else { - GrpcClientRequestReplayHelper.getInstance().getPendingIds().remove(controlCommandDto.getId()); - } - } catch (Throwable e) { - NewRelicSecurity.getAgent().log(LogLevel.SEVERE, String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getRequestBean(), e.getMessage()), e, GrpcRequestProcessor.class.getName()); - NewRelicSecurity.getAgent().reportIncident(LogLevel.SEVERE, - String.format(CALL_FAILED_REQUEST_S_REASON, controlCommandDto.getId(), e.getMessage()), - e, GrpcRequestProcessor.class.getName()); - GrpcClientRequestReplayHelper.getInstance().addFuzzFailEventToQueue(controlCommandDto.getRequestBean(), e); - } } public ControlCommandDto getPartialControlCommand() { return controlCommandDto; } + + public void setSuccessful(boolean successful) { + isSuccessful = successful; + } + + public void setResponseCode(int responseCode) { + this.responseCode = responseCode; + } + + public void setExceptionRaised(boolean exceptionRaised) { + this.exceptionRaised = exceptionRaised; + } + + public void setError(Throwable error) { + this.error = error; + } + + public ControlCommandDto getControlCommandDto() { + return controlCommandDto; + } + + public int getRepeatCount() { + return repeatCount; + } + + public boolean isSuccessful() { + return isSuccessful; + } + + public int getResponseCode() { + return responseCode; + } + + public boolean isExceptionRaised() { + return exceptionRaised; + } + + public Throwable getError() { + return error; + } } \ No newline at end of file diff --git a/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/processor/GrpcRequestThreadPool.java b/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/processor/GrpcRequestThreadPool.java index 1e23a656b..1a8a2cf0a 100644 --- a/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/processor/GrpcRequestThreadPool.java +++ b/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/processor/GrpcRequestThreadPool.java @@ -5,10 +5,9 @@ import com.newrelic.api.agent.security.schema.StringUtils; import com.newrelic.api.agent.security.utils.logging.LogLevel; -import java.util.HashSet; +import java.io.InterruptedIOException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RunnableFuture; import java.util.concurrent.ThreadFactory; @@ -47,21 +46,27 @@ protected void afterExecute(Runnable r, Throwable t) { GrpcClientRequestReplayHelper.getInstance().setInProcessRequestQueue(getQueue()); String controlCommandId = null; if (r instanceof CustomFutureTask && ((CustomFutureTask) r).getTask() instanceof GrpcRequestProcessor) { - Object result = (Object) ((CustomFutureTask) r).get(); + GrpcClientRequestReplayHelper.getInstance().incrementReplayRequestExecuted(); GrpcRequestProcessor task = (GrpcRequestProcessor) ((CustomFutureTask) r).getTask(); controlCommandId = task.getPartialControlCommand().getId(); - if (t != null || result != null) { - if (StringUtils.isNotBlank(controlCommandId)) { - GrpcClientRequestReplayHelper.getInstance().getRejectedIds().add(controlCommandId); - } + if (task.isSuccessful()) { + GrpcClientRequestReplayHelper.getInstance().incrementReplayRequestSucceeded(); + GrpcClientRequestReplayHelper.getInstance().getCompletedReplay().add(controlCommandId); + } else if (task.isExceptionRaised() && task.getError() instanceof InterruptedIOException) { + GrpcClientRequestReplayHelper.getInstance().getClearFromPending().add(controlCommandId); + } else if(task.isExceptionRaised()) { + GrpcClientRequestReplayHelper.getInstance().getErrorInReplay().add(controlCommandId); } else { - GrpcClientRequestReplayHelper.getInstance().getProcessedIds().putIfAbsent(controlCommandId, new HashSet<>()); + GrpcClientRequestReplayHelper.getInstance().getClearFromPending().add(controlCommandId); + } + if (StringUtils.isBlank(controlCommandId)) { + GrpcClientRequestReplayHelper.getInstance().getRejectedIds().add(controlCommandId); + } + if (!task.isSuccessful()){ + GrpcClientRequestReplayHelper.getInstance().incrementReplayRequestFailed(); } } - if (StringUtils.isNotBlank(controlCommandId)) { - GrpcClientRequestReplayHelper.getInstance().getPendingIds().remove(controlCommandId); - } - } catch (InterruptedException | ExecutionException e) { + } catch (Exception e) { } } diff --git a/instrumentation-security/jersey-2.16/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java b/instrumentation-security/jersey-2.16/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java index a84a351bc..4f2cd95c3 100644 --- a/instrumentation-security/jersey-2.16/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java +++ b/instrumentation-security/jersey-2.16/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java @@ -5,10 +5,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ICsecApiConstants; import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; -import com.newrelic.api.agent.security.schema.AgentMetaData; -import com.newrelic.api.agent.security.schema.HttpRequest; -import com.newrelic.api.agent.security.schema.SecurityMetaData; -import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.*; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; @@ -77,7 +74,10 @@ public static void preprocessSecurityHook(ContainerRequest requestContext) { } HttpRequestHelper.processHttpRequestHeader(requestContext, securityRequest); - securityMetaData.setTracingHeaderValue(HttpRequestHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); + securityRequest.setUrl(requestContext.getRequestUri().toString()); StackTraceElement[] trace = Thread.currentThread().getStackTrace(); @@ -184,17 +184,6 @@ private static String getHeaderValue(List values) { return finalValue.toString(); } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static boolean isRequestLockAcquired() { try { return NewRelicSecurity.isHookProcessingActive() && diff --git a/instrumentation-security/jersey-2/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java b/instrumentation-security/jersey-2/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java index a52a7a084..b4e6827e6 100644 --- a/instrumentation-security/jersey-2/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java +++ b/instrumentation-security/jersey-2/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java @@ -5,10 +5,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ICsecApiConstants; import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; -import com.newrelic.api.agent.security.schema.AgentMetaData; -import com.newrelic.api.agent.security.schema.HttpRequest; -import com.newrelic.api.agent.security.schema.SecurityMetaData; -import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.*; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; @@ -79,7 +76,10 @@ public static void preprocessSecurityHook(ContainerRequest requestContext) { } HttpRequestHelper.processHttpRequestHeader(requestContext, securityRequest); - securityMetaData.setTracingHeaderValue(HttpRequestHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); + securityRequest.setUrl(requestContext.getRequestUri().toString()); StackTraceElement[] trace = Thread.currentThread().getStackTrace(); @@ -186,17 +186,6 @@ private static String getHeaderValue(List values) { return finalValue.toString(); } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static boolean isRequestLockAcquired() { try { return NewRelicSecurity.isHookProcessingActive() && diff --git a/instrumentation-security/jersey-3/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java b/instrumentation-security/jersey-3/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java index c43db4efe..0e01f5b8a 100644 --- a/instrumentation-security/jersey-3/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java +++ b/instrumentation-security/jersey-3/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/HttpRequestHelper.java @@ -5,10 +5,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ICsecApiConstants; import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; -import com.newrelic.api.agent.security.schema.AgentMetaData; -import com.newrelic.api.agent.security.schema.HttpRequest; -import com.newrelic.api.agent.security.schema.SecurityMetaData; -import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.*; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; @@ -77,7 +74,10 @@ public static void preprocessSecurityHook(ContainerRequest requestContext) { } HttpRequestHelper.processHttpRequestHeader(requestContext, securityRequest); - securityMetaData.setTracingHeaderValue(HttpRequestHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); + securityRequest.setUrl(requestContext.getRequestUri().toString()); StackTraceElement[] trace = Thread.currentThread().getStackTrace(); @@ -184,17 +184,6 @@ private static String getHeaderValue(List values) { return finalValue.toString(); } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static boolean isRequestLockAcquired() { try { return NewRelicSecurity.isHookProcessingActive() && diff --git a/instrumentation-security/jetty-11/src/main/java/com/newrelic/agent/security/instrumentation/jetty11/HttpServletHelper.java b/instrumentation-security/jetty-11/src/main/java/com/newrelic/agent/security/instrumentation/jetty11/HttpServletHelper.java index 00c729bec..9364b77f2 100644 --- a/instrumentation-security/jetty-11/src/main/java/com/newrelic/agent/security/instrumentation/jetty11/HttpServletHelper.java +++ b/instrumentation-security/jetty-11/src/main/java/com/newrelic/agent/security/instrumentation/jetty11/HttpServletHelper.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.ApplicationURLMapping; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -84,17 +85,6 @@ public static void processHttpRequestHeader(HttpServletRequest request, HttpRequ } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static boolean isServletLockAcquired() { try { return NewRelicSecurity.isHookProcessingActive() && @@ -154,7 +144,9 @@ public static void preprocessSecurityHook(HttpServletRequest httpServletRequest) HttpServletHelper.processHttpRequestHeader(httpServletRequest, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(httpServletRequest.getScheme()); securityRequest.setUrl(httpServletRequest.getRequestURI()); diff --git a/instrumentation-security/jetty-12/src/main/java/com/newrelic/agent/security/instrumentation/jetty12/server/HttpServletHelper.java b/instrumentation-security/jetty-12/src/main/java/com/newrelic/agent/security/instrumentation/jetty12/server/HttpServletHelper.java index 930b540a3..05c68de38 100644 --- a/instrumentation-security/jetty-12/src/main/java/com/newrelic/agent/security/instrumentation/jetty12/server/HttpServletHelper.java +++ b/instrumentation-security/jetty-12/src/main/java/com/newrelic/agent/security/instrumentation/jetty12/server/HttpServletHelper.java @@ -7,6 +7,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -19,7 +20,6 @@ import java.util.Arrays; import java.util.Iterator; -import java.util.Map; import java.util.Set; public class HttpServletHelper { @@ -85,17 +85,6 @@ public static void processHttpRequestHeader(Request request, HttpRequest securit } } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static boolean isServletLockAcquired() { try { return NewRelicSecurity.isHookProcessingActive() && @@ -155,7 +144,9 @@ public static void preprocessSecurityHook(Request request) { HttpServletHelper.processHttpRequestHeader(request, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(request.getHttpURI().getScheme()); diff --git a/instrumentation-security/jetty-9/src/main/java/com/newrelic/agent/security/instrumentation/jetty9/HttpServletHelper.java b/instrumentation-security/jetty-9/src/main/java/com/newrelic/agent/security/instrumentation/jetty9/HttpServletHelper.java index dd3d81697..bea66dbcc 100644 --- a/instrumentation-security/jetty-9/src/main/java/com/newrelic/agent/security/instrumentation/jetty9/HttpServletHelper.java +++ b/instrumentation-security/jetty-9/src/main/java/com/newrelic/agent/security/instrumentation/jetty9/HttpServletHelper.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.ApplicationURLMapping; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -85,17 +86,6 @@ public static void processHttpRequestHeader(HttpServletRequest request, HttpRequ } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static boolean isServletLockAcquired() { try { return NewRelicSecurity.isHookProcessingActive() && @@ -155,7 +145,9 @@ public static void preprocessSecurityHook(HttpServletRequest httpServletRequest) HttpServletHelper.processHttpRequestHeader(httpServletRequest, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(httpServletRequest.getScheme()); securityRequest.setUrl(httpServletRequest.getRequestURI()); diff --git a/instrumentation-security/mule-3.6/src/main/java/com/newrelic/agent/security/instrumentation/mule36/MuleHelper.java b/instrumentation-security/mule-3.6/src/main/java/com/newrelic/agent/security/instrumentation/mule36/MuleHelper.java index 3a79f35d7..6d3bee671 100644 --- a/instrumentation-security/mule-3.6/src/main/java/com/newrelic/agent/security/instrumentation/mule36/MuleHelper.java +++ b/instrumentation-security/mule-3.6/src/main/java/com/newrelic/agent/security/instrumentation/mule36/MuleHelper.java @@ -83,16 +83,6 @@ public static void processHttpRequestHeader(HttpRequest httpRequest, } } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } public static String getContentType(HttpRequest httpRequest) { return httpRequest.getHeaderValue(HttpHeaders.Names.CONTENT_TYPE); } diff --git a/instrumentation-security/mule-3.6/src/main/java/org/mule/module/http/internal/listener/HttpRequestToMuleEvent_Instrumentation.java b/instrumentation-security/mule-3.6/src/main/java/org/mule/module/http/internal/listener/HttpRequestToMuleEvent_Instrumentation.java index 637a252b3..b04f5ce8e 100644 --- a/instrumentation-security/mule-3.6/src/main/java/org/mule/module/http/internal/listener/HttpRequestToMuleEvent_Instrumentation.java +++ b/instrumentation-security/mule-3.6/src/main/java/org/mule/module/http/internal/listener/HttpRequestToMuleEvent_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -70,7 +71,9 @@ private static void preprocessSecurityHook(HttpRequestContext requestContext) { } MuleHelper.processHttpRequestHeader(httpRequest, securityRequest); - securityMetaData.setTracingHeaderValue(MuleHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(requestContext.getScheme()); securityRequest.setUrl(httpRequest.getUri()); diff --git a/instrumentation-security/mule-3.6/src/main/java/org/mule/module/http/internal/listener/async/RequestHandler_Instrumentation.java b/instrumentation-security/mule-3.6/src/main/java/org/mule/module/http/internal/listener/async/RequestHandler_Instrumentation.java index a7f6bc1ef..820804a28 100644 --- a/instrumentation-security/mule-3.6/src/main/java/org/mule/module/http/internal/listener/async/RequestHandler_Instrumentation.java +++ b/instrumentation-security/mule-3.6/src/main/java/org/mule/module/http/internal/listener/async/RequestHandler_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -64,7 +65,9 @@ private void preprocessSecurityHook(HttpRequestContext requestContext) { } MuleHelper.processHttpRequestHeader(httpRequest, securityRequest); - securityMetaData.setTracingHeaderValue(MuleHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(requestContext.getScheme()); securityRequest.setUrl(httpRequest.getUri()); diff --git a/instrumentation-security/mule-3.7/src/main/java/com/newrelic/agent/security/instrumentation/mule37/MuleHelper.java b/instrumentation-security/mule-3.7/src/main/java/com/newrelic/agent/security/instrumentation/mule37/MuleHelper.java index afc9c97ba..7ef0b4561 100644 --- a/instrumentation-security/mule-3.7/src/main/java/com/newrelic/agent/security/instrumentation/mule37/MuleHelper.java +++ b/instrumentation-security/mule-3.7/src/main/java/com/newrelic/agent/security/instrumentation/mule37/MuleHelper.java @@ -77,16 +77,6 @@ public static void processHttpRequestHeader(HttpRequest httpRequest, com.newreli } } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } public static String getContentType(HttpRequest httpRequest) { return httpRequest.getHeaderValue(HttpHeaders.Names.CONTENT_TYPE); } diff --git a/instrumentation-security/mule-3.7/src/main/java/org/mule/module/http/internal/listener/HttpRequestToMuleEvent_Instrumentation.java b/instrumentation-security/mule-3.7/src/main/java/org/mule/module/http/internal/listener/HttpRequestToMuleEvent_Instrumentation.java index e02e96ca8..fcdd980b4 100644 --- a/instrumentation-security/mule-3.7/src/main/java/org/mule/module/http/internal/listener/HttpRequestToMuleEvent_Instrumentation.java +++ b/instrumentation-security/mule-3.7/src/main/java/org/mule/module/http/internal/listener/HttpRequestToMuleEvent_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -70,7 +71,9 @@ private static void preprocessSecurityHook(HttpRequestContext requestContext) { } MuleHelper.processHttpRequestHeader(httpRequest, securityRequest); - securityMetaData.setTracingHeaderValue(MuleHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(requestContext.getScheme()); securityRequest.setUrl(httpRequest.getUri()); diff --git a/instrumentation-security/mule-3.7/src/main/java/org/mule/module/http/internal/listener/async/RequestHandler_Instrumentation.java b/instrumentation-security/mule-3.7/src/main/java/org/mule/module/http/internal/listener/async/RequestHandler_Instrumentation.java index 4fe834e0e..d4e48fb62 100644 --- a/instrumentation-security/mule-3.7/src/main/java/org/mule/module/http/internal/listener/async/RequestHandler_Instrumentation.java +++ b/instrumentation-security/mule-3.7/src/main/java/org/mule/module/http/internal/listener/async/RequestHandler_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -64,7 +65,9 @@ private void preprocessSecurityHook(HttpRequestContext requestContext) { } MuleHelper.processHttpRequestHeader(httpRequest, securityRequest); - securityMetaData.setTracingHeaderValue(MuleHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(requestContext.getScheme()); securityRequest.setUrl(httpRequest.getUri()); diff --git a/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/utils/NettyUtils.java b/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/utils/NettyUtils.java index 3a34eac2e..2eafc66ec 100644 --- a/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/utils/NettyUtils.java +++ b/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/utils/NettyUtils.java @@ -56,7 +56,7 @@ public static void processSecurityRequest(ChannelHandlerContext ctx, Object msg, setClientAddressDetails(securityMetaData, ctx.channel().remoteAddress().toString()); setServerPortDetails(securityRequest, ctx.channel().localAddress().toString()); processHttpRequestHeader((HttpRequest)msg, securityRequest); - securityMetaData.setTracingHeaderValue(getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); securityRequest.setProtocol(((HttpRequest) msg).getProtocolVersion().protocolName().toLowerCase()); securityRequest.setContentType(securityRequest.getHeaders().get("content-type")); @@ -159,18 +159,6 @@ public static void processHttpRequestHeader(HttpRequest request, com.newrelic.ap } } - - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static void processSecurityResponse(ChannelHandlerContext ctx, Object msg) { try { if (NewRelicSecurity.isHookProcessingActive() && msg instanceof FullHttpResponse) { diff --git a/instrumentation-security/servlet-2.4/src/main/java/com/newrelic/agent/security/instrumentation/servlet24/HttpServletHelper.java b/instrumentation-security/servlet-2.4/src/main/java/com/newrelic/agent/security/instrumentation/servlet24/HttpServletHelper.java index aa6ceacd9..5d167c82c 100644 --- a/instrumentation-security/servlet-2.4/src/main/java/com/newrelic/agent/security/instrumentation/servlet24/HttpServletHelper.java +++ b/instrumentation-security/servlet-2.4/src/main/java/com/newrelic/agent/security/instrumentation/servlet24/HttpServletHelper.java @@ -13,7 +13,6 @@ import javax.servlet.http.HttpServletRequest; import java.util.Collection; import java.util.Enumeration; -import java.util.Iterator; import java.util.Map; public class HttpServletHelper { @@ -80,17 +79,6 @@ public static void processHttpRequestHeader(HttpServletRequest request, HttpRequ } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static boolean isServletLockAcquired() { try { return NewRelicSecurity.isHookProcessingActive() && diff --git a/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/FilterChain_Instrumentation.java b/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/FilterChain_Instrumentation.java index 2e25a599f..63eb09c89 100644 --- a/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/FilterChain_Instrumentation.java +++ b/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/FilterChain_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -67,7 +68,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp HttpServletHelper.processHttpRequestHeader(httpServletRequest, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(httpServletRequest.getScheme()); securityRequest.setUrl(httpServletRequest.getRequestURI()); diff --git a/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/Filter_Instrumentation.java b/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/Filter_Instrumentation.java index 6acac817c..49857c37b 100644 --- a/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/Filter_Instrumentation.java +++ b/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/Filter_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -69,7 +70,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp HttpServletHelper.processHttpRequestHeader(httpServletRequest, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(httpServletRequest.getScheme()); securityRequest.setUrl(httpServletRequest.getRequestURI()); diff --git a/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/Servlet_Instrumentation.java b/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/Servlet_Instrumentation.java index 98f957d36..cdc3a9eb4 100644 --- a/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/Servlet_Instrumentation.java +++ b/instrumentation-security/servlet-2.4/src/main/java/javax/servlet/Servlet_Instrumentation.java @@ -13,6 +13,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -73,7 +74,9 @@ private void preprocessSecurityHook(ServletRequest_Instrumentation request, Serv HttpServletHelper.processHttpRequestHeader(httpServletRequest, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(httpServletRequest.getScheme()); securityRequest.setUrl(httpServletRequest.getRequestURI()); diff --git a/instrumentation-security/servlet-5.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet5/HttpServletHelper.java b/instrumentation-security/servlet-5.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet5/HttpServletHelper.java index 8c6278daa..9ac214f5a 100644 --- a/instrumentation-security/servlet-5.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet5/HttpServletHelper.java +++ b/instrumentation-security/servlet-5.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet5/HttpServletHelper.java @@ -80,17 +80,6 @@ public static void processHttpRequestHeader(HttpServletRequest request, HttpRequ } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static boolean isServletLockAcquired() { try { return NewRelicSecurity.isHookProcessingActive() && diff --git a/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/FilterChain_Instrumentation.java b/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/FilterChain_Instrumentation.java index 9893b7ccf..6d28636b6 100644 --- a/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/FilterChain_Instrumentation.java +++ b/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/FilterChain_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -67,7 +68,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp HttpServletHelper.processHttpRequestHeader(httpServletRequest, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(httpServletRequest.getScheme()); securityRequest.setUrl(httpServletRequest.getRequestURI()); diff --git a/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/Filter_Instrumentation.java b/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/Filter_Instrumentation.java index cf4ddbeb9..bc6eb8a7e 100644 --- a/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/Filter_Instrumentation.java +++ b/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/Filter_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -68,7 +69,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp HttpServletHelper.processHttpRequestHeader(httpServletRequest, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(httpServletRequest.getScheme()); securityRequest.setUrl(httpServletRequest.getRequestURI()); diff --git a/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/Servlet_Instrumentation.java b/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/Servlet_Instrumentation.java index 01da21d98..5a4bca260 100644 --- a/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/Servlet_Instrumentation.java +++ b/instrumentation-security/servlet-5.0/src/main/java/jakarta/servlet/Servlet_Instrumentation.java @@ -13,6 +13,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -73,7 +74,9 @@ private void preprocessSecurityHook(ServletRequest_Instrumentation request, Serv HttpServletHelper.processHttpRequestHeader(httpServletRequest, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(httpServletRequest.getScheme()); securityRequest.setUrl(httpServletRequest.getRequestURI()); diff --git a/instrumentation-security/servlet-6.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet6/HttpServletHelper.java b/instrumentation-security/servlet-6.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet6/HttpServletHelper.java index 847d8e440..72830055a 100644 --- a/instrumentation-security/servlet-6.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet6/HttpServletHelper.java +++ b/instrumentation-security/servlet-6.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet6/HttpServletHelper.java @@ -80,17 +80,6 @@ public static void processHttpRequestHeader(HttpServletRequest request, HttpRequ } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } - public static boolean isServletLockAcquired() { try { return NewRelicSecurity.isHookProcessingActive() && diff --git a/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/FilterChain_Instrumentation.java b/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/FilterChain_Instrumentation.java index c7f7a3c45..3a4efcbf3 100644 --- a/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/FilterChain_Instrumentation.java +++ b/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/FilterChain_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -67,7 +68,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp HttpServletHelper.processHttpRequestHeader(httpServletRequest, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(httpServletRequest.getScheme()); securityRequest.setUrl(httpServletRequest.getRequestURI()); diff --git a/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/Filter_Instrumentation.java b/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/Filter_Instrumentation.java index d1d36a341..c95019801 100644 --- a/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/Filter_Instrumentation.java +++ b/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/Filter_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -68,7 +69,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp HttpServletHelper.processHttpRequestHeader(httpServletRequest, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(httpServletRequest.getScheme()); securityRequest.setUrl(httpServletRequest.getRequestURI()); diff --git a/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/Servlet_Instrumentation.java b/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/Servlet_Instrumentation.java index cc01075f3..e171a6cb2 100644 --- a/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/Servlet_Instrumentation.java +++ b/instrumentation-security/servlet-6.0/src/main/java/jakarta/servlet/Servlet_Instrumentation.java @@ -13,6 +13,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -73,7 +74,9 @@ private void preprocessSecurityHook(ServletRequest_Instrumentation request, Serv HttpServletHelper.processHttpRequestHeader(httpServletRequest, securityRequest); - securityMetaData.setTracingHeaderValue(HttpServletHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); securityRequest.setProtocol(httpServletRequest.getScheme()); securityRequest.setUrl(httpServletRequest.getRequestURI()); diff --git a/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/Filter_Instrumentation.java b/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/Filter_Instrumentation.java index 54518e111..a1dfeec68 100644 --- a/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/Filter_Instrumentation.java +++ b/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/Filter_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -60,7 +61,10 @@ private void preprocessSecurityHook(HttpExchange exchange) { } HttpServerHelper.processHttpRequestHeaders(exchange.getRequestHeaders(), securityRequest); - securityMetaData.setTracingHeaderValue(HttpServerHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); + securityRequest.setProtocol(HttpServerHelper.getProtocol(exchange)); securityRequest.setUrl(String.valueOf(exchange.getRequestURI())); diff --git a/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/HttpHandler_Instrumentation.java b/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/HttpHandler_Instrumentation.java index 04e5f0727..1f5d174c3 100644 --- a/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/HttpHandler_Instrumentation.java +++ b/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/HttpHandler_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; @@ -60,7 +61,10 @@ private void preprocessSecurityHook(HttpExchange exchange) { } HttpServerHelper.processHttpRequestHeaders(exchange.getRequestHeaders(), securityRequest); - securityMetaData.setTracingHeaderValue(HttpServerHelper.getTraceHeader(securityRequest.getHeaders())); + securityMetaData.setTracingHeaderValue(ServletHelper.getTraceHeader(securityRequest.getHeaders())); + + NewRelicSecurity.getAgent().setEmptyIastDataRequestEntry(ServletHelper.iastDataRequestAddEmptyEntry(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getTracingHeaderValue(), securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class)), RequestCategory.HTTP); + securityRequest.setProtocol(HttpServerHelper.getProtocol(exchange)); securityRequest.setUrl(String.valueOf(exchange.getRequestURI())); diff --git a/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/HttpServerHelper.java b/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/HttpServerHelper.java index 0ee68c2ee..f5a542640 100644 --- a/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/HttpServerHelper.java +++ b/instrumentation-security/sun-net-httpserver/src/main/java/com/sun/net/httpserver/HttpServerHelper.java @@ -79,16 +79,6 @@ public static String getContentType(Headers headers){ } return data; } - public static String getTraceHeader(Map headers) { - String data = EMPTY; - if (headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER); - if (data == null || data.trim().isEmpty()) { - data = headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); - } - } - return data; - } public static void registerInputStreamHashIfNeeded(int inputStreamHash){ try { diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/DispatcherPool.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/DispatcherPool.java index f317969a7..9a08a1bf4 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/DispatcherPool.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/DispatcherPool.java @@ -200,14 +200,20 @@ public void dispatchEvent(AbstractOperation operation, SecurityMetaData security String parentId = securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class); if (StringUtils.isNotBlank(parentId)) { if (securityMetaData.getRequest().getIsGrpc()) { - GrpcClientRequestReplayHelper.getInstance().getProcessedIds().putIfAbsent(parentId, new HashSet<>()); if (StringUtils.equals(securityMetaData.getFuzzRequestIdentifier().getApiRecordId(), operation.getApiID())) { - GrpcClientRequestReplayHelper.getInstance().registerEventForProcessedCC(parentId, operation.getExecutionId()); + String originAppUUID = securityMetaData.getFuzzRequestIdentifier().getOriginApplicationUUID(); + if(StringUtils.isBlank(originAppUUID)){ + originAppUUID = AgentInfo.getInstance().getApplicationUUID(); + } + GrpcClientRequestReplayHelper.getInstance().registerEventForProcessedCC(parentId, operation.getExecutionId(), originAppUUID); } } else { - RestRequestThreadPool.getInstance().getProcessedIds().putIfAbsent(parentId, new HashSet<>()); if (StringUtils.equals(securityMetaData.getFuzzRequestIdentifier().getApiRecordId(), operation.getApiID())) { - RestRequestThreadPool.getInstance().registerEventForProcessedCC(parentId, operation.getExecutionId()); + String originAppUUID = securityMetaData.getFuzzRequestIdentifier().getOriginApplicationUUID(); + if(StringUtils.isBlank(originAppUUID)){ + originAppUUID = AgentInfo.getInstance().getApplicationUUID(); + } + RestRequestThreadPool.getInstance().registerEventForProcessedCC(parentId, operation.getExecutionId(), originAppUUID); } } } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/EventAbortPolicy.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/EventAbortPolicy.java index 7a2595c9f..77dc8b113 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/EventAbortPolicy.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/EventAbortPolicy.java @@ -12,10 +12,10 @@ public class EventAbortPolicy implements RejectedExecutionHandler { public EventAbortPolicy() { - AgentInfo.getInstance().getJaHealthCheck().getIastReplayRequest().incrementReplayRequestRejected(); } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { + AgentInfo.getInstance().getJaHealthCheck().getIastReplayRequest().incrementReplayRequestRejected(); logger.log(LogLevel.WARNING, "Fuzz request " + r.toString() + " rejected from " + e.toString(), EventAbortPolicy.class.getName()); } } \ No newline at end of file diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/IASTDataTransferRequestProcessor.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/IASTDataTransferRequestProcessor.java index 628b2cf99..4177fffc8 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/IASTDataTransferRequestProcessor.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/IASTDataTransferRequestProcessor.java @@ -16,8 +16,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.HashSet; -import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -93,12 +91,10 @@ private void task() { request = new IASTDataTransferRequest(NewRelicSecurity.getAgent().getAgentUUID()); request.setBatchSize(batchSize); - request.setCompletedRequests(getEffectiveCompletedRequests()); - - HashSet pendingRequestIds = new HashSet<>(); - pendingRequestIds.addAll(RestRequestThreadPool.getInstance().getPendingIds()); - pendingRequestIds.addAll(GrpcClientRequestReplayHelper.getInstance().getPendingIds()); - request.setPendingRequestIds(pendingRequestIds); + request.setGeneratedEvent(getEffectiveCompletedRequests()); + request.setClearFromPending(getEffectiveClearFromPending()); + request.setCompletedReplay(getEffectiveCompletedReplay()); + request.setErrorInReplay(getEffectiveErrorInReplay()); WSClient.getInstance().send(request.toString()); } } catch (Throwable e) { @@ -108,19 +104,54 @@ private void task() { } } - private Map> getEffectiveCompletedRequests() { - Map> completedRequest = new HashMap<>(); - completedRequest.putAll(RestRequestThreadPool.getInstance().getProcessedIds()); - completedRequest.putAll(GrpcClientRequestReplayHelper.getInstance().getProcessedIds()); + private Set getEffectiveErrorInReplay() { + Set errorInReplay = new HashSet<>(); + errorInReplay.addAll(RestRequestThreadPool.getInstance().getErrorInReplay()); + errorInReplay.addAll(GrpcClientRequestReplayHelper.getInstance().getErrorInReplay()); + return errorInReplay; + } + + private Set getEffectiveCompletedReplay() { + Set effectiveReplay = new HashSet<>(); + effectiveReplay.addAll(RestRequestThreadPool.getInstance().getCompletedReplay()); + effectiveReplay.addAll(GrpcClientRequestReplayHelper.getInstance().getCompletedReplay()); + return effectiveReplay; + } + + private Set getEffectiveClearFromPending() { + Set effectiveClearFromPending = new HashSet<>(); + effectiveClearFromPending.addAll(RestRequestThreadPool.getInstance().getClearFromPending()); + effectiveClearFromPending.addAll(GrpcClientRequestReplayHelper.getInstance().getClearFromPending()); + return effectiveClearFromPending; + } + + private Map>> getEffectiveCompletedRequests() { + Map>> generatedEvents = new HashMap<>(); + for (String rejectedId : RestRequestThreadPool.getInstance().getRejectedIds()) { - completedRequest.remove(rejectedId); + for (Map.Entry>> applicationMap : RestRequestThreadPool.getInstance().getGeneratedEvent().entrySet()) { + applicationMap.getValue().remove(rejectedId); + } } + generatedEvents.putAll(RestRequestThreadPool.getInstance().getGeneratedEvent()); RestRequestThreadPool.getInstance().getRejectedIds().clear(); + for (String rejectedId : GrpcClientRequestReplayHelper.getInstance().getRejectedIds()) { - completedRequest.remove(rejectedId); + for (Map.Entry>> applicationMap : GrpcClientRequestReplayHelper.getInstance().getGeneratedEvent().entrySet()) { + applicationMap.getValue().remove(rejectedId); + } } + + for (Map.Entry>> applicationMap : GrpcClientRequestReplayHelper.getInstance().getGeneratedEvent().entrySet()) { + if(generatedEvents.containsKey(applicationMap.getKey())){ + generatedEvents.get(applicationMap.getKey()).putAll(applicationMap.getValue()); + } else { + generatedEvents.put(applicationMap.getKey(),applicationMap.getValue()); + } + } + GrpcClientRequestReplayHelper.getInstance().getRejectedIds().clear(); - return completedRequest; + return generatedEvents; } private IASTDataTransferRequestProcessor() { diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RequestUtils.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RequestUtils.java index b518f2d63..de544cc61 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RequestUtils.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RequestUtils.java @@ -1,9 +1,11 @@ package com.newrelic.agent.security.instrumentator.httpclient; +import com.newrelic.agent.security.AgentInfo; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.agent.security.intcodeagent.websocket.JsonConverter; import com.newrelic.api.agent.security.instrumentation.helpers.ICsecApiConstants; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; +import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.agent.security.intcodeagent.models.FuzzRequestBean; import okhttp3.*; @@ -48,7 +50,7 @@ public static boolean refineEndpoints(FuzzRequestBean httpRequest, String endpoi return RestClient.getInstance().isListening(request); } - public static Request generateK2Request(FuzzRequestBean httpRequest, String endpoint) { + public static Request generateK2Request(FuzzRequestBean httpRequest, String endpoint, String controlCommandId) { try { logger.log(LogLevel.FINER, String.format("Firing request : %s", JsonConverter.toJSON(httpRequest)), RequestUtils.class.getName()); StringBuilder url = new StringBuilder(endpoint); @@ -82,7 +84,9 @@ public static Request generateK2Request(FuzzRequestBean httpRequest, String endp requestBuilder = requestBuilder.method(httpRequest.getMethod(), null); } requestBuilder = requestBuilder.headers(Headers.of((Map) httpRequest.getHeaders())); + requestBuilder.header(GenericHelper.CSEC_PARENT_ID, controlCommandId); + AgentInfo.getInstance().getJaHealthCheck().getIastReplayRequest().incrementReplayRequestGenerated(); return requestBuilder.build(); } catch (Exception e){ logger.log(LogLevel.FINEST, String.format(ERROR_IN_FUZZ_REQUEST_GENERATION, e.toString()), RequestUtils.class.getSimpleName()); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestClient.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestClient.java index ec44bec82..cdd857ac6 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestClient.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestClient.java @@ -122,23 +122,22 @@ public OkHttpClient getClient() { return clientThreadLocal.get(); } - public void fireRequest(FuzzRequestBean httpRequest, List endpoints, int repeatCount, String fuzzRequestId){ + public void fireRequest(FuzzRequestBean httpRequest, List endpoints, RestRequestProcessor restRequestProcessor, int repeatCount){ int responseCode = 999; if(endpoints.isEmpty()){ - Request request = RequestUtils.generateK2Request(httpRequest, String.format(IAgentConstants.ENDPOINT_LOCALHOST_S, httpRequest.getProtocol(), httpRequest.getServerPort())); + Request request = RequestUtils.generateK2Request(httpRequest, String.format(IAgentConstants.ENDPOINT_LOCALHOST_S, httpRequest.getProtocol(), httpRequest.getServerPort()), restRequestProcessor.getControlCommand().getId()); if (request != null) { try { - responseCode = RestClient.getInstance().fireRequest(request, repeatCount + endpoints.size() -1, fuzzRequestId); + responseCode = RestClient.getInstance().fireRequest(request, restRequestProcessor, repeatCount + endpoints.size() -1); } catch (SSLException e) { NewRelicSecurity.getAgent().reportIASTScanFailure(null, null, - e, RequestUtils.extractNRCsecFuzzReqHeader(httpRequest), fuzzRequestId, + e, RequestUtils.extractNRCsecFuzzReqHeader(httpRequest), restRequestProcessor.getControlCommand().getId(), String.format(IAgentConstants.SSL_EXCEPTION_FAILURE_MESSAGE, request.url())); logger.log(LogLevel.FINER, String.format(CALL_FAILED_REQUEST_S_REASON, request, e.getMessage()), e, RestClient.class.getName()); logger.postLogMessageIfNecessary(LogLevel.WARNING, - String.format(CALL_FAILED_REQUEST_S_REASON, fuzzRequestId, e.getMessage()), + String.format(CALL_FAILED_REQUEST_S_REASON, restRequestProcessor.getControlCommand().getId(), e.getMessage()), e, RestRequestProcessor.class.getName()); - RestRequestThreadPool.getInstance().getProcessedIds().putIfAbsent(fuzzRequestId, new HashSet<>()); // TODO: Add to fuzz fail count in HC and remove FuzzFailEvent if not needed. FuzzFailEvent fuzzFailEvent = new FuzzFailEvent(AgentInfo.getInstance().getApplicationUUID()); fuzzFailEvent.setFuzzHeader(request.header(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); @@ -148,10 +147,10 @@ public void fireRequest(FuzzRequestBean httpRequest, List endpoints, int return; } for (String endpoint : endpoints) { - Request request = RequestUtils.generateK2Request(httpRequest, endpoint); + Request request = RequestUtils.generateK2Request(httpRequest, endpoint, restRequestProcessor.getControlCommand().getId()); try { if (request != null) { - responseCode = RestClient.getInstance().fireRequest(request, repeatCount + endpoints.size() -1, fuzzRequestId); + responseCode = fireRequest(request, restRequestProcessor, repeatCount + endpoints.size() -1); } if(responseCode == 301){continue;} break; @@ -185,7 +184,7 @@ public boolean isListening(Request request) { return false; } - public int fireRequest(Request request, int repeatCount, String fuzzRequestId) throws SSLException { + public int fireRequest(Request request, RestRequestProcessor restRequestProcessor, int repeatCount) throws SSLException { OkHttpClient client = clientThreadLocal.get(); logger.log(LogLevel.FINER, String.format(FIRING_REQUEST_METHOD_S, request.method()), RestClient.class.getName()); @@ -197,45 +196,50 @@ public int fireRequest(Request request, int repeatCount, String fuzzRequestId) t logger.log(LogLevel.FINER, String.format(REQUEST_FIRED_SUCCESS, request), RestClient.class.getName()); if (response.code() >= 500) { logger.postLogMessageIfNecessary(LogLevel.WARNING, - String.format(RestClient.CALL_FAILED_REQUEST_S_REASON_S, fuzzRequestId, response, response.body().string()), null, + String.format(RestClient.CALL_FAILED_REQUEST_S_REASON_S, restRequestProcessor.getControlCommand().getId(), response, response.body().string()), null, RestRequestProcessor.class.getName()); } else if(response.code() >= 400){ String responseBody = response.body().string(); NewRelicSecurity.getAgent().reportIASTScanFailure(null, null, null, - RequestUtils.extractNRCsecFuzzReqHeader(request.headers()), fuzzRequestId, + RequestUtils.extractNRCsecFuzzReqHeader(request.headers()), restRequestProcessor.getControlCommand().getId(), String.format(IAgentConstants.REQUEST_FAILURE_FOR_S_WITH_RESPONSE_CODE, request.url(), response, responseBody)); - RestRequestThreadPool.getInstance().getProcessedIds().putIfAbsent(fuzzRequestId, new HashSet<>()); logger.postLogMessageIfNecessary(LogLevel.WARNING, - String.format(RestClient.CALL_FAILED_REQUEST_S_REASON_S, fuzzRequestId, response, responseBody), null, + String.format(RestClient.CALL_FAILED_REQUEST_S_REASON_S, restRequestProcessor.getControlCommand().getId(), response, responseBody), null, RestRequestProcessor.class.getName()); - } else if(response.isSuccessful()){ - RestRequestThreadPool.getInstance().getProcessedIds().putIfAbsent(fuzzRequestId, new HashSet<>()); - }else { + } else { logger.log(LogLevel.FINER, String.format(REQUEST_SUCCESS_S_RESPONSE_S_S, request, response, response.body().string()), RestClient.class.getName()); } + restRequestProcessor.setSuccessful(true); + restRequestProcessor.setResponseCode(response.code()); response.body().close(); if (client.connectionPool() != null) { client.connectionPool().evictAll(); } return response.code(); } catch (SSLException e){ + restRequestProcessor.setExceptionRaised(true); + restRequestProcessor.setError(e); logger.log(LogLevel.FINE, String.format("Request failed due to SSL Exception %s : reason %s", request, e.getMessage()), e, RestClient.class.getName()); throw e; } catch (InterruptedIOException e){ + restRequestProcessor.setExceptionRaised(true); + restRequestProcessor.setError(e); if(repeatCount >= 0){ - return fireRequest(request, --repeatCount, fuzzRequestId); + return fireRequest(request, restRequestProcessor, --repeatCount); } } catch (IOException e) { NewRelicSecurity.getAgent().reportIASTScanFailure(null, null, - e, RequestUtils.extractNRCsecFuzzReqHeader(request.headers()), fuzzRequestId, + e, RequestUtils.extractNRCsecFuzzReqHeader(request.headers()), restRequestProcessor.getControlCommand().getId(), IAgentConstants.REQUEST_FAILURE_DUE_TO_IOEXCEPTION); logger.log(LogLevel.FINER, String.format(CALL_FAILED_REQUEST_S_REASON, e.getMessage(), request), e, RestClient.class.getName()); + restRequestProcessor.setExceptionRaised(true); + restRequestProcessor.setError(e); + logger.log(LogLevel.FINER, String.format(CALL_FAILED_REQUEST_S_REASON, request), e, RestClient.class.getName()); logger.postLogMessageIfNecessary(LogLevel.WARNING, - String.format(CALL_FAILED_REQUEST_S_REASON, e.getMessage(), fuzzRequestId), + String.format(CALL_FAILED_REQUEST_S_REASON, restRequestProcessor.getControlCommand().getId(), e.getMessage()), e, RestRequestProcessor.class.getName()); - RestRequestThreadPool.getInstance().getProcessedIds().putIfAbsent(fuzzRequestId, new HashSet<>()); // TODO: Add to fuzz fail count in HC and remove FuzzFailEvent if not needed. FuzzFailEvent fuzzFailEvent = new FuzzFailEvent(AgentInfo.getInstance().getApplicationUUID()); fuzzFailEvent.setFuzzHeader(request.header(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID)); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestRequestProcessor.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestRequestProcessor.java index 021694b94..5f96f5d86 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestRequestProcessor.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestRequestProcessor.java @@ -43,6 +43,14 @@ public class RestRequestProcessor implements Callable { private int repeatCount; + private boolean isSuccessful = false; + + private int responseCode; + + private boolean exceptionRaised = false; + + private Throwable error; + private ObjectMapper objectMapper = new ObjectMapper(); private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); @@ -52,6 +60,41 @@ public RestRequestProcessor(IntCodeControlCommand controlCommand, int repeatCoun this.repeatCount = repeatCount; } + public boolean isSuccessful() { + return isSuccessful; + } + + public void setSuccessful(boolean successful) { + isSuccessful = successful; + } + + public int getResponseCode() { + return responseCode; + } + + public void setResponseCode(int responseCode) { + this.responseCode = responseCode; + } + + public boolean isExceptionRaised() { + return exceptionRaised; + } + + public void setExceptionRaised(boolean exceptionRaised) { + this.exceptionRaised = exceptionRaised; + } + + public Throwable getError() { + return error; + } + + public void setError(Throwable error) { + this.error = error; + } + + public int getRepeatCount() { + return repeatCount; + } /** * Does the request replay in IAST mode. @@ -81,13 +124,7 @@ public Boolean call() throws InterruptedException { httpRequest = objectMapper.readValue(req, FuzzRequestBean.class); httpRequest.getHeaders().put(GenericHelper.CSEC_PARENT_ID, controlCommand.getId()); - if (httpRequest.getIsGrpc()){ - GrpcClientRequestReplayHelper.getInstance().getPendingIds().add(controlCommand.getId()); - GrpcClientRequestReplayHelper.getInstance().removeFromProcessedCC(controlCommand.getId()); - } else { - RestRequestThreadPool.getInstance().getPendingIds().add(controlCommand.getId()); - RestRequestThreadPool.getInstance().removeFromProcessedCC(controlCommand.getId()); - } + httpRequest.setReflectedMetaData(controlCommand.getReflectedMetaData()); if (httpRequest.getIsGrpc()){ @@ -114,32 +151,26 @@ public Boolean call() throws InterruptedException { logger.log(LogLevel.FINER, String.format("Endpoints to fire in empty: %s", endpoints), RestRequestProcessor.class.getSimpleName()); postSSL = true; } - RestClient.getInstance().fireRequest(httpRequest, endpoints, repeatCount + endpoints.size() -1, controlCommand.getId()); + RestClient.getInstance().fireRequest(httpRequest, endpoints, this, repeatCount + endpoints.size() -1); } return true; } catch (JsonProcessingException e){ - NewRelicSecurity.getAgent().reportIASTScanFailure(null, null, - e, null, controlCommand.getId(), - String.format(JSON_PARSING_ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S, controlCommand.getArguments().get(0))); - + setExceptionRaised(true); + setError(e); logger.log(LogLevel.SEVERE, String.format(JSON_PARSING_ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S, controlCommand.getArguments().get(0)), e, RestRequestProcessor.class.getName()); logger.postLogMessageIfNecessary(LogLevel.SEVERE, String.format(JSON_PARSING_ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S, controlCommand.getId()), e, RestRequestProcessor.class.getName()); - RestRequestThreadPool.getInstance().getProcessedIds().putIfAbsent(controlCommand.getId(), new HashSet<>()); } catch (Throwable e) { - NewRelicSecurity.getAgent().reportIASTScanFailure(null, null, - e, RequestUtils.extractNRCsecFuzzReqHeader(httpRequest), controlCommand.getId(), - String.format(JSON_PARSING_ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S, controlCommand.getArguments().get(0))); - + setExceptionRaised(true); + setError(e); logger.log(LogLevel.SEVERE, String.format(ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S, controlCommand.getArguments().get(0)), e, RestRequestProcessor.class.getName()); logger.postLogMessageIfNecessary(LogLevel.SEVERE, String.format(ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S, controlCommand.getId()), e, RestRequestProcessor.class.getName()); - RestRequestThreadPool.getInstance().getProcessedIds().putIfAbsent(controlCommand.getId(), new HashSet<>()); throw e; } return true; diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestRequestThreadPool.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestRequestThreadPool.java index e0238558e..c60670724 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestRequestThreadPool.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/httpclient/RestRequestThreadPool.java @@ -7,9 +7,8 @@ import com.newrelic.api.agent.security.utils.logging.LogLevel; import org.apache.commons.lang3.StringUtils; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.io.InterruptedIOException; +import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -31,19 +30,42 @@ public class RestRequestThreadPool { private static final AtomicBoolean isWaiting = new AtomicBoolean(false); - private final Map> processedIds = new ConcurrentHashMap(); + private final Set rejectedIds = ConcurrentHashMap.newKeySet(); - private final Set pendingIds = ConcurrentHashMap.newKeySet(); + private Set completedReplay = ConcurrentHashMap.newKeySet(); + + private Set errorInReplay = ConcurrentHashMap.newKeySet(); + + private Set clearFromPending = ConcurrentHashMap.newKeySet(); + + /** + * "generatedEvents": + * { + * "ORIGIN_APPUUID_1" : {"FUZZ_ID_1":["EVENT_ID_1"], "FUZZ_ID_2":["EVENT_ID_2"]}, + * } + * */ + private final Map>> generatedEvent = new ConcurrentHashMap(); - private final Set rejectedIds = ConcurrentHashMap.newKeySet(); public void resetIASTProcessing() { - rejectedIds.addAll(processedIds.keySet()); - processedIds.clear(); - pendingIds.clear(); + getAllControlCommandID(generatedEvent); + generatedEvent.clear(); + completedReplay.clear(); + clearFromPending.clear(); + errorInReplay.clear(); executor.getQueue().clear(); } + private void getAllControlCommandID(Map>> generatedEvents) { + if(generatedEvents == null || generatedEvents.isEmpty()) { + return; + } + + for (Map> applicationMap : generatedEvents.values()) { + rejectedIds.addAll(applicationMap.keySet()); + } + } + private RestRequestThreadPool() { LinkedBlockingQueue processQueue; // load the settings @@ -56,21 +78,31 @@ protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); String controlCommandId = null; if (r instanceof CustomFutureTask && ((CustomFutureTask) r).getTask() instanceof RestRequestProcessor) { - Boolean result = (Boolean) ((CustomFutureTask) r).get(); + AgentInfo.getInstance().getJaHealthCheck().getIastReplayRequest().incrementReplayRequestExecuted(); RestRequestProcessor task = (RestRequestProcessor) ((CustomFutureTask) r).getTask(); controlCommandId = task.getControlCommand().getId(); - if(t != null || !result) { - if (StringUtils.isNotBlank(controlCommandId)) { - rejectedIds.add(controlCommandId); - } + if(task.isSuccessful() && 500 < task.getResponseCode() && task.getResponseCode() >= 400){ + errorInReplay.add(controlCommandId); + } else if (task.isSuccessful()) { + completedReplay.add(controlCommandId); + } else if (task.isExceptionRaised() && task.getError() instanceof InterruptedIOException) { + clearFromPending.add(controlCommandId); + } else if(task.isExceptionRaised()) { + errorInReplay.add(controlCommandId); } else { - processedIds.putIfAbsent(controlCommandId, new HashSet<>()); + clearFromPending.add(controlCommandId); + } + if (StringUtils.isBlank(controlCommandId)) { + rejectedIds.add(controlCommandId); + } + + if(task.isSuccessful() && 200 <= task.getResponseCode() && task.getResponseCode() < 300){ + AgentInfo.getInstance().getJaHealthCheck().getIastReplayRequest().incrementReplayRequestSucceeded(); + } else { + AgentInfo.getInstance().getJaHealthCheck().getIastReplayRequest().incrementReplayRequestFailed(); } } - if(StringUtils.isNotBlank(controlCommandId)){ - pendingIds.remove(controlCommandId); - } - } catch (ExecutionException | InterruptedException ignored) { + } catch (Exception ignored) { } } @@ -136,32 +168,36 @@ public ThreadPoolExecutor getExecutor() { return executor; } - public Map> getProcessedIds() { - return processedIds; - } - public Set getRejectedIds() { return rejectedIds; } - public Set getPendingIds() { - return pendingIds; + public Set getCompletedReplay() { + return completedReplay; } - public void registerEventForProcessedCC(String controlCommandId, String eventId) { + public Set getErrorInReplay() { + return errorInReplay; + } + + public Set getClearFromPending() { + return clearFromPending; + } + + public void registerEventForProcessedCC(String controlCommandId, String eventId, String originAppUuid) { if(StringUtils.isAnyBlank(controlCommandId, eventId)){ return; } - Set registeredEvents = processedIds.get(controlCommandId); - if(registeredEvents != null) { - registeredEvents.add(eventId); + if(!generatedEvent.containsKey(originAppUuid)){ + logger.log(LogLevel.FINE, String.format("Entry from map of generatedEvents for %s is missing. generatedEvents are : %s", originAppUuid, generatedEvent), RestRequestThreadPool.class.getName()); } - } - public void removeFromProcessedCC(String controlCommandId) { - if(StringUtils.isNotBlank(controlCommandId)){ - processedIds.remove(controlCommandId); + if(generatedEvent.get(originAppUuid).containsKey(controlCommandId)) { + generatedEvent.get(originAppUuid).get(controlCommandId).add(eventId); } } + public Map>> getGeneratedEvent() { + return generatedEvent; + } } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/HashGenerator.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/HashGenerator.java index dc6f5914c..244f320d0 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/HashGenerator.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/HashGenerator.java @@ -148,8 +148,7 @@ public static String getSHA256HexDigest(List data) { return getChecksum(input); } public static String getSHA256HexDigest(String data) { - String input = StringUtils.join(data); - return getChecksum(input); + return getChecksum(data); } /** diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessor.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessor.java index be5511579..628d12160 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessor.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessor.java @@ -2,18 +2,19 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.newrelic.agent.security.AgentInfo; +import com.fasterxml.jackson.databind.ObjectMapper; import com.newrelic.agent.security.instrumentator.httpclient.IASTDataTransferRequestProcessor; import com.newrelic.agent.security.instrumentator.httpclient.RestRequestProcessor; import com.newrelic.agent.security.instrumentator.httpclient.RestRequestThreadPool; import com.newrelic.agent.security.instrumentator.utils.AgentUtils; import com.newrelic.agent.security.instrumentator.utils.InstrumentationUtils; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; +import com.newrelic.agent.security.intcodeagent.models.IASTDataTransferRequest; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.agent.security.intcodeagent.logging.IAgentConstants; import com.newrelic.agent.security.intcodeagent.models.config.AgentPolicyParameters; import com.newrelic.agent.security.intcodeagent.models.javaagent.EventResponse; import com.newrelic.agent.security.intcodeagent.models.javaagent.IntCodeControlCommand; -import com.newrelic.agent.security.intcodeagent.utils.CommonUtils; import com.newrelic.agent.security.intcodeagent.websocket.EventSendPool; import com.newrelic.agent.security.intcodeagent.websocket.JsonConverter; import com.newrelic.agent.security.intcodeagent.websocket.WSClient; @@ -30,6 +31,7 @@ import java.time.temporal.ChronoUnit; import java.util.List; import java.util.Map; +import java.util.Set; public class ControlCommandProcessor implements Runnable { @@ -66,6 +68,7 @@ public class ControlCommandProcessor implements Runnable { public static final String PURGING_CONFIRMED_IAST_PROCESSED_RECORDS_COUNT_S = "Purging confirmed IAST processed records count : %s"; public static final String PURGING_CONFIRMED_IAST_PROCESSED_RECORDS_S = "Purging confirmed IAST processed records : %s"; + private ObjectMapper objectMapper = new ObjectMapper(); private String controlCommandMessage; @@ -261,8 +264,8 @@ public void run() { controlCommand.getArguments().size()), this.getClass().getName()); logger.log(LogLevel.FINEST, String.format(PURGING_CONFIRMED_IAST_PROCESSED_RECORDS_S, controlCommand.getArguments()), this.getClass().getName()); - controlCommand.getArguments().forEach(RestRequestThreadPool.getInstance().getProcessedIds()::remove); - controlCommand.getArguments().forEach(GrpcClientRequestReplayHelper.getInstance().getProcessedIds()::remove); + IASTDataTransferRequest requestForPurge = objectMapper.convertValue(controlCommand.getData(), IASTDataTransferRequest.class); + purgeIastDataTransferRequest(requestForPurge); break; default: logger.log(LogLevel.WARNING, String.format(UNKNOWN_CONTROL_COMMAND_S, controlCommandMessage), @@ -271,6 +274,28 @@ public void run() { } } + private static void purgeIastDataTransferRequest(IASTDataTransferRequest requestForPurge) { + + GrpcClientRequestReplayHelper.getInstance().getCompletedReplay().removeAll(requestForPurge.getCompletedReplay()); + GrpcClientRequestReplayHelper.getInstance().getErrorInReplay().removeAll(requestForPurge.getErrorInReplay()); + GrpcClientRequestReplayHelper.getInstance().getClearFromPending().removeAll(requestForPurge.getClearFromPending()); + for (Map.Entry>> applicationMap : GrpcClientRequestReplayHelper.getInstance().getGeneratedEvent().entrySet()) { + String originAppUUID = applicationMap.getKey(); + Map> purgeApplicationMap = requestForPurge.getGeneratedEvent().get(originAppUUID); + purgeApplicationMap.forEach(applicationMap.getValue()::remove); + } + + + RestRequestThreadPool.getInstance().getCompletedReplay().removeAll(requestForPurge.getCompletedReplay()); + RestRequestThreadPool.getInstance().getErrorInReplay().removeAll(requestForPurge.getErrorInReplay()); + RestRequestThreadPool.getInstance().getClearFromPending().removeAll(requestForPurge.getClearFromPending()); + for (Map.Entry>> applicationMap : RestRequestThreadPool.getInstance().getGeneratedEvent().entrySet()) { + String originAppUUID = applicationMap.getKey(); + Map> purgeApplicationMap = requestForPurge.getGeneratedEvent().get(originAppUUID); + purgeApplicationMap.forEach(applicationMap.getValue()::remove); + } + } + public static void processControlCommand(String controlCommandMessage, long receiveTimestamp) { ControlCommandProcessorThreadPool.getInstance().executor .submit(new ControlCommandProcessor(controlCommandMessage, receiveTimestamp)); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/logging/HealthCheckScheduleThread.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/logging/HealthCheckScheduleThread.java index a33da7bbe..e83f94a78 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/logging/HealthCheckScheduleThread.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/logging/HealthCheckScheduleThread.java @@ -81,6 +81,10 @@ public void run() { logger.log(LogLevel.INFO, String.format("Pending CCs to be processed : %s", RestRequestThreadPool.getInstance().getQueueSize()), this.getClass().getName()); AgentInfo.getInstance().getJaHealthCheck().getIastReplayRequest().incrementPendingControlCommandsBy(RestRequestThreadPool.getInstance().getQueueSize()); AgentInfo.getInstance().getJaHealthCheck().getIastReplayRequest().incrementPendingControlCommandsBy(GrpcClientRequestReplayHelper.getInstance().getRequestQueue().size()); + AgentInfo.getInstance().getJaHealthCheck().getIastReplayRequest().incrementReplayRequestExecutedBy(GrpcClientRequestReplayHelper.getInstance().getReplayRequestExecuted()); + AgentInfo.getInstance().getJaHealthCheck().getIastReplayRequest().incrementReplayRequestFailedBy(GrpcClientRequestReplayHelper.getInstance().getReplayRequestFailed()); + AgentInfo.getInstance().getJaHealthCheck().getIastReplayRequest().incrementReplayRequestSucceededBy(GrpcClientRequestReplayHelper.getInstance().getReplayRequestSucceeded()); + GrpcClientRequestReplayHelper.getInstance().resetReplayRequestMetric(); AgentUtils.getInstance().addStatusLogMostRecentHCs(AgentInfo.getInstance().getJaHealthCheck().toString()); // channel.write(ByteBuffer.wrap(new JAHealthCheck(AgentNew.JA_HEALTH_CHECK).toString().getBytes())); if (WSClient.getInstance().isOpen()) { @@ -122,7 +126,7 @@ private ThreadPoolStats populateThreadPoolStats() { private HealthCheckScheduleThread() {} public void scheduleNewTask() { - future = SchedulerHelper.getInstance().scheduleHealthCheck(runnable, 30, 30, TimeUnit.SECONDS); + future = SchedulerHelper.getInstance().scheduleHealthCheck(runnable, 300, 300, TimeUnit.SECONDS); } public boolean cancelTask(boolean forceCancel) { diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/IASTDataTransferRequest.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/IASTDataTransferRequest.java index 9a7fe3b02..34894c579 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/IASTDataTransferRequest.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/IASTDataTransferRequest.java @@ -14,11 +14,13 @@ public class IASTDataTransferRequest { private int batchSize; - private Set pendingRequestIds; + private Set completedReplay; - private Map> completedRequests; + private Set errorInReplay; - private String sequenceNumber; + private Set clearFromPending; + + private Map>> generatedEvent; public IASTDataTransferRequest() {} public IASTDataTransferRequest(String applicationUUID) { @@ -41,28 +43,44 @@ public void setBatchSize(int batchSize) { this.batchSize = batchSize; } - public Map> getCompletedRequests() { - return completedRequests; + public String getJsonName() { + return jsonName; } - public void setCompletedRequests(Map> completedRequests) { - this.completedRequests = completedRequests; + public void setJsonName(String jsonName) { + this.jsonName = jsonName; } - public Set getPendingRequestIds() { - return pendingRequestIds; + public Set getCompletedReplay() { + return completedReplay; } - public void setPendingRequestIds(Set pendingRequestIds) { - this.pendingRequestIds = pendingRequestIds; + public void setCompletedReplay(Set completedReplay) { + this.completedReplay = completedReplay; } - public String getJsonName() { - return jsonName; + public Set getErrorInReplay() { + return errorInReplay; } - public void setJsonName(String jsonName) { - this.jsonName = jsonName; + public void setErrorInReplay(Set errorInReplay) { + this.errorInReplay = errorInReplay; + } + + public Set getClearFromPending() { + return clearFromPending; + } + + public void setClearFromPending(Set clearFromPending) { + this.clearFromPending = clearFromPending; + } + + public Map>> getGeneratedEvent() { + return generatedEvent; + } + + public void setGeneratedEvent(Map>> generatedEvent) { + this.generatedEvent = generatedEvent; } @Override diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/IastReplayRequest.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/IastReplayRequest.java index 15b9dba2f..b6b3999f8 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/IastReplayRequest.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/IastReplayRequest.java @@ -8,8 +8,6 @@ public class IastReplayRequest { private AtomicInteger receivedControlCommands = new AtomicInteger(); - private AtomicInteger processedControlCommands = new AtomicInteger(); - private AtomicInteger pendingControlCommands = new AtomicInteger(); private AtomicInteger replayRequestGenerated = new AtomicInteger(); @@ -27,7 +25,6 @@ public IastReplayRequest() { public IastReplayRequest(IastReplayRequest iastReplayRequest) { this.receivedControlCommands.set(iastReplayRequest.getReceivedControlCommands().get()); - this.processedControlCommands.set(iastReplayRequest.getProcessedControlCommands().get()); this.pendingControlCommands.set(iastReplayRequest.getPendingControlCommands().get()); this.replayRequestGenerated.set(iastReplayRequest.getReplayRequestGenerated().get()); this.replayRequestExecuted.set(iastReplayRequest.getReplayRequestExecuted().get()); @@ -40,10 +37,6 @@ public AtomicInteger getReceivedControlCommands() { return receivedControlCommands; } - public AtomicInteger getProcessedControlCommands() { - return processedControlCommands; - } - public AtomicInteger getPendingControlCommands() { return pendingControlCommands; } @@ -72,14 +65,6 @@ public int incrementReceivedControlCommands() { return receivedControlCommands.incrementAndGet(); } - public int incrementProcessedControlCommands() { - return processedControlCommands.incrementAndGet(); - } - - public int incrementPendingControlCommands() { - return pendingControlCommands.incrementAndGet(); - } - public int incrementReplayRequestGenerated() { return replayRequestGenerated.incrementAndGet(); } @@ -104,9 +89,20 @@ public void incrementPendingControlCommandsBy(int count) { pendingControlCommands.addAndGet(count); } + public void incrementReplayRequestExecutedBy(int count) { + replayRequestExecuted.addAndGet(count); + } + + public void incrementReplayRequestSucceededBy(int count) { + replayRequestSucceeded.addAndGet(count); + } + + public void incrementReplayRequestFailedBy(int count) { + replayRequestFailed.addAndGet(count); + } + public void reset() { receivedControlCommands.set(0); - processedControlCommands.set(0); pendingControlCommands.set(0); replayRequestGenerated.set(0); replayRequestExecuted.set(0); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/WSClient.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/WSClient.java index df8ebdffe..3d00c81c3 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/WSClient.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/WSClient.java @@ -200,7 +200,7 @@ public void onOpen(ServerHandshake handshakedata) { public void onMessage(String message) { // Receive communication from IC side. try { - AgentInfo.getInstance().getJaHealthCheck().getWebSocketConnectionStats().incrementMessagesSent(); + AgentInfo.getInstance().getJaHealthCheck().getWebSocketConnectionStats().incrementMessagesReceived(); if (logger.isLogLevelEnabled(LogLevel.FINEST)) { logger.log(LogLevel.FINEST, String.format(INCOMING_CONTROL_COMMAND_S, message), this.getClass().getName()); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/api/agent/security/Agent.java b/newrelic-security-agent/src/main/java/com/newrelic/api/agent/security/Agent.java index c9dccf1a7..1caa392ae 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/api/agent/security/Agent.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/api/agent/security/Agent.java @@ -4,6 +4,7 @@ import com.newrelic.agent.security.AgentConfig; import com.newrelic.agent.security.AgentInfo; import com.newrelic.agent.security.instrumentator.dispatcher.DispatcherPool; +import com.newrelic.agent.security.instrumentator.httpclient.RestRequestThreadPool; import com.newrelic.agent.security.instrumentator.os.OsVariablesInstance; import com.newrelic.agent.security.instrumentator.utils.*; import com.newrelic.agent.security.intcodeagent.constants.AgentServices; @@ -35,10 +36,8 @@ import java.net.HttpURLConnection; import java.net.URL; import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; @@ -754,4 +753,36 @@ public String decryptAndVerify(String encryptedData, String hashVerifier) { } } + @Override + public void setEmptyIastDataRequestEntry(FuzzRequestEmptyEntry fuzzRequestEmptyEntry, RequestCategory category) { + switch (category) { + case GRPC: + setEmptyIastDataRequestEntry(fuzzRequestEmptyEntry, GrpcClientRequestReplayHelper.getInstance().getGeneratedEvent()); + break; + case HTTP: + default: + setEmptyIastDataRequestEntry(fuzzRequestEmptyEntry, RestRequestThreadPool.getInstance().getGeneratedEvent()); + break; + } + } + + + private void setEmptyIastDataRequestEntry(FuzzRequestEmptyEntry fuzzRequestEmptyEntry, Map>> generatedEvent) { + String currentEntityGuid = AgentInfo.getInstance().getLinkingMetadata().getOrDefault(INRSettingsKey.NR_ENTITY_GUID, StringUtils.EMPTY); + String originAppUUID = fuzzRequestEmptyEntry.getOriginAppUuid(); + if(StringUtils.isBlank(originAppUUID)){ + originAppUUID = AgentInfo.getInstance().getApplicationUUID(); + } + String shaDigestOfCurrentEntityGuid = HashGenerator.getSHA256HexDigest(currentEntityGuid); + if(StringUtils.equals(shaDigestOfCurrentEntityGuid, fuzzRequestEmptyEntry.getOriginEntityGuid())){ + if(generatedEvent.containsKey(originAppUUID)) { + generatedEvent.get(originAppUUID).put(fuzzRequestEmptyEntry.getControlCommandId(), ConcurrentHashMap.newKeySet()); + } else { + Map> emptyEntry = new ConcurrentHashMap<>(); + emptyEntry.put(fuzzRequestEmptyEntry.getControlCommandId(), ConcurrentHashMap.newKeySet()); + generatedEvent.put(originAppUUID, emptyEntry); + } + } + } + } \ No newline at end of file diff --git a/newrelic-security-api-test-impl/src/main/java/com/newrelic/api/agent/security/Agent.java b/newrelic-security-api-test-impl/src/main/java/com/newrelic/api/agent/security/Agent.java index c906210fa..1e53e41ad 100644 --- a/newrelic-security-api-test-impl/src/main/java/com/newrelic/api/agent/security/Agent.java +++ b/newrelic-security-api-test-impl/src/main/java/com/newrelic/api/agent/security/Agent.java @@ -2,8 +2,9 @@ import com.newrelic.api.agent.NewRelic; import com.newrelic.api.agent.Transaction; -import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.FuzzRequestEmptyEntry; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.ServerConnectionConfiguration; import com.newrelic.api.agent.security.schema.operation.FileIntegrityOperation; @@ -13,10 +14,7 @@ import java.lang.instrument.Instrumentation; import java.net.URL; import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class Agent implements SecurityAgent { @@ -201,4 +199,10 @@ public void retransformUninstrumentedClass(Class classToRetransform) { public String decryptAndVerify(String encryptedData, String hashVerifier) { return null; } + + @Override + public void setEmptyIastDataRequestEntry(FuzzRequestEmptyEntry fuzzRequestEmptyEntry, RequestCategory category) { + + } + } \ No newline at end of file diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/NoOpAgent.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/NoOpAgent.java index d7ae1ec51..63a84df84 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/NoOpAgent.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/NoOpAgent.java @@ -7,8 +7,9 @@ package com.newrelic.api.agent.security; -import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.FuzzRequestEmptyEntry; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.ServerConnectionConfiguration; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; @@ -18,6 +19,7 @@ import java.net.URL; import java.util.Collections; import java.util.Map; +import java.util.Set; /** * Provides NoOps for API objects to avoid returning null. Do not call these objects directly. @@ -132,5 +134,10 @@ public String decryptAndVerify(String encryptedData, String hashVerifier) { return null; } + @Override + public void setEmptyIastDataRequestEntry(FuzzRequestEmptyEntry fuzzRequestEmptyEntry, RequestCategory category) { + + } + } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/SecurityAgent.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/SecurityAgent.java index 2ae86ea9e..726c0ab34 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/SecurityAgent.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/SecurityAgent.java @@ -8,6 +8,8 @@ package com.newrelic.api.agent.security; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.FuzzRequestEmptyEntry; +import com.newrelic.api.agent.security.schema.RequestCategory; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.ServerConnectionConfiguration; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; @@ -16,6 +18,7 @@ import java.lang.instrument.Instrumentation; import java.net.URL; import java.util.Map; +import java.util.Set; /** * The New Relic Security Java Agent's API. @@ -71,4 +74,6 @@ void reportIASTScanFailure(SecurityMetaData securityMetaData, String apiId, Thro void retransformUninstrumentedClass(Class classToRetransform); String decryptAndVerify(String encryptedData, String hashVerifier); + + void setEmptyIastDataRequestEntry(FuzzRequestEmptyEntry fuzzRequestEmptyEntry, RequestCategory category); } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GrpcClientRequestReplayHelper.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GrpcClientRequestReplayHelper.java index eb2eef653..257387cf4 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GrpcClientRequestReplayHelper.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GrpcClientRequestReplayHelper.java @@ -1,8 +1,10 @@ package com.newrelic.api.agent.security.instrumentation.helpers; +import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.schema.ControlCommandDto; import com.newrelic.api.agent.security.schema.FuzzRequestBean; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.utils.logging.LogLevel; import java.util.Collections; import java.util.Map; @@ -11,15 +13,77 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; public class GrpcClientRequestReplayHelper { private BlockingQueue requestQueue = new LinkedBlockingQueue<>(1000); private BlockingQueue inProcessRequestQueue = new LinkedBlockingQueue(1000); private BlockingQueue> fuzzFailRequestQueue = new LinkedBlockingQueue(1000); private boolean isGrpcRequestExecutorStarted = false; - private final Map> processedIds = new ConcurrentHashMap(); - private final Set pendingIds = ConcurrentHashMap.newKeySet(); + private final Set rejectedIds = ConcurrentHashMap.newKeySet(); + + private Set completedReplay = ConcurrentHashMap.newKeySet(); + + private Set errorInReplay = ConcurrentHashMap.newKeySet(); + + private Set clearFromPending = ConcurrentHashMap.newKeySet(); + + private AtomicInteger replayRequestGenerated = new AtomicInteger(); + + private AtomicInteger replayRequestExecuted = new AtomicInteger(); + + private AtomicInteger replayRequestSucceeded = new AtomicInteger(); + + private AtomicInteger replayRequestFailed = new AtomicInteger(); + + public int incrementReplayRequestGenerated() { + return replayRequestGenerated.incrementAndGet(); + } + + public int incrementReplayRequestExecuted() { + return replayRequestExecuted.incrementAndGet(); + } + + public int incrementReplayRequestSucceeded() { + return replayRequestSucceeded.incrementAndGet(); + } + + public int incrementReplayRequestFailed() { + return replayRequestFailed.incrementAndGet(); + } + + public int getReplayRequestGenerated() { + return replayRequestGenerated.get(); + } + + public int getReplayRequestExecuted() { + return replayRequestExecuted.get(); + } + + public int getReplayRequestSucceeded() { + return replayRequestSucceeded.get(); + } + + public int getReplayRequestFailed() { + return replayRequestFailed.get(); + } + + public void resetReplayRequestMetric() { + replayRequestGenerated.set(0); + replayRequestExecuted.set(0); + replayRequestSucceeded.set(0); + replayRequestFailed.set(0); + } + + /** + * "generatedEvents": + * { + * "ORIGIN_APPUUID_1" : {"FUZZ_ID_1":["EVENT_ID_1"], "FUZZ_ID_2":["EVENT_ID_2"]}, + * } + * */ + private final Map>> generatedEvent = new ConcurrentHashMap(); + private static final AtomicBoolean isWaiting = new AtomicBoolean(false); public static GrpcClientRequestReplayHelper getInstance(){ @@ -30,10 +94,22 @@ private static final class InstanceHolder { static final GrpcClientRequestReplayHelper instance = new GrpcClientRequestReplayHelper(); } + private void getAllControlCommandID(Map>> generatedEvents) { + if(generatedEvents == null || generatedEvents.isEmpty()) { + return; + } + + for (Map> applicationMap : generatedEvents.values()) { + rejectedIds.addAll(applicationMap.keySet()); + } + } + public void resetIASTProcessing() { - rejectedIds.addAll(processedIds.keySet()); - processedIds.clear(); - pendingIds.clear(); + getAllControlCommandID(generatedEvent); + generatedEvent.clear(); + completedReplay.clear(); + clearFromPending.clear(); + errorInReplay.clear(); requestQueue.clear(); } @@ -81,34 +157,48 @@ public Map getSingleRequestFromFuzzFailRequestQueue( return fuzzFailRequestQueue.take(); } - public Map> getProcessedIds() { - return processedIds; - } - public Set getRejectedIds() { return rejectedIds; } - public Set getPendingIds() { - return pendingIds; + public void registerEventForProcessedCC(String controlCommandId, String eventId, String originAppUuid) { + if(StringUtils.isAnyBlank(controlCommandId, eventId)){ + return; + } + if(!generatedEvent.containsKey(originAppUuid)){ + NewRelicSecurity.getAgent().log(LogLevel.FINE, String.format("Entry from map of generatedEvents for %s is missing. generatedEvents are : %s", originAppUuid, generatedEvent), GrpcClientRequestReplayHelper.class.getName()); + } + + if(generatedEvent.get(originAppUuid).containsKey(controlCommandId)) { + generatedEvent.get(originAppUuid).get(controlCommandId).add(eventId); + } } + public Set getCompletedReplay() { + return completedReplay; + } + public void setCompletedReplay(Set completedReplay) { + this.completedReplay = completedReplay; + } + public Set getErrorInReplay() { + return errorInReplay; + } - public void registerEventForProcessedCC(String controlCommandId, String eventId) { - if(StringUtils.isAnyBlank(controlCommandId, eventId)){ - return; - } - Set registeredEvents = processedIds.get(controlCommandId); - if(registeredEvents != null) { - registeredEvents.add(eventId); - } + public void setErrorInReplay(Set errorInReplay) { + this.errorInReplay = errorInReplay; } - public void removeFromProcessedCC(String controlCommandId) { - if(StringUtils.isNotBlank(controlCommandId)){ - processedIds.remove(controlCommandId); - } + public Set getClearFromPending() { + return clearFromPending; + } + + public void setClearFromPending(Set clearFromPending) { + this.clearFromPending = clearFromPending; + } + + public Map>> getGeneratedEvent() { + return generatedEvent; } } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/ServletHelper.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/ServletHelper.java index 0a8e7d99d..7216e7140 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/ServletHelper.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/ServletHelper.java @@ -1,10 +1,7 @@ package com.newrelic.api.agent.security.instrumentation.helpers; import com.newrelic.api.agent.security.NewRelicSecurity; -import com.newrelic.api.agent.security.schema.APIRecordStatus; -import com.newrelic.api.agent.security.schema.K2RequestIdentifier; -import com.newrelic.api.agent.security.schema.SecurityMetaData; -import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.*; import com.newrelic.api.agent.security.utils.logging.LogLevel; import java.io.File; @@ -13,10 +10,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class ServletHelper { @@ -33,6 +27,7 @@ public class ServletHelper { public static final String SERVLET_GET_WRITER_OPERATION_LOCK = "SERVLET_GET_WRITER_OPERATION_LOCK-"; public static final String NR_SEC_HTTP_SESSION_ATTRIB_NAME = "NR-CSEC-HTTP-SESSION-"; public static final String NR_SEC_HTTP_SERVLET_RESPONSE_ATTRIB_NAME = "NR-CSEC-HTTP-SERVLET-RESPONSE-"; + public static final String SEPARATOR_COLON = ":"; private static Set filesToRemove = ConcurrentHashMap.newKeySet(); private static final Set unsupportedContentType = new HashSet() {{ @@ -83,7 +78,8 @@ public static K2RequestIdentifier parseFuzzRequestIdentifierHeader(String reques String[] data = StringUtils.splitByWholeSeparatorWorker(requestHeaderVal, SEPARATOR_SEMICOLON, -1, false); if (data.length >= 5) { - k2RequestIdentifierInstance.setApiRecordId(data[0].trim()); + k2RequestIdentifierInstance.setOriginEntityGuid(StringUtils.substringBefore(data[0].trim(), SEPARATOR_COLON)); + k2RequestIdentifierInstance.setApiRecordId(StringUtils.substringAfterLast(data[0].trim(), SEPARATOR_COLON)); k2RequestIdentifierInstance.setRefId(data[1].trim()); k2RequestIdentifierInstance.setRefValue(data[2].trim()); k2RequestIdentifierInstance.setNextStage(APIRecordStatus.valueOf(data[3].trim())); @@ -227,4 +223,31 @@ public static boolean isResponseContentTypeExcluded( String responseContentType) } return unsupportedContentType.contains(responseContentType); } + + public static FuzzRequestEmptyEntry iastDataRequestAddEmptyEntry(K2RequestIdentifier requestIdentifier, String traceHeader, String csecParentId) { + String originAppUUID = getOriginAppUUID(traceHeader); + requestIdentifier.setOriginApplicationUUID(originAppUUID); + return new FuzzRequestEmptyEntry(originAppUUID, requestIdentifier.getOriginEntityGuid(), csecParentId); + } + + private static String getOriginAppUUID(String traceHeader) { + if(StringUtils.isNotBlank(traceHeader)) { + return StringUtils.substringBefore(traceHeader, "/"); + } + return StringUtils.EMPTY; + } + + /** + * This method should be called only after parseFuzzRequestIdentifierHeader + * */ + public static String getTraceHeader(Map headers) { + String data = StringUtils.EMPTY; + if (headers.containsKey(CSEC_DISTRIBUTED_TRACING_HEADER) || headers.containsKey(CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase())) { + data = headers.get(CSEC_DISTRIBUTED_TRACING_HEADER); + if (data == null || data.trim().isEmpty()) { + data = headers.get(CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase()); + } + } + return data; + } } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/FuzzRequestEmptyEntry.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/FuzzRequestEmptyEntry.java new file mode 100644 index 000000000..e4a81b9fd --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/FuzzRequestEmptyEntry.java @@ -0,0 +1,40 @@ +package com.newrelic.api.agent.security.schema; + +public class FuzzRequestEmptyEntry { + + private String originAppUuid; + + private String originEntityGuid; + + private String controlCommandId; + + public FuzzRequestEmptyEntry(String originAppUuid, String originEntityGuid, String controlCommandId) { + this.originAppUuid = originAppUuid; + this.originEntityGuid = originEntityGuid; + this.controlCommandId = controlCommandId; + } + + public String getOriginAppUuid() { + return originAppUuid; + } + + public void setOriginAppUuid(String originAppUuid) { + this.originAppUuid = originAppUuid; + } + + public String getOriginEntityGuid() { + return originEntityGuid; + } + + public void setOriginEntityGuid(String originEntityGuid) { + this.originEntityGuid = originEntityGuid; + } + + public String getControlCommandId() { + return controlCommandId; + } + + public void setControlCommandId(String controlCommandId) { + this.controlCommandId = controlCommandId; + } +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/K2RequestIdentifier.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/K2RequestIdentifier.java index b690fb7f6..75dbec5db 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/K2RequestIdentifier.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/K2RequestIdentifier.java @@ -14,6 +14,10 @@ public class K2RequestIdentifier { private String refKey; private List tempFiles; + private String originApplicationUUID; + + private String originEntityGuid; + public K2RequestIdentifier() { k2Request = false; tempFiles = new ArrayList<>(); @@ -32,6 +36,8 @@ public K2RequestIdentifier(K2RequestIdentifier k2RequestIdentifierInstance) { this.tempFiles = new ArrayList<>(k2RequestIdentifierInstance.tempFiles); } this.raw = (StringUtils.isNotBlank(k2RequestIdentifierInstance.raw)) ? new String(k2RequestIdentifierInstance.raw) : null; + this.originApplicationUUID = (StringUtils.isNotBlank(k2RequestIdentifierInstance.originApplicationUUID)) ? new String(k2RequestIdentifierInstance.originApplicationUUID) : null; + this.originEntityGuid = (StringUtils.isNotBlank(k2RequestIdentifierInstance.originEntityGuid)) ? new String(k2RequestIdentifierInstance.originEntityGuid) : null; } public String getRefId() { @@ -111,4 +117,20 @@ public String getRefKey() { public void setRefKey(String refKey) { this.refKey = refKey; } + + public String getOriginApplicationUUID() { + return originApplicationUUID; + } + + public void setOriginApplicationUUID(String originApplicationUUID) { + this.originApplicationUUID = originApplicationUUID; + } + + public String getOriginEntityGuid() { + return originEntityGuid; + } + + public void setOriginEntityGuid(String originEntityGuid) { + this.originEntityGuid = originEntityGuid; + } } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/RequestCategory.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/RequestCategory.java new file mode 100644 index 000000000..216de5910 --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/RequestCategory.java @@ -0,0 +1,9 @@ +package com.newrelic.api.agent.security.schema; + +public enum RequestCategory { + + HTTP, + + GRPC; + +}