From 8d61c7366d33147214dafb4059c63dba8a59b437 Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Sat, 27 Jan 2024 12:41:59 +0530 Subject: [PATCH 01/44] gRPC: API endpoint detection for v1.4.0+ --- .../grpc/BindableService_Instrumentation.java | 24 +++++++++++++++++++ .../grpc/BindableService_Instrumentation.java | 24 +++++++++++++++++++ .../grpc/BindableService_Instrumentation.java | 24 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/BindableService_Instrumentation.java create mode 100644 instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/BindableService_Instrumentation.java create mode 100644 instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/BindableService_Instrumentation.java diff --git a/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/BindableService_Instrumentation.java b/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/BindableService_Instrumentation.java new file mode 100644 index 000000000..b813e5293 --- /dev/null +++ b/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/BindableService_Instrumentation.java @@ -0,0 +1,24 @@ +package io.grpc; + +import com.newrelic.api.agent.security.instrumentation.helpers.URLMappingsHelper; +import com.newrelic.api.agent.security.schema.ApplicationURLMapping; +import com.newrelic.api.agent.weaver.MatchType; +import com.newrelic.api.agent.weaver.Weave; +import com.newrelic.api.agent.weaver.Weaver; + +@Weave(originalName = "io.grpc.BindableService", type = MatchType.Interface) +public class BindableService_Instrumentation { + public ServerServiceDefinition bindService() { + ServerServiceDefinition returnValue = Weaver.callOriginal(); + + String handler = this.getClass().getName(); + for (ServerMethodDefinition serverMethod : returnValue.getMethods()) { + MethodDescriptor methodDescriptor = serverMethod.getMethodDescriptor(); + String url = methodDescriptor.getFullMethodName(); + String methodType = methodDescriptor.getType().name(); + URLMappingsHelper.addApplicationURLMapping(new ApplicationURLMapping(methodType, url, handler)); + } + + return returnValue; + } +} diff --git a/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/BindableService_Instrumentation.java b/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/BindableService_Instrumentation.java new file mode 100644 index 000000000..b813e5293 --- /dev/null +++ b/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/BindableService_Instrumentation.java @@ -0,0 +1,24 @@ +package io.grpc; + +import com.newrelic.api.agent.security.instrumentation.helpers.URLMappingsHelper; +import com.newrelic.api.agent.security.schema.ApplicationURLMapping; +import com.newrelic.api.agent.weaver.MatchType; +import com.newrelic.api.agent.weaver.Weave; +import com.newrelic.api.agent.weaver.Weaver; + +@Weave(originalName = "io.grpc.BindableService", type = MatchType.Interface) +public class BindableService_Instrumentation { + public ServerServiceDefinition bindService() { + ServerServiceDefinition returnValue = Weaver.callOriginal(); + + String handler = this.getClass().getName(); + for (ServerMethodDefinition serverMethod : returnValue.getMethods()) { + MethodDescriptor methodDescriptor = serverMethod.getMethodDescriptor(); + String url = methodDescriptor.getFullMethodName(); + String methodType = methodDescriptor.getType().name(); + URLMappingsHelper.addApplicationURLMapping(new ApplicationURLMapping(methodType, url, handler)); + } + + return returnValue; + } +} diff --git a/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/BindableService_Instrumentation.java b/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/BindableService_Instrumentation.java new file mode 100644 index 000000000..b813e5293 --- /dev/null +++ b/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/BindableService_Instrumentation.java @@ -0,0 +1,24 @@ +package io.grpc; + +import com.newrelic.api.agent.security.instrumentation.helpers.URLMappingsHelper; +import com.newrelic.api.agent.security.schema.ApplicationURLMapping; +import com.newrelic.api.agent.weaver.MatchType; +import com.newrelic.api.agent.weaver.Weave; +import com.newrelic.api.agent.weaver.Weaver; + +@Weave(originalName = "io.grpc.BindableService", type = MatchType.Interface) +public class BindableService_Instrumentation { + public ServerServiceDefinition bindService() { + ServerServiceDefinition returnValue = Weaver.callOriginal(); + + String handler = this.getClass().getName(); + for (ServerMethodDefinition serverMethod : returnValue.getMethods()) { + MethodDescriptor methodDescriptor = serverMethod.getMethodDescriptor(); + String url = methodDescriptor.getFullMethodName(); + String methodType = methodDescriptor.getType().name(); + URLMappingsHelper.addApplicationURLMapping(new ApplicationURLMapping(methodType, url, handler)); + } + + return returnValue; + } +} From b1eee479e06a8da1a16ea6e3ab2396723b7111ce Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Sat, 27 Jan 2024 16:09:37 +0530 Subject: [PATCH 02/44] gRPC: added critical logging --- .../grpc/BindableService_Instrumentation.java | 20 +++++++++++++------ .../grpc/BindableService_Instrumentation.java | 20 +++++++++++++------ .../grpc/BindableService_Instrumentation.java | 20 +++++++++++++------ 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/BindableService_Instrumentation.java b/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/BindableService_Instrumentation.java index b813e5293..2b4be8dd3 100644 --- a/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/BindableService_Instrumentation.java +++ b/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/BindableService_Instrumentation.java @@ -1,7 +1,10 @@ package io.grpc; +import com.newrelic.agent.security.instrumentation.grpc1220.GrpcUtils; +import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.URLMappingsHelper; import com.newrelic.api.agent.security.schema.ApplicationURLMapping; +import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -11,12 +14,17 @@ public class BindableService_Instrumentation { public ServerServiceDefinition bindService() { ServerServiceDefinition returnValue = Weaver.callOriginal(); - String handler = this.getClass().getName(); - for (ServerMethodDefinition serverMethod : returnValue.getMethods()) { - MethodDescriptor methodDescriptor = serverMethod.getMethodDescriptor(); - String url = methodDescriptor.getFullMethodName(); - String methodType = methodDescriptor.getType().name(); - URLMappingsHelper.addApplicationURLMapping(new ApplicationURLMapping(methodType, url, handler)); + try { + String handler = this.getClass().getName(); + for (ServerMethodDefinition serverMethod : returnValue.getMethods()) { + MethodDescriptor methodDescriptor = serverMethod.getMethodDescriptor(); + String url = methodDescriptor.getFullMethodName(); + String methodType = methodDescriptor.getType().name(); + URLMappingsHelper.addApplicationURLMapping(new ApplicationURLMapping(methodType, url, handler)); + } + } catch (Exception e){ + String message = "Instrumentation library: %s , error while getting app endpoints : %s"; + NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(message, GrpcUtils.GRPC_1_22_0, e.getMessage()), e, this.getClass().getName()); } return returnValue; diff --git a/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/BindableService_Instrumentation.java b/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/BindableService_Instrumentation.java index b813e5293..edeafd068 100644 --- a/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/BindableService_Instrumentation.java +++ b/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/BindableService_Instrumentation.java @@ -1,7 +1,10 @@ package io.grpc; +import com.newrelic.agent.security.instrumentation.grpc140.GrpcUtils; +import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.URLMappingsHelper; import com.newrelic.api.agent.security.schema.ApplicationURLMapping; +import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -11,12 +14,17 @@ public class BindableService_Instrumentation { public ServerServiceDefinition bindService() { ServerServiceDefinition returnValue = Weaver.callOriginal(); - String handler = this.getClass().getName(); - for (ServerMethodDefinition serverMethod : returnValue.getMethods()) { - MethodDescriptor methodDescriptor = serverMethod.getMethodDescriptor(); - String url = methodDescriptor.getFullMethodName(); - String methodType = methodDescriptor.getType().name(); - URLMappingsHelper.addApplicationURLMapping(new ApplicationURLMapping(methodType, url, handler)); + try { + String handler = this.getClass().getName(); + for (ServerMethodDefinition serverMethod : returnValue.getMethods()) { + MethodDescriptor methodDescriptor = serverMethod.getMethodDescriptor(); + String url = methodDescriptor.getFullMethodName(); + String methodType = methodDescriptor.getType().name(); + URLMappingsHelper.addApplicationURLMapping(new ApplicationURLMapping(methodType, url, handler)); + } + } catch (Exception e){ + String message = "Instrumentation library: %s , error while getting app endpoints : %s"; + NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(message, GrpcUtils.GRPC_1_4_0, e.getMessage()), e, this.getClass().getName()); } return returnValue; diff --git a/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/BindableService_Instrumentation.java b/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/BindableService_Instrumentation.java index b813e5293..c1cb1f4e5 100644 --- a/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/BindableService_Instrumentation.java +++ b/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/BindableService_Instrumentation.java @@ -1,7 +1,10 @@ package io.grpc; +import com.newrelic.agent.security.instrumentation.grpc1400.GrpcUtils; +import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.URLMappingsHelper; import com.newrelic.api.agent.security.schema.ApplicationURLMapping; +import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -11,12 +14,17 @@ public class BindableService_Instrumentation { public ServerServiceDefinition bindService() { ServerServiceDefinition returnValue = Weaver.callOriginal(); - String handler = this.getClass().getName(); - for (ServerMethodDefinition serverMethod : returnValue.getMethods()) { - MethodDescriptor methodDescriptor = serverMethod.getMethodDescriptor(); - String url = methodDescriptor.getFullMethodName(); - String methodType = methodDescriptor.getType().name(); - URLMappingsHelper.addApplicationURLMapping(new ApplicationURLMapping(methodType, url, handler)); + try { + String handler = this.getClass().getName(); + for (ServerMethodDefinition serverMethod : returnValue.getMethods()) { + MethodDescriptor methodDescriptor = serverMethod.getMethodDescriptor(); + String url = methodDescriptor.getFullMethodName(); + String methodType = methodDescriptor.getType().name(); + URLMappingsHelper.addApplicationURLMapping(new ApplicationURLMapping(methodType, url, handler)); + } + } catch (Exception e){ + String message = "Instrumentation library: %s , error while getting app endpoints : %s"; + NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(message, GrpcUtils.GRPC_1_40_0, e.getMessage()), e, this.getClass().getName()); } return returnValue; From af4a26a1b59a4c1ce58ba760d412191256af770a Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Fri, 2 Aug 2024 11:29:35 +0530 Subject: [PATCH 03/44] Initial draft for IAST in restricted mode --- .../newrelic/agent/security/AgentConfig.java | 113 +- .../utils/InstrumentationUtils.java | 8 +- .../ControlCommandProcessor.java | 5 +- .../models/collectorconfig/AgentMode.java | 55 + .../schedulers/SchedulerHelper.java | 6 +- .../intcodeagent/utils/CronExpression.java | 1428 +++++++++++++++++ .../utils/RestrictionUtility.java | 340 ++++ .../intcodeagent/websocket/EventSendPool.java | 2 +- .../intcodeagent/websocket/WSClient.java | 10 +- .../agent/security/util/IUtilConstants.java | 15 + .../newrelic/api/agent/security/Agent.java | 52 +- .../agent/security/schema/HttpRequest.java | 62 + .../schema/annotations/JsonProperty.java | 14 + .../security/schema/policy/AccountInfo.java | 18 + .../schema/policy/HttpParameterLocation.java | 9 + .../security/schema/policy/IASTScan.java | 19 +- .../schema/policy/MappingParameters.java | 40 + .../security/schema/policy/RASPScan.java | 17 + .../schema/policy/RestrictionCriteria.java | 60 + .../security/schema/policy/ScanTime.java | 39 + .../schema/policy/SkipScanParameters.java | 52 + .../schema/policy/StrictMappings.java | 46 + .../schema/policy/VulnerabilityScan.java | 2 +- 23 files changed, 2384 insertions(+), 28 deletions(-) create mode 100644 newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/collectorconfig/AgentMode.java create mode 100644 newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/CronExpression.java create mode 100644 newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/annotations/JsonProperty.java create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/AccountInfo.java create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/HttpParameterLocation.java create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameters.java create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RASPScan.java create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanTime.java create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScanParameters.java create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/StrictMappings.java diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index af043606f..2fdec7789 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -1,16 +1,24 @@ package com.newrelic.agent.security; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.introspect.Annotated; +import com.fasterxml.jackson.databind.introspect.AnnotatedMember; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.newrelic.agent.security.instrumentator.os.OSVariables; import com.newrelic.agent.security.instrumentator.os.OsVariablesInstance; import com.newrelic.agent.security.instrumentator.utils.AgentUtils; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; +import com.newrelic.agent.security.intcodeagent.models.collectorconfig.AgentMode; +import com.newrelic.agent.security.intcodeagent.utils.CronExpression; +import com.newrelic.api.agent.security.schema.annotations.JsonIgnore; +import com.newrelic.api.agent.security.schema.annotations.JsonProperty; +import com.newrelic.api.agent.security.schema.policy.*; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.agent.security.intcodeagent.filelogging.LogWriter; import com.newrelic.agent.security.intcodeagent.models.collectorconfig.CollectorConfig; import com.newrelic.agent.security.intcodeagent.utils.CommonUtils; import com.newrelic.agent.security.util.IUtilConstants; import com.newrelic.api.agent.NewRelic; -import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import org.apache.commons.io.FileUtils; import org.apache.commons.io.comparator.LastModifiedFileComparator; import org.apache.commons.io.filefilter.FileFilterUtils; @@ -21,10 +29,11 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Collection; +import java.text.ParseException; +import java.time.Instant; +import java.util.*; -import static com.newrelic.agent.security.util.IUtilConstants.DIRECTORY_PERMISSION; +import static com.newrelic.agent.security.util.IUtilConstants.*; public class AgentConfig { @@ -38,6 +47,8 @@ public class AgentConfig { private String groupName; + private AgentMode agentMode; + private CollectorConfig config = new CollectorConfig(); private boolean isNRSecurityEnabled; @@ -49,7 +60,7 @@ public class AgentConfig { private AgentConfig(){ } - public void instantiate(){ + public long instantiate(){ //Set k2 home path try { boolean validHomePath = setK2HomePath(); @@ -68,6 +79,90 @@ public void instantiate(){ //Instantiation call please do not move or repeat this. osVariables = OsVariablesInstance.instantiate().getOsVariables(); + + instantiateAgentMode(groupName); + + return trigerIAST(); + } + + public long trigerIAST() { + if(agentMode.getIastScan().getEnabled() && agentMode.getIastScan().getRestricted()){ + long date = agentMode.getIastScan().getRestrictionCriteria().getScanTime().getNextScanTime().getTime(); + long currentTime = Instant.now().toEpochMilli(); + System.out.println("IAST is in restricted mode will start at "+date); + return date-currentTime; + } + return 0; + } + + private void instantiateAgentMode(String groupName) { + this.agentMode = new AgentMode(groupName); + switch (groupName){ + case IAST: + //this is default case which requires no changes + break; + case RASP: + readRaspConfig(); + break; + case IAST_RESTRICTED: + readIastRestrictedConfig(); + break; + default: + //this is default case which requires no changes + break; + } + + } + + private void readIastRestrictedConfig() { + this.agentMode.getIastScan().setRestricted(true); + RestrictionCriteria restrictionCriteria = this.agentMode.getIastScan().getRestrictionCriteria(); + restrictionCriteria.setAccountInfo(new AccountInfo(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_ACCOUNT_INFO_ACCOUNT_ID))); + if(StringUtils.isBlank(restrictionCriteria.getAccountInfo().getAccountId())) { + //TODO raise error + + } + + restrictionCriteria.getScanTime().setDuration(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SCAN_TIME_DURATION, 5)); + restrictionCriteria.getScanTime().setSchedule(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SCAN_TIME_SCHEDULE, "0 0 2 * * MON")); + if(CronExpression.isValidExpression(restrictionCriteria.getScanTime().getSchedule())){ + try { + restrictionCriteria.getScanTime().setNextScanTime(new CronExpression(restrictionCriteria.getScanTime().getSchedule()).getTimeAfter(new Date())); + } catch (ParseException e) { + //TODO log error and set default scan time + } + } else { + //TODO raise error + } + + //Mapping parameters + List> mappingParameters = NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS, Collections.emptyList()); + ObjectMapper mapper = new ObjectMapper(); + mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() { + + }); + for (Map mappingParameter : mappingParameters) { + MappingParameters matchingCriteria = new MappingParameters(HttpParameterLocation.valueOf(mappingParameter.get("account_id_location")), mappingParameter.get("account_id_key")); +// MappingParameters matchingCriteria = mapper.convertValue(mappingParameter, MappingParameters.class); + restrictionCriteria.getMappingParameters().add(matchingCriteria); + } + //Skip Scan Parameters + restrictionCriteria.getSkipScanParameters().setBody(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_BODY, Collections.emptyList())); + restrictionCriteria.getSkipScanParameters().setHeader(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_HEADER, Collections.emptyList())); + restrictionCriteria.getSkipScanParameters().setQuery(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_QUERY, Collections.emptyList())); + + //Strict Criteria + List> strictCriteria = NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_STRICT, Collections.emptyList()); + for (Map strictCriterion : strictCriteria) { + StrictMappings matchingCriteria = mapper.convertValue(strictCriterion, StrictMappings.class); + restrictionCriteria.getStrictMappings().add(matchingCriteria); + } + + } + + private void readRaspConfig() { + this.agentMode.getIastScan().setEnabled(false); + this.agentMode.getRaspScan().setEnabled(true); } private static final class InstanceHolder { @@ -164,6 +259,10 @@ public void setConfig(CollectorConfig config) { this.config = config; } + public String getLogLevel() { + return logLevel; + } + public void createSnapshotDirectory() throws IOException { Path snapshotDir = Paths.get(osVariables.getSnapshotDir()); // Remove any file with this name from target. @@ -207,4 +306,8 @@ public void setNRSecurityEnabled(boolean NRSecurityEnabled) { public String getK2Home() { return NR_CSEC_HOME; } + + public AgentMode getAgentMode() { + return agentMode; + } } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/InstrumentationUtils.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/InstrumentationUtils.java index 0cf9bb752..c97777b98 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/InstrumentationUtils.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/InstrumentationUtils.java @@ -5,6 +5,7 @@ import com.newrelic.agent.security.instrumentator.os.OsVariablesInstance; import com.newrelic.agent.security.intcodeagent.controlcommand.ControlCommandProcessorThreadPool; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; +import com.newrelic.agent.security.intcodeagent.schedulers.FileCleaner; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.agent.security.intcodeagent.logging.HealthCheckScheduleThread; import com.newrelic.agent.security.intcodeagent.logging.IAgentConstants; @@ -13,6 +14,7 @@ import com.newrelic.agent.security.intcodeagent.websocket.WSClient; import com.newrelic.agent.security.intcodeagent.websocket.WSReconnectionST; import org.apache.commons.io.FileUtils; +import org.java_websocket.framing.CloseFrame; import java.io.File; import java.util.concurrent.TimeUnit; @@ -47,7 +49,7 @@ public class InstrumentationUtils { private static Boolean IAST = false; - public static void shutdownLogic(boolean doResetInstrumentation) { + public static void shutdownLogic() { // System.out.println("K2 Collector's shutdown hooked called."); // AgentUtils.getInstance().setAgentActive(false); try { @@ -67,13 +69,13 @@ public static void shutdownLogic(boolean doResetInstrumentation) { } catch (Throwable e) { } try { -// ServletEventPool.getInstance().shutDownThreadPoolExecutor(); HealthCheckScheduleThread.getInstance().cancelTask(true); -// EventThreadPool.getInstance().shutDownThreadPoolExecutor(); DispatcherPool.shutDownPool(); ControlCommandProcessorThreadPool.shutDownPool(); EventSendPool.shutDownPool(); WSReconnectionST.shutDownPool(); + WSClient.shutDownWSClient(true, CloseFrame.NORMAL, "IAST agent shutting down"); + FileCleaner.cancelTask(); FileUtils.deleteQuietly(new File(OsVariablesInstance.getInstance().getOsVariables().getTmpDirectory())); } catch (Throwable e) { 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 f66a634d4..3113cf3d5 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 @@ -12,7 +12,6 @@ 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; @@ -107,13 +106,13 @@ public void run() { switch (controlCommand.getControlCommand()) { case IntCodeControlCommand.SHUTDOWN_LANGUAGE_AGENT: - InstrumentationUtils.shutdownLogic(true); + InstrumentationUtils.shutdownLogic(); break; case IntCodeControlCommand.UNSUPPORTED_AGENT: logger.log(LogLevel.SEVERE, controlCommand.getArguments().get(0), ControlCommandProcessor.class.getSimpleName()); System.err.println(controlCommand.getArguments().get(0)); - InstrumentationUtils.shutdownLogic(true); + InstrumentationUtils.shutdownLogic(); break; case IntCodeControlCommand.SEND_POLICY_PARAMETERS: diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/collectorconfig/AgentMode.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/collectorconfig/AgentMode.java new file mode 100644 index 000000000..6f24cc64f --- /dev/null +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/collectorconfig/AgentMode.java @@ -0,0 +1,55 @@ +package com.newrelic.agent.security.intcodeagent.models.collectorconfig; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.newrelic.agent.security.intcodeagent.websocket.JsonConverter; +import com.newrelic.api.agent.security.schema.policy.IASTScan; +import com.newrelic.api.agent.security.schema.policy.RASPScan; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder(alphabetic = true) +public class AgentMode { + + private String mode; + + private IASTScan iastScan; + + private RASPScan raspScan; + + public AgentMode() {} + + public AgentMode(String mode) { + this.mode = mode; + iastScan = new IASTScan(); + raspScan = new RASPScan(); + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public IASTScan getIastScan() { + return iastScan; + } + + public void setIastScan(IASTScan iastScan) { + this.iastScan = iastScan; + } + + public RASPScan getRaspScan() { + return raspScan; + } + + public void setRaspScan(RASPScan raspScan) { + this.raspScan = raspScan; + } + + @Override + public String toString() { + return JsonConverter.toJSON(this); + } +} diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java index a68025e68..8568a08a1 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java @@ -1,6 +1,5 @@ package com.newrelic.agent.security.intcodeagent.schedulers; -import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.agent.security.intcodeagent.filelogging.LogFileHelper; import com.newrelic.agent.security.intcodeagent.logging.IAgentConstants; import com.newrelic.agent.security.util.IUtilConstants; @@ -11,7 +10,6 @@ import java.util.concurrent.atomic.AtomicInteger; public class SchedulerHelper { - private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); private final ScheduledExecutorService commonExecutor; @@ -39,6 +37,10 @@ public static SchedulerHelper getInstance() { private final Map> scheduledFutureMap = new ConcurrentHashMap<>(); + public ScheduledFuture scheduleIastTrigger(Runnable runnable, long initialDelay, TimeUnit unit) { + return commonExecutor.schedule(runnable, initialDelay, unit); + } + public ScheduledFuture scheduleHealthCheck(Runnable command, long initialDelay, long period, diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/CronExpression.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/CronExpression.java new file mode 100644 index 000000000..07d44d370 --- /dev/null +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/CronExpression.java @@ -0,0 +1,1428 @@ +package com.newrelic.agent.security.intcodeagent.utils; + +import java.text.ParseException; +import java.util.*; + +public class CronExpression { + + protected static final int SECOND = 0; + protected static final int MINUTE = 1; + protected static final int HOUR = 2; + protected static final int DAY_OF_MONTH = 3; + protected static final int MONTH = 4; + protected static final int DAY_OF_WEEK = 5; + protected static final int YEAR = 6; + protected static final int ALL_SPEC_INT = 99; // '*' + protected static final int NO_SPEC_INT = 98; // '?' + protected static final Integer ALL_SPEC = ALL_SPEC_INT; + protected static final Integer NO_SPEC = NO_SPEC_INT; + + protected static final Map monthMap = new HashMap(20); + protected static final Map dayMap = new HashMap(60); + static { + monthMap.put("JAN", 0); + monthMap.put("FEB", 1); + monthMap.put("MAR", 2); + monthMap.put("APR", 3); + monthMap.put("MAY", 4); + monthMap.put("JUN", 5); + monthMap.put("JUL", 6); + monthMap.put("AUG", 7); + monthMap.put("SEP", 8); + monthMap.put("OCT", 9); + monthMap.put("NOV", 10); + monthMap.put("DEC", 11); + + dayMap.put("SUN", 1); + dayMap.put("MON", 2); + dayMap.put("TUE", 3); + dayMap.put("WED", 4); + dayMap.put("THU", 5); + dayMap.put("FRI", 6); + dayMap.put("SAT", 7); + } + + private final String cronExpression; + private TimeZone timeZone = null; + protected transient TreeSet seconds; + protected transient TreeSet minutes; + protected transient TreeSet hours; + protected transient TreeSet daysOfMonth; + protected transient TreeSet months; + protected transient TreeSet daysOfWeek; + protected transient TreeSet years; + + protected transient boolean lastdayOfWeek = false; + protected transient int nthdayOfWeek = 0; + protected transient boolean lastdayOfMonth = false; + protected transient boolean nearestWeekday = false; + protected transient int lastdayOffset = 0; + protected transient boolean expressionParsed = false; + + public static final int MAX_YEAR = Calendar.getInstance().get(Calendar.YEAR) + 100; + + public CronExpression(String cronExpression) throws ParseException { + this.cronExpression = cronExpression.toUpperCase(Locale.US); + + buildExpression(this.cronExpression); + } + + /** + * Indicates whether the given date satisfies the cron expression. Note that + * milliseconds are ignored, so two Dates falling on different milliseconds + * of the same second will always have the same result here. + * + * @param date the date to evaluate + * @return a boolean indicating whether the given date satisfies the cron + * expression + */ + public boolean isSatisfiedBy(Date date) { + Calendar testDateCal = Calendar.getInstance(getTimeZone()); + testDateCal.setTime(date); + testDateCal.set(Calendar.MILLISECOND, 0); + Date originalDate = testDateCal.getTime(); + + testDateCal.add(Calendar.SECOND, -1); + + Date timeAfter = getTimeAfter(testDateCal.getTime()); + + return ((timeAfter != null) && (timeAfter.equals(originalDate))); + } + + /** + * Returns the next date/time after the given date/time which + * satisfies the cron expression. + * + * @param date the date/time at which to begin the search for the next valid + * date/time + * @return the next valid date/time + */ + public Date getNextValidTimeAfter(Date date) { + return getTimeAfter(date); + } + + /** + * Returns the next date/time after the given date/time which does + * not satisfy the expression + * + * @param date the date/time at which to begin the search for the next + * invalid date/time + * @return the next valid date/time + */ + public Date getNextInvalidTimeAfter(Date date) { + long difference = 1000; + + //move back to the nearest second so differences will be accurate + Calendar adjustCal = Calendar.getInstance(getTimeZone()); + adjustCal.setTime(date); + adjustCal.set(Calendar.MILLISECOND, 0); + Date lastDate = adjustCal.getTime(); + + Date newDate; + + //FUTURE_TODO: (QUARTZ-481) IMPROVE THIS! The following is a BAD solution to this problem. Performance will be very bad here, depending on the cron expression. It is, however A solution. + + //keep getting the next included time until it's farther than one second + // apart. At that point, lastDate is the last valid fire time. We return + // the second immediately following it. + while (difference == 1000) { + newDate = getTimeAfter(lastDate); + if(newDate == null) + break; + + difference = newDate.getTime() - lastDate.getTime(); + + if (difference == 1000) { + lastDate = newDate; + } + } + + return new Date(lastDate.getTime() + 1000); + } + + /** + * Returns the time zone for which this CronExpression + * will be resolved. + */ + public TimeZone getTimeZone() { + if (timeZone == null) { + timeZone = TimeZone.getDefault(); + } + + return timeZone; + } + + /** + * Sets the time zone for which this CronExpression + * will be resolved. + */ + public void setTimeZone(TimeZone timeZone) { + this.timeZone = timeZone; + } + + /** + * Returns the string representation of the CronExpression + * + * @return a string representation of the CronExpression + */ + @Override + public String toString() { + return cronExpression; + } + + /** + * Indicates whether the specified cron expression can be parsed into a + * valid cron expression + * + * @param cronExpression the expression to evaluate + * @return a boolean indicating whether the given expression is a valid cron + * expression + */ + public static boolean isValidExpression(String cronExpression) { + + try { + new CronExpression(cronExpression); + } catch (ParseException pe) { + return false; + } + + return true; + } + + public static void validateExpression(String cronExpression) throws ParseException { + + new CronExpression(cronExpression); + } + + + //////////////////////////////////////////////////////////////////////////// + // + // Expression Parsing Functions + // + //////////////////////////////////////////////////////////////////////////// + + protected void buildExpression(String expression) throws ParseException { + expressionParsed = true; + + try { + + if (seconds == null) { + seconds = new TreeSet(); + } + if (minutes == null) { + minutes = new TreeSet(); + } + if (hours == null) { + hours = new TreeSet(); + } + if (daysOfMonth == null) { + daysOfMonth = new TreeSet(); + } + if (months == null) { + months = new TreeSet(); + } + if (daysOfWeek == null) { + daysOfWeek = new TreeSet(); + } + if (years == null) { + years = new TreeSet(); + } + + int exprOn = SECOND; + + StringTokenizer exprsTok = new StringTokenizer(expression, " \t", + false); + + while (exprsTok.hasMoreTokens() && exprOn <= YEAR) { + String expr = exprsTok.nextToken().trim(); + + // throw an exception if L is used with other days of the month + if(exprOn == DAY_OF_MONTH && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) { + throw new ParseException("Support for specifying 'L' and 'LW' with other days of the month is not implemented", -1); + } + // throw an exception if L is used with other days of the week + if(exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) { + throw new ParseException("Support for specifying 'L' with other days of the week is not implemented", -1); + } + if(exprOn == DAY_OF_WEEK && expr.indexOf('#') != -1 && expr.indexOf('#', expr.indexOf('#') +1) != -1) { + throw new ParseException("Support for specifying multiple \"nth\" days is not implemented.", -1); + } + + StringTokenizer vTok = new StringTokenizer(expr, ","); + while (vTok.hasMoreTokens()) { + String v = vTok.nextToken(); + storeExpressionVals(0, v, exprOn); + } + + exprOn++; + } + + if (exprOn <= DAY_OF_WEEK) { + throw new ParseException("Unexpected end of expression.", + expression.length()); + } + + if (exprOn <= YEAR) { + storeExpressionVals(0, "*", YEAR); + } + + TreeSet dow = getSet(DAY_OF_WEEK); + TreeSet dom = getSet(DAY_OF_MONTH); + + // Copying the logic from the UnsupportedOperationException below + boolean dayOfMSpec = !dom.contains(NO_SPEC); + boolean dayOfWSpec = !dow.contains(NO_SPEC); + + if (!dayOfMSpec || dayOfWSpec) { + if (!dayOfWSpec || dayOfMSpec) { + throw new ParseException( + "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.", 0); + } + } + } catch (ParseException pe) { + throw pe; + } catch (Exception e) { + throw new ParseException("Illegal cron expression format (" + + e.toString() + ")", 0); + } + } + + protected int storeExpressionVals(int pos, String s, int type) + throws ParseException { + + int incr = 0; + int i = skipWhiteSpace(pos, s); + if (i >= s.length()) { + return i; + } + char c = s.charAt(i); + if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW")) && (!s.matches("^L-[0-9]*[W]?"))) { + String sub = s.substring(i, i + 3); + int sval = -1; + int eval = -1; + if (type == MONTH) { + sval = getMonthNumber(sub) + 1; + if (sval <= 0) { + throw new ParseException("Invalid Month value: '" + sub + "'", i); + } + if (s.length() > i + 3) { + c = s.charAt(i + 3); + if (c == '-') { + i += 4; + sub = s.substring(i, i + 3); + eval = getMonthNumber(sub) + 1; + if (eval <= 0) { + throw new ParseException("Invalid Month value: '" + sub + "'", i); + } + } + } + } else if (type == DAY_OF_WEEK) { + sval = getDayOfWeekNumber(sub); + if (sval < 0) { + throw new ParseException("Invalid Day-of-Week value: '" + + sub + "'", i); + } + if (s.length() > i + 3) { + c = s.charAt(i + 3); + if (c == '-') { + i += 4; + sub = s.substring(i, i + 3); + eval = getDayOfWeekNumber(sub); + if (eval < 0) { + throw new ParseException( + "Invalid Day-of-Week value: '" + sub + + "'", i); + } + } else if (c == '#') { + try { + i += 4; + nthdayOfWeek = Integer.parseInt(s.substring(i)); + if (nthdayOfWeek < 1 || nthdayOfWeek > 5) { + throw new Exception(); + } + } catch (Exception e) { + throw new ParseException( + "A numeric value between 1 and 5 must follow the '#' option", + i); + } + } else if (c == 'L') { + lastdayOfWeek = true; + i++; + } + } + + } else { + throw new ParseException( + "Illegal characters for this position: '" + sub + "'", + i); + } + if (eval != -1) { + incr = 1; + } + addToSet(sval, eval, incr, type); + return (i + 3); + } + + if (c == '?') { + i++; + if ((i + 1) < s.length() + && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\t')) { + throw new ParseException("Illegal character after '?': " + + s.charAt(i), i); + } + if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) { + throw new ParseException( + "'?' can only be specified for Day-of-Month or Day-of-Week.", + i); + } + if (type == DAY_OF_WEEK && !lastdayOfMonth) { + int val = daysOfMonth.last(); + if (val == NO_SPEC_INT) { + throw new ParseException( + "'?' can only be specified for Day-of-Month -OR- Day-of-Week.", + i); + } + } + + addToSet(NO_SPEC_INT, -1, 0, type); + return i; + } + + if (c == '*' || c == '/') { + if (c == '*' && (i + 1) >= s.length()) { + addToSet(ALL_SPEC_INT, -1, incr, type); + return i + 1; + } else if (c == '/' + && ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s + .charAt(i + 1) == '\t')) { + throw new ParseException("'/' must be followed by an integer.", i); + } else if (c == '*') { + i++; + } + c = s.charAt(i); + if (c == '/') { // is an increment specified? + i++; + if (i >= s.length()) { + throw new ParseException("Unexpected end of string.", i); + } + + incr = getNumericValue(s, i); + + i++; + if (incr > 10) { + i++; + } + checkIncrementRange(incr, type, i); + } else { + incr = 1; + } + + addToSet(ALL_SPEC_INT, -1, incr, type); + return i; + } else if (c == 'L') { + i++; + if (type == DAY_OF_MONTH) { + lastdayOfMonth = true; + } + if (type == DAY_OF_WEEK) { + addToSet(7, 7, 0, type); + } + if(type == DAY_OF_MONTH && s.length() > i) { + c = s.charAt(i); + if(c == '-') { + ValueSet vs = getValue(0, s, i+1); + lastdayOffset = vs.value; + if(lastdayOffset > 30) + throw new ParseException("Offset from last day must be <= 30", i+1); + i = vs.pos; + } + if(s.length() > i) { + c = s.charAt(i); + if(c == 'W') { + nearestWeekday = true; + i++; + } + } + } + return i; + } else if (c >= '0' && c <= '9') { + int val = Integer.parseInt(String.valueOf(c)); + i++; + if (i >= s.length()) { + addToSet(val, -1, -1, type); + } else { + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(val, s, i); + val = vs.value; + i = vs.pos; + } + i = checkNext(i, s, val, type); + return i; + } + } else { + throw new ParseException("Unexpected character: " + c, i); + } + + return i; + } + + private void checkIncrementRange(int incr, int type, int idxPos) throws ParseException { + if (incr > 59 && (type == SECOND || type == MINUTE)) { + throw new ParseException("Increment > 60 : " + incr, idxPos); + } else if (incr > 23 && (type == HOUR)) { + throw new ParseException("Increment > 24 : " + incr, idxPos); + } else if (incr > 31 && (type == DAY_OF_MONTH)) { + throw new ParseException("Increment > 31 : " + incr, idxPos); + } else if (incr > 7 && (type == DAY_OF_WEEK)) { + throw new ParseException("Increment > 7 : " + incr, idxPos); + } else if (incr > 12 && (type == MONTH)) { + throw new ParseException("Increment > 12 : " + incr, idxPos); + } + } + + protected int checkNext(int pos, String s, int val, int type) + throws ParseException { + + int end = -1; + int i = pos; + + if (i >= s.length()) { + addToSet(val, end, -1, type); + return i; + } + + char c = s.charAt(pos); + + if (c == 'L') { + if (type == DAY_OF_WEEK) { + if(val < 1 || val > 7) + throw new ParseException("Day-of-Week values must be between 1 and 7", -1); + lastdayOfWeek = true; + } else { + throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i); + } + TreeSet set = getSet(type); + set.add(val); + i++; + return i; + } + + if (c == 'W') { + if (type == DAY_OF_MONTH) { + nearestWeekday = true; + } else { + throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i); + } + if(val > 31) + throw new ParseException("The 'W' option does not make sense with values larger than 31 (max number of days in a month)", i); + TreeSet set = getSet(type); + set.add(val); + i++; + return i; + } + + if (c == '#') { + if (type != DAY_OF_WEEK) { + throw new ParseException("'#' option is not valid here. (pos=" + i + ")", i); + } + i++; + try { + nthdayOfWeek = Integer.parseInt(s.substring(i)); + if (nthdayOfWeek < 1 || nthdayOfWeek > 5) { + throw new Exception(); + } + } catch (Exception e) { + throw new ParseException( + "A numeric value between 1 and 5 must follow the '#' option", + i); + } + + TreeSet set = getSet(type); + set.add(val); + i++; + return i; + } + + if (c == '-') { + i++; + c = s.charAt(i); + int v = Integer.parseInt(String.valueOf(c)); + end = v; + i++; + if (i >= s.length()) { + addToSet(val, end, 1, type); + return i; + } + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(v, s, i); + end = vs.value; + i = vs.pos; + } + if (i < s.length() && ((c = s.charAt(i)) == '/')) { + i++; + c = s.charAt(i); + int v2 = Integer.parseInt(String.valueOf(c)); + i++; + if (i >= s.length()) { + addToSet(val, end, v2, type); + return i; + } + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(v2, s, i); + int v3 = vs.value; + addToSet(val, end, v3, type); + i = vs.pos; + return i; + } else { + addToSet(val, end, v2, type); + return i; + } + } else { + addToSet(val, end, 1, type); + return i; + } + } + + if (c == '/') { + if ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s.charAt(i + 1) == '\t') { + throw new ParseException("'/' must be followed by an integer.", i); + } + + i++; + c = s.charAt(i); + int v2 = Integer.parseInt(String.valueOf(c)); + i++; + if (i >= s.length()) { + checkIncrementRange(v2, type, i); + addToSet(val, end, v2, type); + return i; + } + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(v2, s, i); + int v3 = vs.value; + checkIncrementRange(v3, type, i); + addToSet(val, end, v3, type); + i = vs.pos; + return i; + } else { + throw new ParseException("Unexpected character '" + c + "' after '/'", i); + } + } + + addToSet(val, end, 0, type); + i++; + return i; + } + + public String getCronExpression() { + return cronExpression; + } + + public String getExpressionSummary() { + StringBuilder buf = new StringBuilder(); + + buf.append("seconds: "); + buf.append(getExpressionSetSummary(seconds)); + buf.append("\n"); + buf.append("minutes: "); + buf.append(getExpressionSetSummary(minutes)); + buf.append("\n"); + buf.append("hours: "); + buf.append(getExpressionSetSummary(hours)); + buf.append("\n"); + buf.append("daysOfMonth: "); + buf.append(getExpressionSetSummary(daysOfMonth)); + buf.append("\n"); + buf.append("months: "); + buf.append(getExpressionSetSummary(months)); + buf.append("\n"); + buf.append("daysOfWeek: "); + buf.append(getExpressionSetSummary(daysOfWeek)); + buf.append("\n"); + buf.append("lastdayOfWeek: "); + buf.append(lastdayOfWeek); + buf.append("\n"); + buf.append("nearestWeekday: "); + buf.append(nearestWeekday); + buf.append("\n"); + buf.append("NthDayOfWeek: "); + buf.append(nthdayOfWeek); + buf.append("\n"); + buf.append("lastdayOfMonth: "); + buf.append(lastdayOfMonth); + buf.append("\n"); + buf.append("years: "); + buf.append(getExpressionSetSummary(years)); + buf.append("\n"); + + return buf.toString(); + } + + protected String getExpressionSetSummary(Set set) { + + if (set.contains(NO_SPEC)) { + return "?"; + } + if (set.contains(ALL_SPEC)) { + return "*"; + } + + StringBuilder buf = new StringBuilder(); + + Iterator itr = set.iterator(); + boolean first = true; + while (itr.hasNext()) { + Integer iVal = itr.next(); + String val = iVal.toString(); + if (!first) { + buf.append(","); + } + buf.append(val); + first = false; + } + + return buf.toString(); + } + + protected String getExpressionSetSummary(ArrayList list) { + + if (list.contains(NO_SPEC)) { + return "?"; + } + if (list.contains(ALL_SPEC)) { + return "*"; + } + + StringBuilder buf = new StringBuilder(); + + Iterator itr = list.iterator(); + boolean first = true; + while (itr.hasNext()) { + Integer iVal = itr.next(); + String val = iVal.toString(); + if (!first) { + buf.append(","); + } + buf.append(val); + first = false; + } + + return buf.toString(); + } + + protected int skipWhiteSpace(int i, String s) { + for (; i < s.length() && (s.charAt(i) == ' ' || s.charAt(i) == '\t'); i++) { + ; + } + + return i; + } + + protected int findNextWhiteSpace(int i, String s) { + for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t'); i++) { + ; + } + + return i; + } + + protected void addToSet(int val, int end, int incr, int type) + throws ParseException { + + TreeSet set = getSet(type); + + if (type == SECOND || type == MINUTE) { + if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) { + throw new ParseException( + "Minute and Second values must be between 0 and 59", + -1); + } + } else if (type == HOUR) { + if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT)) { + throw new ParseException( + "Hour values must be between 0 and 23", -1); + } + } else if (type == DAY_OF_MONTH) { + if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT) + && (val != NO_SPEC_INT)) { + throw new ParseException( + "Day of month values must be between 1 and 31", -1); + } + } else if (type == MONTH) { + if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT)) { + throw new ParseException( + "Month values must be between 1 and 12", -1); + } + } else if (type == DAY_OF_WEEK) { + if ((val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT) + && (val != NO_SPEC_INT)) { + throw new ParseException( + "Day-of-Week values must be between 1 and 7", -1); + } + } + + if ((incr == 0 || incr == -1) && val != ALL_SPEC_INT) { + if (val != -1) { + set.add(val); + } else { + set.add(NO_SPEC); + } + + return; + } + + int startAt = val; + int stopAt = end; + + if (val == ALL_SPEC_INT && incr <= 0) { + incr = 1; + set.add(ALL_SPEC); // put in a marker, but also fill values + } + + if (type == SECOND || type == MINUTE) { + if (stopAt == -1) { + stopAt = 59; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 0; + } + } else if (type == HOUR) { + if (stopAt == -1) { + stopAt = 23; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 0; + } + } else if (type == DAY_OF_MONTH) { + if (stopAt == -1) { + stopAt = 31; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1; + } + } else if (type == MONTH) { + if (stopAt == -1) { + stopAt = 12; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1; + } + } else if (type == DAY_OF_WEEK) { + if (stopAt == -1) { + stopAt = 7; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1; + } + } else if (type == YEAR) { + if (stopAt == -1) { + stopAt = MAX_YEAR; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1970; + } + } + + // if the end of the range is before the start, then we need to overflow into + // the next day, month etc. This is done by adding the maximum amount for that + // type, and using modulus max to determine the value being added. + int max = -1; + if (stopAt < startAt) { + switch (type) { + case SECOND : max = 60; break; + case MINUTE : max = 60; break; + case HOUR : max = 24; break; + case MONTH : max = 12; break; + case DAY_OF_WEEK : max = 7; break; + case DAY_OF_MONTH : max = 31; break; + case YEAR : throw new IllegalArgumentException("Start year must be less than stop year"); + default : throw new IllegalArgumentException("Unexpected type encountered"); + } + stopAt += max; + } + + for (int i = startAt; i <= stopAt; i += incr) { + if (max == -1) { + // ie: there's no max to overflow over + set.add(i); + } else { + // take the modulus to get the real value + int i2 = i % max; + + // 1-indexed ranges should not include 0, and should include their max + if (i2 == 0 && (type == MONTH || type == DAY_OF_WEEK || type == DAY_OF_MONTH) ) { + i2 = max; + } + + set.add(i2); + } + } + } + + TreeSet getSet(int type) { + switch (type) { + case SECOND: + return seconds; + case MINUTE: + return minutes; + case HOUR: + return hours; + case DAY_OF_MONTH: + return daysOfMonth; + case MONTH: + return months; + case DAY_OF_WEEK: + return daysOfWeek; + case YEAR: + return years; + default: + return null; + } + } + + protected ValueSet getValue(int v, String s, int i) { + char c = s.charAt(i); + StringBuilder s1 = new StringBuilder(String.valueOf(v)); + while (c >= '0' && c <= '9') { + s1.append(c); + i++; + if (i >= s.length()) { + break; + } + c = s.charAt(i); + } + ValueSet val = new ValueSet(); + + val.pos = (i < s.length()) ? i : i + 1; + val.value = Integer.parseInt(s1.toString()); + return val; + } + + protected int getNumericValue(String s, int i) { + int endOfVal = findNextWhiteSpace(i, s); + String val = s.substring(i, endOfVal); + return Integer.parseInt(val); + } + + protected int getMonthNumber(String s) { + Integer integer = monthMap.get(s); + + if (integer == null) { + return -1; + } + + return integer; + } + + protected int getDayOfWeekNumber(String s) { + Integer integer = dayMap.get(s); + + if (integer == null) { + return -1; + } + + return integer; + } + + //////////////////////////////////////////////////////////////////////////// + // + // Computation Functions + // + //////////////////////////////////////////////////////////////////////////// + + public Date getTimeAfter(Date afterTime) { + + // Computation is based on Gregorian year only. + Calendar cl = new GregorianCalendar(getTimeZone()); + + // move ahead one second, since we're computing the time *after* the + // given time + afterTime = new Date(afterTime.getTime() + 1000); + // CronTrigger does not deal with milliseconds + cl.setTime(afterTime); + cl.set(Calendar.MILLISECOND, 0); + + boolean gotOne = false; + // loop until we've computed the next time, or we've past the endTime + while (!gotOne) { + + //if (endTime != null && cl.getTime().after(endTime)) return null; + if(cl.get(Calendar.YEAR) > 2999) { // prevent endless loop... + return null; + } + + SortedSet st = null; + int t = 0; + + int sec = cl.get(Calendar.SECOND); + int min = cl.get(Calendar.MINUTE); + + // get second................................................. + st = seconds.tailSet(sec); + if (st != null && st.size() != 0) { + sec = st.first(); + } else { + sec = seconds.first(); + min++; + cl.set(Calendar.MINUTE, min); + } + cl.set(Calendar.SECOND, sec); + + min = cl.get(Calendar.MINUTE); + int hr = cl.get(Calendar.HOUR_OF_DAY); + t = -1; + + // get minute................................................. + st = minutes.tailSet(min); + if (st != null && st.size() != 0) { + t = min; + min = st.first(); + } else { + min = minutes.first(); + hr++; + } + if (min != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, min); + setCalendarHour(cl, hr); + continue; + } + cl.set(Calendar.MINUTE, min); + + hr = cl.get(Calendar.HOUR_OF_DAY); + int day = cl.get(Calendar.DAY_OF_MONTH); + t = -1; + + // get hour................................................... + st = hours.tailSet(hr); + if (st != null && st.size() != 0) { + t = hr; + hr = st.first(); + } else { + hr = hours.first(); + day++; + } + if (hr != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + setCalendarHour(cl, hr); + continue; + } + cl.set(Calendar.HOUR_OF_DAY, hr); + + day = cl.get(Calendar.DAY_OF_MONTH); + int mon = cl.get(Calendar.MONTH) + 1; + // '+ 1' because calendar is 0-based for this field, and we are + // 1-based + t = -1; + int tmon = mon; + + // get day................................................... + boolean dayOfMSpec = !daysOfMonth.contains(NO_SPEC); + boolean dayOfWSpec = !daysOfWeek.contains(NO_SPEC); + if (dayOfMSpec && !dayOfWSpec) { // get day by day of month rule + st = daysOfMonth.tailSet(day); + if (lastdayOfMonth) { + if(!nearestWeekday) { + t = day; + day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + day -= lastdayOffset; + if(t > day) { + mon++; + if(mon > 12) { + mon = 1; + tmon = 3333; // ensure test of mon != tmon further below fails + cl.add(Calendar.YEAR, 1); + } + day = 1; + } + } else { + t = day; + day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + day -= lastdayOffset; + + Calendar tcal = Calendar.getInstance(getTimeZone()); + tcal.set(Calendar.SECOND, 0); + tcal.set(Calendar.MINUTE, 0); + tcal.set(Calendar.HOUR_OF_DAY, 0); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + tcal.set(Calendar.YEAR, cl.get(Calendar.YEAR)); + + int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + int dow = tcal.get(Calendar.DAY_OF_WEEK); + + if(dow == Calendar.SATURDAY && day == 1) { + day += 2; + } else if(dow == Calendar.SATURDAY) { + day -= 1; + } else if(dow == Calendar.SUNDAY && day == ldom) { + day -= 2; + } else if(dow == Calendar.SUNDAY) { + day += 1; + } + + tcal.set(Calendar.SECOND, sec); + tcal.set(Calendar.MINUTE, min); + tcal.set(Calendar.HOUR_OF_DAY, hr); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + Date nTime = tcal.getTime(); + if(nTime.before(afterTime)) { + day = 1; + mon++; + } + } + } else if(nearestWeekday) { + t = day; + day = daysOfMonth.first(); + + Calendar tcal = Calendar.getInstance(getTimeZone()); + tcal.set(Calendar.SECOND, 0); + tcal.set(Calendar.MINUTE, 0); + tcal.set(Calendar.HOUR_OF_DAY, 0); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + tcal.set(Calendar.YEAR, cl.get(Calendar.YEAR)); + + int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + int dow = tcal.get(Calendar.DAY_OF_WEEK); + + if(dow == Calendar.SATURDAY && day == 1) { + day += 2; + } else if(dow == Calendar.SATURDAY) { + day -= 1; + } else if(dow == Calendar.SUNDAY && day == ldom) { + day -= 2; + } else if(dow == Calendar.SUNDAY) { + day += 1; + } + + + tcal.set(Calendar.SECOND, sec); + tcal.set(Calendar.MINUTE, min); + tcal.set(Calendar.HOUR_OF_DAY, hr); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + Date nTime = tcal.getTime(); + if(nTime.before(afterTime)) { + day = daysOfMonth.first(); + mon++; + } + } else if (st != null && st.size() != 0) { + t = day; + day = st.first(); + // make sure we don't over-run a short month, such as february + int lastDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + if (day > lastDay) { + day = daysOfMonth.first(); + mon++; + } + } else { + day = daysOfMonth.first(); + mon++; + } + + if (day != t || mon != tmon) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, and we + // are 1-based + continue; + } + } else if (dayOfWSpec && !dayOfMSpec) { // get day by day of week rule + if (lastdayOfWeek) { // are we looking for the last XXX day of + // the month? + int dow = daysOfWeek.first(); // desired + // d-o-w + int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w + int daysToAdd = 0; + if (cDow < dow) { + daysToAdd = dow - cDow; + } + if (cDow > dow) { + daysToAdd = dow + (7 - cDow); + } + + int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + + if (day + daysToAdd > lDay) { // did we already miss the + // last one? + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon); + // no '- 1' here because we are promoting the month + continue; + } + + // find date of last occurrence of this day in this month... + while ((day + daysToAdd + 7) <= lDay) { + daysToAdd += 7; + } + + day += daysToAdd; + + if (daysToAdd > 0) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' here because we are not promoting the month + continue; + } + + } else if (nthdayOfWeek != 0) { + // are we looking for the Nth XXX day in the month? + int dow = daysOfWeek.first(); // desired + // d-o-w + int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w + int daysToAdd = 0; + if (cDow < dow) { + daysToAdd = dow - cDow; + } else if (cDow > dow) { + daysToAdd = dow + (7 - cDow); + } + + boolean dayShifted = false; + if (daysToAdd > 0) { + dayShifted = true; + } + + day += daysToAdd; + int weekOfMonth = day / 7; + if (day % 7 > 0) { + weekOfMonth++; + } + + daysToAdd = (nthdayOfWeek - weekOfMonth) * 7; + day += daysToAdd; + if (daysToAdd < 0 + || day > getLastDayOfMonth(mon, cl + .get(Calendar.YEAR))) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon); + // no '- 1' here because we are promoting the month + continue; + } else if (daysToAdd > 0 || dayShifted) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' here because we are NOT promoting the month + continue; + } + } else { + int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w + int dow = daysOfWeek.first(); // desired + // d-o-w + st = daysOfWeek.tailSet(cDow); + if (st != null && st.size() > 0) { + dow = st.first(); + } + + int daysToAdd = 0; + if (cDow < dow) { + daysToAdd = dow - cDow; + } + if (cDow > dow) { + daysToAdd = dow + (7 - cDow); + } + + int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + + if (day + daysToAdd > lDay) { // will we pass the end of + // the month? + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon); + // no '- 1' here because we are promoting the month + continue; + } else if (daysToAdd > 0) { // are we swithing days? + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day + daysToAdd); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, + // and we are 1-based + continue; + } + } + } else { // dayOfWSpec && !dayOfMSpec + throw new UnsupportedOperationException( + "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented."); + } + cl.set(Calendar.DAY_OF_MONTH, day); + + mon = cl.get(Calendar.MONTH) + 1; + // '+ 1' because calendar is 0-based for this field, and we are + // 1-based + int year = cl.get(Calendar.YEAR); + t = -1; + + // test for expressions that never generate a valid fire date, + // but keep looping... + if (year > MAX_YEAR) { + return null; + } + + // get month................................................... + st = months.tailSet(mon); + if (st != null && st.size() != 0) { + t = mon; + mon = st.first(); + } else { + mon = months.first(); + year++; + } + if (mon != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, and we are + // 1-based + cl.set(Calendar.YEAR, year); + continue; + } + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, and we are + // 1-based + + year = cl.get(Calendar.YEAR); + t = -1; + + // get year................................................... + st = years.tailSet(year); + if (st != null && st.size() != 0) { + t = year; + year = st.first(); + } else { + return null; // ran out of years... + } + + if (year != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, 0); + // '- 1' because calendar is 0-based for this field, and we are + // 1-based + cl.set(Calendar.YEAR, year); + continue; + } + cl.set(Calendar.YEAR, year); + + gotOne = true; + } // while( !done ) + + return cl.getTime(); + } + + /** + * Advance the calendar to the particular hour paying particular attention + * to daylight saving problems. + * + * @param cal the calendar to operate on + * @param hour the hour to set + */ + protected void setCalendarHour(Calendar cal, int hour) { + cal.set(Calendar.HOUR_OF_DAY, hour); + if (cal.get(Calendar.HOUR_OF_DAY) != hour && hour != 24) { + cal.set(Calendar.HOUR_OF_DAY, hour + 1); + } + } + + /** + * NOT YET IMPLEMENTED: Returns the time before the given time + * that the CronExpression matches. + */ + public Date getTimeBefore(Date endTime) { + // FUTURE_TODO: implement QUARTZ-423 + return null; + } + + /** + * NOT YET IMPLEMENTED: Returns the final time that the + * CronExpression will match. + */ + public Date getFinalFireTime() { + // FUTURE_TODO: implement QUARTZ-423 + return null; + } + + protected boolean isLeapYear(int year) { + return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)); + } + + protected int getLastDayOfMonth(int monthNum, int year) { + + switch (monthNum) { + case 1: + return 31; + case 2: + return (isLeapYear(year)) ? 29 : 28; + case 3: + return 31; + case 4: + return 30; + case 5: + return 31; + case 6: + return 30; + case 7: + return 31; + case 8: + return 31; + case 9: + return 30; + case 10: + return 31; + case 11: + return 30; + case 12: + return 31; + default: + throw new IllegalArgumentException("Illegal month number: " + + monthNum); + } + } + + + private void readObject(java.io.ObjectInputStream stream) + throws java.io.IOException, ClassNotFoundException { + + stream.defaultReadObject(); + try { + buildExpression(cronExpression); + } catch (Exception ignore) { + } // never happens + } + +} + +class ValueSet { + public int value; + + public int pos; +} + diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java new file mode 100644 index 000000000..f674f602e --- /dev/null +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java @@ -0,0 +1,340 @@ +package com.newrelic.agent.security.intcodeagent.utils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; +import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; +import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.policy.MappingParameters; +import com.newrelic.api.agent.security.schema.policy.RestrictionCriteria; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.StringReader; +import java.util.*; + +public class RestrictionUtility { + + public static final String SEPARATOR_CHARS_QUESTION_MARK = "?"; + public static final String SEPARATOR_CHARS_SEMICOLON = ";"; + public static final String FORWARD_SLASH = "/"; + public static final String AND = "&"; + public static final String SEPARATOR_EQUALS = "="; + public static final String EQUAL = "="; + public static final String CONTENT_TYPE_TEXT_JSON = "text/json"; + public static final String CONTENT_TYPE_TEXT_XML = "text/xml"; + public static final String CONTENT_TYPE_APPLICATION_JSON = "application/json"; + public static final String CONTENT_TYPE_APPLICATION_XML = "application/xml"; + public static final String CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; + + private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); + + public static boolean hasValidAccountId(RestrictionCriteria restrictionCriteria, HttpRequest request) { + String accountId = restrictionCriteria.getAccountInfo().getAccountId(); + if (request == null) { + return false; + } + if(!request.isRequestParametersParsed()){ + parseHttpRequestParameters(request); + } + for (MappingParameters mappingParameter : restrictionCriteria.getMappingParameters()) { + boolean match = false; + switch (mappingParameter.getAccountIdLocation()) { + case QUERY: + List queryParameters = getQueryString(mappingParameter.getAccountIdKey(), request.getQueryParameters()); + match = matcher(accountId, queryParameters); + break; + case PATH: + match = matcher(accountId, request.getPathParameters()); + break; + case HEADER: + List headerValues = getHeaderParameters(mappingParameter.getAccountIdKey(), request.getRequestHeaderParameters()); + match = matcher(accountId, headerValues); + break; + case BODY: + List bodyValues = getBodyParameters(mappingParameter.getAccountIdKey(), request.getRequestBodyParameters()); + match = matcher(accountId, bodyValues); + break; + } + if(match){ + return true; + } + } + return false; + } + + private static List getBodyParameters(String accountId, Map> requestBodyParameters) { + if (requestBodyParameters == null || requestBodyParameters.isEmpty()) { + return Collections.emptyList(); + } + String lowerCaseAccountId = accountId.toLowerCase(); + return requestBodyParameters.get(lowerCaseAccountId); + } + + private static List getHeaderParameters(String accountId, Map> requestHeaderParameters) { + if (requestHeaderParameters == null || requestHeaderParameters.isEmpty()) { + return Collections.emptyList(); + } + String lowerCaseAccountId = accountId.toLowerCase(); + return requestHeaderParameters.get(lowerCaseAccountId); + } + + private static List getQueryString(String accountId, Map> queryParameters) { + if(queryParameters == null || queryParameters.isEmpty()) { + return Collections.emptyList(); + } + String lowerCaseAccountId = accountId.toLowerCase(); + return queryParameters.get(lowerCaseAccountId); + } + + private static boolean matcher(String accountId, List values) { + if(values == null || values.isEmpty() || StringUtils.isBlank(accountId)) { + return false; + } + String lowerCaseAccountId = accountId.toLowerCase(); + return values.contains(lowerCaseAccountId); + } + + private static void parseHttpRequestParameters(HttpRequest request) { + request.setPathParameters(parsePathParameters(StringUtils.substringBefore(request.getUrl(), + SEPARATOR_CHARS_QUESTION_MARK))); + request.setQueryParameters(parseQueryParameters(request.getUrl())); + request.setRequestHeaderParameters(parseRequestHeaders(request.getHeaders())); + request.setRequestBodyParameters(parseRequestBody(request.getBody(), request.getContentType(), request.getRequestBodyParameters())); + request.setRequestBodyParameters(parseRequestParameterMap(request.getParameterMap(), request.getRequestBodyParameters())); + request.setRequestParsed(true); + } + + private static Map> parseRequestParameterMap(Map parameterMap, Map> requestBodyParameters) { + if(parameterMap == null) { + return requestBodyParameters; + } + if(requestBodyParameters == null) { + requestBodyParameters = new HashMap<>(); + } + + for (Map.Entry entry : parameterMap.entrySet()) { + String key = entry.getKey(); + String[] values = entry.getValue(); + List valuesList = new ArrayList<>(); + for (String value : values) { + valuesList.add(StringUtils.lowerCase(value)); + } + if(requestBodyParameters.containsKey(key)){ + requestBodyParameters.get(key).addAll(valuesList); + } else { + requestBodyParameters.put(key, valuesList); + } + } + return requestBodyParameters; + } + + private static Map> parseRequestBody(StringBuilder body, String contentType, Map> requestBodyParameters) { + if(StringUtils.isBlank(body.toString())) { + return requestBodyParameters; + } + + if(requestBodyParameters == null) { + requestBodyParameters = new HashMap<>(); + } + + switch (contentType) { + case CONTENT_TYPE_APPLICATION_JSON: + case CONTENT_TYPE_TEXT_JSON: + requestBodyParameters.putAll(parseJsonRequestBody(body.toString())); + break; + case CONTENT_TYPE_APPLICATION_XML: + case CONTENT_TYPE_TEXT_XML: + requestBodyParameters.putAll(parseXmlRequestBody(body.toString())); + break; + case CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED: + requestBodyParameters.putAll(queryParamKeyValueGenerator(body.toString(),new HashMap<>())); + break; + default: + break; + } + return requestBodyParameters; + + } + + private static Map> parseXmlRequestBody(String body) { + //write logic to xml parsing + Map> requestBodyParameters = new HashMap<>(); + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(new InputSource(new StringReader(body))); + document.getDocumentElement().normalize(); + Element root = document.getDocumentElement(); + parseXmlNode(root, StringUtils.EMPTY, requestBodyParameters); + } catch (Exception e) { + // TODO: log error + } + return requestBodyParameters; + } + + private static void parseXmlNode(Node node, String baseKey, Map> requestBodyParameters) { + if (node.getNodeType() == Node.ELEMENT_NODE) { + Element element = (Element) node; + NodeList children = element.getChildNodes(); + String key = baseKey.isEmpty() ? element.getTagName() : baseKey + "." + element.getTagName(); + if (children.getLength() == 1 && children.item(0).getNodeType() == Node.TEXT_NODE) { + String value = children.item(0).getTextContent().trim(); + if (!value.isEmpty()) { + requestBodyParameters.computeIfAbsent(key, k -> new ArrayList<>()).add(value); + } + } else { + for (int i = 0; i < children.getLength(); i++) { + parseXmlNode(children.item(i), key, requestBodyParameters); + } + } + } + } + + private static Map> parseJsonRequestBody(String body) { + JsonNode node; + ObjectMapper mapper = new ObjectMapper(); + try { + node = mapper.readValue(body, JsonNode.class); + Map> requestBodyParameters = new HashMap<>(); + return parseJsonNode(node, StringUtils.EMPTY, requestBodyParameters); + } catch (JsonProcessingException e) { + //TODO log error + } + return Collections.emptyMap(); + + } + + private static Map> parseJsonNode(JsonNode node, String baseKey, Map> requestBodyParameters) { + if (node.isObject()) { + Iterator> iterator = node.fields(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + String key = entry.getKey(); + String base = getBase(baseKey, key); + JsonNode value = entry.getValue(); + if(value.isContainerNode()){ + parseJsonNode(value, base, requestBodyParameters); + } else if (StringUtils.isNotBlank(value.asText())) { + if(!requestBodyParameters.containsKey(base)){ + requestBodyParameters.put(base, new ArrayList<>()); + } + requestBodyParameters.get(base).add(value.asText()); + } + } + } else if (node.isArray()) { + ArrayNode arrayNode = (ArrayNode) node; + for (int i = 0; i < arrayNode.size(); i++) { + JsonNode jsonNode = arrayNode.get(i); + String base = getBase(baseKey, i); + if(jsonNode.isContainerNode()){ + parseJsonNode(jsonNode, base, requestBodyParameters); + } else if (StringUtils.isNotBlank(jsonNode.asText())) { + if(!requestBodyParameters.containsKey(base)){ + requestBodyParameters.put(base, new ArrayList<>()); + } + requestBodyParameters.get(base).add(jsonNode.asText()); + } + } + } + return requestBodyParameters; + } + + private static @NotNull String getBase(String baseKey, String key) { + if(StringUtils.isBlank(baseKey)){ + return key; + } + return baseKey + "." + key; + } + + private static @NotNull String getBase(String baseKey, int index) { + if(StringUtils.isBlank(baseKey)){ + return String.format("[%s]", index); + } + return String.format("%s[%s]", baseKey, index); + } + + private static Map> parseRequestHeaders(Map headers) { + Map> requestHeaderParameters = new HashMap<>(); + for (Map.Entry header : headers.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + putHeaderParameter(key, value, requestHeaderParameters); + if (StringUtils.containsAny(value, SEPARATOR_CHARS_SEMICOLON, EQUAL)) { + String[] headerKeyValues = value.split(SEPARATOR_CHARS_SEMICOLON); + for (int i = 0; i < headerKeyValues.length; i++) { + if (StringUtils.contains(headerKeyValues[i], EQUAL) + && !StringUtils.endsWith(headerKeyValues[i], EQUAL)) { + String headerKey = StringUtils.substringBefore(headerKeyValues[i], EQUAL).trim(); + String headerValue = StringUtils.substringAfter(headerKeyValues[i], EQUAL).trim(); + putHeaderParameter(headerKey, headerValue, requestHeaderParameters); + } else { + putHeaderParameter(key, headerKeyValues[i], requestHeaderParameters); + } + } + } + } + return requestHeaderParameters; + } + + private static void putHeaderParameter(String key, String value, Map> requestHeaderParameters) { + List headerValues = requestHeaderParameters.get(key); + if (headerValues == null) { + headerValues = new ArrayList<>(); + } + headerValues.add(StringUtils.lowerCase(value)); + headerValues.add(StringUtils.lowerCase(ServletHelper.urlDecode(value))); + requestHeaderParameters.put(key, headerValues); + } + + private static Map> parseQueryParameters(String url) { + Map> queryParameters = new HashMap<>(); + String query = StringUtils.substringAfter(url, SEPARATOR_CHARS_QUESTION_MARK); + if (StringUtils.isNotBlank(query)) { + queryParamKeyValueGenerator(query, queryParameters); + } else { + query = StringUtils.substringAfter(url, SEPARATOR_CHARS_SEMICOLON); + if (StringUtils.isNotBlank(query)) { + queryParamKeyValueGenerator(query, queryParameters); + } + } + return queryParameters; + } + + private static Map> queryParamKeyValueGenerator(String query, Map> queryParameters) { + String[] queryParams = StringUtils.split(query, AND); + for (String queryParam : queryParams) { + String key, value; + key = StringUtils.substringBefore(queryParam, SEPARATOR_EQUALS); + value = StringUtils.substringAfter(queryParam, SEPARATOR_EQUALS); + List values = new ArrayList<>(); + values.add(StringUtils.lowerCase(value)); + values.add(StringUtils.lowerCase(ServletHelper.urlDecode(value))); + queryParameters.put(key, values); + } + return queryParameters; + } + + private static List parsePathParameters(String uri) { + List pathParameters = new ArrayList<>(); + String requestPath = StringUtils.substringBefore(uri, + SEPARATOR_CHARS_SEMICOLON); + if(StringUtils.isNotBlank(requestPath)) { + String[] pathVariables = StringUtils.split(requestPath, FORWARD_SLASH); + for (String pathVariable : pathVariables) { + pathParameters.add(StringUtils.lowerCase(pathVariable)); + pathParameters.add(StringUtils.lowerCase(ServletHelper.urlDecode(pathVariable))); + } + } + return pathParameters; + } +} diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java index d940d5844..dcf24e7af 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java @@ -91,7 +91,7 @@ public void sendEvent(JavaAgentEventBean event) { AgentInfo.getInstance().getJaHealthCheck().incrementEventSendRejectionCount(); return; } - executor.submit(new EventSender(event)); + Future f = executor.submit(new EventSender(event)); AgentInfo.getInstance().getJaHealthCheck().incrementEventSentCount(); } 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 64f1ffcfd..09986e15b 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 @@ -347,16 +347,22 @@ public static WSClient reconnectWSClient() throws URISyntaxException, Interrupte return instance; } - public static void shutDownWSClient(boolean clean) { + public static void shutDownWSClientAbnormal(boolean clean) { logger.log(LogLevel.WARNING, "Disconnecting WS client forced by APM", WSClient.class.getName()); + shutDownWSClient(clean, CloseFrame.ABNORMAL_CLOSE, "Client disconnecting forced by APM"); + } + + public static void shutDownWSClient(boolean clean, int frame, String message) { + logger.log(LogLevel.WARNING, String.format("WebSocket Shutdown initiated with %s", frame), + WSClient.class.getName()); WSUtils.getInstance().setConnected(false); if(clean) { RestRequestThreadPool.getInstance().resetIASTProcessing(); GrpcClientRequestReplayHelper.getInstance().resetIASTProcessing(); } if (instance != null) { - instance.close(CloseFrame.ABNORMAL_CLOSE, "Client disconnecting forced by APM"); + instance.close(frame, message); } } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java index 8764c0b62..bec8860eb 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java @@ -6,6 +6,21 @@ public interface IUtilConstants { String RASP = "RASP"; String IAST = "IAST"; + String IAST_RESTRICTED = "IAST_RESTRICTED"; + + String RESTRICTION_CRITERIA_SCAN_TIME = "security.restriction_criteria.scan_time"; + String RESTRICTION_CRITERIA_SCAN_TIME_SCHEDULE = "security.restriction_criteria.scan_time.schedule"; + String RESTRICTION_CRITERIA_SCAN_TIME_DURATION = "security.restriction_criteria.scan_time.duration"; + String RESTRICTION_CRITERIA = "security.restriction_criteria"; + String RESTRICTION_CRITERIA_ACCOUNT_INFO_ACCOUNT_ID = "security.restriction_criteria.account_info.account_id"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS = "security.restriction_criteria.mapping_parameters"; + String RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS = "security.restriction_criteria.skip_scan_parameters"; + String RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_HEADER = "security.restriction_criteria.skip_scan_parameters.header"; + String RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_QUERY = "security.restriction_criteria.skip_scan_parameters.query"; + String RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_BODY = "security.restriction_criteria.skip_scan_parameters.body"; + String RESTRICTION_CRITERIA_STRICT = "security.restriction_criteria.strict"; + + String GROUP_NAME = "group-name"; String INFO = "INFO"; String K_2_LOG_LEVEL = "K2_LOG_LEVEL"; 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 ab468d430..3f1d40827 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 @@ -12,6 +12,7 @@ import com.newrelic.agent.security.intcodeagent.filelogging.LogFileHelper; import com.newrelic.agent.security.intcodeagent.models.javaagent.*; import com.newrelic.agent.security.intcodeagent.utils.EncryptorUtils; +import com.newrelic.agent.security.intcodeagent.utils.RestrictionUtility; import com.newrelic.agent.security.intcodeagent.utils.RuntimeErrorReporter; import com.newrelic.api.agent.security.instrumentation.helpers.*; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -29,8 +30,6 @@ import com.newrelic.api.agent.security.schema.operation.RXSSOperation; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -39,6 +38,7 @@ import java.net.HttpURLConnection; import java.net.URL; import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -92,7 +92,18 @@ private Agent(){ } private void initialise() { - // TODO: All the bring up tasks are to be performed here. + + if (!isInitialised()) { + config = AgentConfig.getInstance(); + info = AgentInfo.getInstance(); + } + long delay = config.instantiate(); + SchedulerHelper.getInstance().scheduleIastTrigger(this::triggerNrSecurity, delay, TimeUnit.MILLISECONDS); + } + + private void triggerNrSecurity() { + // All the bring up tasks are to be performed here. + /* * * 1. populate policy * 2. create application info @@ -101,11 +112,6 @@ private void initialise() { * */ //NOTE: The bellow call sequence is critical and dependent on each other - if (!isInitialised()) { - config = AgentConfig.getInstance(); - info = AgentInfo.getInstance(); - } - config.instantiate(); logger = FileLoggerThreadPool.getInstance(); logger.logInit( LogLevel.INFO, @@ -145,6 +151,24 @@ private void initialise() { populateApplicationTmpDir(); startK2Services(); info.agentStatTrigger(true); + //Schedule NR csec shutdown if required + scheduleShutdownTrigger(); + } + + private void scheduleShutdownTrigger() { + if(AgentConfig.getInstance().getAgentMode().getIastScan().getEnabled() && AgentConfig.getInstance().getAgentMode().getIastScan().getRestricted()){ + int duration = AgentConfig.getInstance().getAgentMode().getIastScan().getRestrictionCriteria().getScanTime().getDuration(); + Instant now = Instant.now(); + Instant shutdownInstant = now.plus(duration, ChronoUnit.HOURS); + long shutdownTime = shutdownInstant.getEpochSecond() - now.getEpochSecond(); + SchedulerHelper.getInstance().scheduleIastTrigger(this::IastRestrictedShutdown, shutdownTime, TimeUnit.SECONDS); + } + } + + private void IastRestrictedShutdown() { + InstrumentationUtils.shutdownLogic(); + long delay = config.trigerIAST(); + SchedulerHelper.getInstance().scheduleIastTrigger(this::triggerNrSecurity, delay, TimeUnit.MILLISECONDS); } private void populateApplicationTmpDir() { @@ -222,7 +246,7 @@ private void cancelActiveServiceTasks() { * policy * HealthCheck */ - WSClient.shutDownWSClient(false); + WSClient.shutDownWSClientAbnormal(false); HealthCheckScheduleThread.getInstance().cancelTask(true); FileCleaner.cancelTask(); @@ -245,9 +269,10 @@ private void deactivateSecurityServices(){ * 3. event pool * 4. HealthCheck **/ + InstrumentationUtils.shutdownLogic(); HealthCheckScheduleThread.getInstance().cancelTask(true); FileCleaner.cancelTask(); - WSClient.shutDownWSClient(true); + WSClient.shutDownWSClientAbnormal(true); WSReconnectionST.shutDownPool(); EventSendPool.shutDownPool(); } @@ -313,6 +338,13 @@ public void registerOperation(AbstractOperation operation) { return; } + if(AgentConfig.getInstance().getAgentMode().getIastScan().getEnabled() && AgentConfig.getInstance().getAgentMode().getIastScan().getRestricted()) { + if(!RestrictionUtility.hasValidAccountId(AgentConfig.getInstance().getAgentMode().getIastScan().getRestrictionCriteria(), securityMetaData.getRequest())){ + return; + } + logger.log(LogLevel.FINER, String.format("Valid event for iast restricted environment : %s", operation), Agent.class.getName()); + } + logIfIastScanForFirstTime(securityMetaData.getFuzzRequestIdentifier(), securityMetaData.getRequest()); setRequiredStackTrace(operation, securityMetaData); diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/HttpRequest.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/HttpRequest.java index 5b65ef0f6..82b30226d 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/HttpRequest.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/HttpRequest.java @@ -1,5 +1,7 @@ package com.newrelic.api.agent.security.schema; +import com.newrelic.api.agent.security.schema.annotations.JsonIgnore; + import java.nio.file.Paths; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -35,6 +37,21 @@ public class HttpRequest { private boolean isGrpc; private String route; + @JsonIgnore + private List pathParameters; + + @JsonIgnore + private Map> queryParameters; + + @JsonIgnore + private Map> requestHeaderParameters; + + @JsonIgnore + private Map> requestBodyParameters; + + @JsonIgnore + private boolean isRequestParametersParsed = false; + public HttpRequest() { this.clientIP = StringUtils.EMPTY; this.body = new StringBuilder(); @@ -67,6 +84,11 @@ public HttpRequest(HttpRequest servletInfo) { this.isRequestParsed = servletInfo.isRequestParsed; this.isGrpc = servletInfo.isGrpc; this.route = servletInfo.route; + this.pathParameterMap = servletInfo.pathParameterMap; + this.queryParameters = servletInfo.queryParameters; + this.requestHeaderParameters = servletInfo.requestHeaderParameters; + this.requestBodyParameters = servletInfo.requestBodyParameters; + this.isRequestParametersParsed = servletInfo.isRequestParametersParsed; } public String getMethod() { @@ -229,6 +251,46 @@ public void setRoute(String segment, boolean isAlreadyServlet) { this.route = Paths.get(this.route, formatedSegment).normalize().toString(); } } + + public List getPathParameters() { + return pathParameters; + } + + public void setPathParameters(List pathParameters) { + this.pathParameters = pathParameters; + } + + public Map> getQueryParameters() { + return queryParameters; + } + + public void setQueryParameters(Map> queryParameters) { + this.queryParameters = queryParameters; + } + + public Map> getRequestHeaderParameters() { + return requestHeaderParameters; + } + + public void setRequestHeaderParameters(Map> requestHeaderParameters) { + this.requestHeaderParameters = requestHeaderParameters; + } + + public Map> getRequestBodyParameters() { + return requestBodyParameters; + } + + public void setRequestBodyParameters(Map> requestBodyParameters) { + this.requestBodyParameters = requestBodyParameters; + } + + public boolean isRequestParametersParsed() { + return isRequestParametersParsed; + } + + public void setRequestParametersParsed(boolean requestParametersParsed) { + isRequestParametersParsed = requestParametersParsed; + } } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/annotations/JsonProperty.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/annotations/JsonProperty.java new file mode 100644 index 000000000..19c0e51ed --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/annotations/JsonProperty.java @@ -0,0 +1,14 @@ +package com.newrelic.api.agent.security.schema.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface JsonProperty { + + String value() default ""; + +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/AccountInfo.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/AccountInfo.java new file mode 100644 index 000000000..0d0e679ab --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/AccountInfo.java @@ -0,0 +1,18 @@ +package com.newrelic.api.agent.security.schema.policy; + +public class AccountInfo { + + private final String accountId; + + public AccountInfo() { + this.accountId = null; + } + + public AccountInfo(String accountId) { + this.accountId = accountId; + } + + public String getAccountId() { + return accountId; + } +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/HttpParameterLocation.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/HttpParameterLocation.java new file mode 100644 index 000000000..97b40ac87 --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/HttpParameterLocation.java @@ -0,0 +1,9 @@ +package com.newrelic.api.agent.security.schema.policy; + +public enum HttpParameterLocation { + + QUERY, + PATH, + HEADER, + BODY; +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java index f010cef9e..d5259effb 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java @@ -3,8 +3,10 @@ public class IASTScan { - private Boolean enabled = false; + private Boolean enabled = true; private Probing probing = new Probing(); + private Boolean restricted = false; + private RestrictionCriteria restrictionCriteria = new RestrictionCriteria(); /** * No args constructor for use in serialization @@ -36,4 +38,19 @@ public void setProbing(Probing probing) { this.probing = probing; } + public Boolean getRestricted() { + return restricted; + } + + public void setRestricted(Boolean restricted) { + this.restricted = restricted; + } + + public RestrictionCriteria getRestrictionCriteria() { + return restrictionCriteria; + } + + public void setRestrictionCriteria(RestrictionCriteria restrictionCriteria) { + this.restrictionCriteria = restrictionCriteria; + } } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameters.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameters.java new file mode 100644 index 000000000..2294265ba --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameters.java @@ -0,0 +1,40 @@ +package com.newrelic.api.agent.security.schema.policy; + +import com.newrelic.api.agent.security.schema.annotations.JsonProperty; + +public class MappingParameters { + + @JsonProperty("account_id_location") + private HttpParameterLocation accountIdLocation; + + @JsonProperty("account_id_key") + private String accountIdKey; + + public MappingParameters() { + } + + public MappingParameters(HttpParameterLocation accountIdLocation) { + this.accountIdLocation = accountIdLocation; + } + + public MappingParameters(HttpParameterLocation accountIdLocation, String accountIdKey) { + this.accountIdLocation = accountIdLocation; + this.accountIdKey = accountIdKey; + } + + public HttpParameterLocation getAccountIdLocation() { + return accountIdLocation; + } + + public void setAccountIdLocation(HttpParameterLocation accountIdLocation) { + this.accountIdLocation = accountIdLocation; + } + + public String getAccountIdKey() { + return accountIdKey; + } + + public void setAccountIdKey(String accountIdKey) { + this.accountIdKey = accountIdKey; + } +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RASPScan.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RASPScan.java new file mode 100644 index 000000000..d1d1e0f25 --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RASPScan.java @@ -0,0 +1,17 @@ +package com.newrelic.api.agent.security.schema.policy; + +public class RASPScan { + + private Boolean enabled = true; + + public RASPScan() { + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java new file mode 100644 index 000000000..7a9e227cb --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java @@ -0,0 +1,60 @@ +package com.newrelic.api.agent.security.schema.policy; + +import java.util.ArrayList; +import java.util.List; + +public class RestrictionCriteria { + + private ScanTime scanTime = new ScanTime(); + + private AccountInfo accountInfo = new AccountInfo(); + + private List mappingParameters = new ArrayList<>(); + + private SkipScanParameters skipScanParameters = new SkipScanParameters(); + + private List strictMappings = new ArrayList<>(); + + public RestrictionCriteria() { + } + + public ScanTime getScanTime() { + return scanTime; + } + + public void setScanTime(ScanTime scanTime) { + this.scanTime = scanTime; + } + + public AccountInfo getAccountInfo() { + return accountInfo; + } + + public void setAccountInfo(AccountInfo accountInfo) { + this.accountInfo = accountInfo; + } + + public List getMappingParameters() { + return mappingParameters; + } + + public void setMappingParameters(List mappingParameters) { + this.mappingParameters = mappingParameters; + } + + public SkipScanParameters getSkipScanParameters() { + return skipScanParameters; + } + + public void setSkipScanParameters(SkipScanParameters skipScanParameters) { + this.skipScanParameters = skipScanParameters; + } + + public List getStrictMappings() { + return strictMappings; + } + + public void setStrictMappings(List strictMappings) { + this.strictMappings = strictMappings; + } +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanTime.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanTime.java new file mode 100644 index 000000000..dd5d8901f --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanTime.java @@ -0,0 +1,39 @@ +package com.newrelic.api.agent.security.schema.policy; + +import java.util.Date; + +public class ScanTime { + + private int duration; + + private String schedule; + + private Date nextScanTime; + + public ScanTime() { + } + + public int getDuration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public String getSchedule() { + return schedule; + } + + public void setSchedule(String schedule) { + this.schedule = schedule; + } + + public Date getNextScanTime() { + return nextScanTime; + } + + public void setNextScanTime(Date nextScanTime) { + this.nextScanTime = nextScanTime; + } +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScanParameters.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScanParameters.java new file mode 100644 index 000000000..3338c9d84 --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScanParameters.java @@ -0,0 +1,52 @@ +package com.newrelic.api.agent.security.schema.policy; + +import java.util.ArrayList; +import java.util.List; + +public class SkipScanParameters { + + private List header = new ArrayList<>(); + + private List query = new ArrayList<>(); + + private List body = new ArrayList<>(); + + public SkipScanParameters() { + } + + public List getHeader() { + return header; + } + + public List getQuery() { + return query; + } + + public List getBody() { + return body; + } + + public void setHeader(List header) { + this.header = header; + } + + public void setQuery(List query) { + this.query = query; + } + + public void setBody(List body) { + this.body = body; + } + + public void addHeader(String header) { + this.header.add(header); + } + + public void addQuery(String query) { + this.query.add(query); + } + + public void addBody(String body) { + this.body.add(body); + } +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/StrictMappings.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/StrictMappings.java new file mode 100644 index 000000000..8b26f1238 --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/StrictMappings.java @@ -0,0 +1,46 @@ +package com.newrelic.api.agent.security.schema.policy; + +import java.util.regex.Pattern; + +public class StrictMappings { + + private String route; + + private HttpParameterLocation accountIdLocation; + + private String accountIdKey; + + private Pattern routePattern; + + public StrictMappings() { + } + + public String getRoute() { + return route; + } + + public void setRoute(String route) { + this.route = route; + this.routePattern = Pattern.compile(route); + } + + public HttpParameterLocation getAccountIdLocation() { + return accountIdLocation; + } + + public void setAccountIdLocation(HttpParameterLocation accountIdLocation) { + this.accountIdLocation = accountIdLocation; + } + + public String getAccountIdKey() { + return accountIdKey; + } + + public void setAccountIdKey(String accountIdKey) { + this.accountIdKey = accountIdKey; + } + + public Pattern getRoutePattern() { + return routePattern; + } +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/VulnerabilityScan.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/VulnerabilityScan.java index 2aad4d717..1a36bf327 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/VulnerabilityScan.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/VulnerabilityScan.java @@ -3,7 +3,7 @@ public class VulnerabilityScan { - private Boolean enabled = false; + private Boolean enabled = true; private IASTScan iastScan = new IASTScan(); private Boolean enableHooks = false; From 965fd359362d9b5a1de734a3087c844a7e7f1e77 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 8 Aug 2024 10:25:40 +0530 Subject: [PATCH 04/44] Restriction mode error handling Add capability to allow multiple test account IDs --- .../newrelic/agent/security/AgentConfig.java | 44 ++++++++++------- .../exceptions/RestrictionModeException.java | 20 ++++++++ .../utils/RestrictionUtility.java | 48 ++++++++++++------- .../agent/security/util/IUtilConstants.java | 2 +- .../security/schema/policy/AccountInfo.java | 21 +++++--- 5 files changed, 93 insertions(+), 42 deletions(-) create mode 100644 newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/exceptions/RestrictionModeException.java diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index 2fdec7789..bc8826697 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -1,17 +1,14 @@ package com.newrelic.agent.security; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.introspect.Annotated; -import com.fasterxml.jackson.databind.introspect.AnnotatedMember; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.newrelic.agent.security.instrumentator.os.OSVariables; import com.newrelic.agent.security.instrumentator.os.OsVariablesInstance; import com.newrelic.agent.security.instrumentator.utils.AgentUtils; +import com.newrelic.agent.security.intcodeagent.exceptions.RestrictionModeException; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.agent.security.intcodeagent.models.collectorconfig.AgentMode; import com.newrelic.agent.security.intcodeagent.utils.CronExpression; -import com.newrelic.api.agent.security.schema.annotations.JsonIgnore; -import com.newrelic.api.agent.security.schema.annotations.JsonProperty; import com.newrelic.api.agent.security.schema.policy.*; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.agent.security.intcodeagent.filelogging.LogWriter; @@ -32,6 +29,7 @@ import java.text.ParseException; import java.time.Instant; import java.util.*; +import java.util.logging.Level; import static com.newrelic.agent.security.util.IUtilConstants.*; @@ -86,11 +84,17 @@ public long instantiate(){ } public long trigerIAST() { - if(agentMode.getIastScan().getEnabled() && agentMode.getIastScan().getRestricted()){ - long date = agentMode.getIastScan().getRestrictionCriteria().getScanTime().getNextScanTime().getTime(); - long currentTime = Instant.now().toEpochMilli(); - System.out.println("IAST is in restricted mode will start at "+date); - return date-currentTime; + try { + if(agentMode.getIastScan().getEnabled() && agentMode.getIastScan().getRestricted()){ + long date = agentMode.getIastScan().getRestrictionCriteria().getScanTime().getNextScanTime().getTime(); + long currentTime = Instant.now().toEpochMilli(); + return date-currentTime; + } + } catch (Exception e){ + //TODO send notice error + System.err.println("[NR-CSEC-JA] Error while calculating next scan time for IAST Restricted Mode. IAST Restricted Mode will be disabled."); + NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while calculating next scan time for IAST Restricted Mode. IAST Restricted Mode will be disabled."); + return Long.MAX_VALUE; } return 0; } @@ -105,7 +109,14 @@ private void instantiateAgentMode(String groupName) { readRaspConfig(); break; case IAST_RESTRICTED: - readIastRestrictedConfig(); + try { + readIastRestrictedConfig(); + } catch (RestrictionModeException e) { + System.err.println("[NR-CSEC-JA] Error while reading IAST Restricted Mode Configuration. IAST Restricted Mode will be disabled."); + NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Restricted Mode Configuration. IAST Restricted Mode will be disabled."); + //TODO Send Notice Error + this.agentMode.getIastScan().setEnabled(false); + } break; default: //this is default case which requires no changes @@ -114,25 +125,24 @@ private void instantiateAgentMode(String groupName) { } - private void readIastRestrictedConfig() { + private void readIastRestrictedConfig() throws RestrictionModeException { this.agentMode.getIastScan().setRestricted(true); RestrictionCriteria restrictionCriteria = this.agentMode.getIastScan().getRestrictionCriteria(); restrictionCriteria.setAccountInfo(new AccountInfo(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_ACCOUNT_INFO_ACCOUNT_ID))); - if(StringUtils.isBlank(restrictionCriteria.getAccountInfo().getAccountId())) { - //TODO raise error - + if(restrictionCriteria.getAccountInfo().isEmpty()) { + throw new RestrictionModeException("Account ID is required for IAST Restricted Mode"); } restrictionCriteria.getScanTime().setDuration(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SCAN_TIME_DURATION, 5)); - restrictionCriteria.getScanTime().setSchedule(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SCAN_TIME_SCHEDULE, "0 0 2 * * MON")); + restrictionCriteria.getScanTime().setSchedule(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SCAN_TIME_SCHEDULE, "0 0 0 * * ?")); if(CronExpression.isValidExpression(restrictionCriteria.getScanTime().getSchedule())){ try { restrictionCriteria.getScanTime().setNextScanTime(new CronExpression(restrictionCriteria.getScanTime().getSchedule()).getTimeAfter(new Date())); } catch (ParseException e) { - //TODO log error and set default scan time + throw new RestrictionModeException("Invalid cron expression provided for IAST Restricted Mode", e); } } else { - //TODO raise error + throw new RestrictionModeException("Invalid cron expression provided for IAST Restricted Mode"); } //Mapping parameters diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/exceptions/RestrictionModeException.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/exceptions/RestrictionModeException.java new file mode 100644 index 000000000..488c19da7 --- /dev/null +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/exceptions/RestrictionModeException.java @@ -0,0 +1,20 @@ +package com.newrelic.agent.security.intcodeagent.exceptions; + +public class RestrictionModeException extends Exception { + + public RestrictionModeException() { + super(); + } + + public RestrictionModeException(String message) { + super(message); + } + + public RestrictionModeException(String message, Throwable cause) { + super(message, cause); + } + + public RestrictionModeException(Throwable cause) { + super(cause); + } +} \ No newline at end of file diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java index f674f602e..07b3a9609 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java @@ -4,11 +4,13 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; +import com.newrelic.agent.security.intcodeagent.exceptions.RestrictionModeException; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.HttpRequest; import com.newrelic.api.agent.security.schema.policy.MappingParameters; import com.newrelic.api.agent.security.schema.policy.RestrictionCriteria; +import com.newrelic.api.agent.security.utils.logging.LogLevel; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.w3c.dom.Document; @@ -39,7 +41,7 @@ public class RestrictionUtility { private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); public static boolean hasValidAccountId(RestrictionCriteria restrictionCriteria, HttpRequest request) { - String accountId = restrictionCriteria.getAccountInfo().getAccountId(); + List accountIds = restrictionCriteria.getAccountInfo().getAccountIds(); if (request == null) { return false; } @@ -51,18 +53,18 @@ public static boolean hasValidAccountId(RestrictionCriteria restrictionCriteria, switch (mappingParameter.getAccountIdLocation()) { case QUERY: List queryParameters = getQueryString(mappingParameter.getAccountIdKey(), request.getQueryParameters()); - match = matcher(accountId, queryParameters); + match = matcher(accountIds, queryParameters); break; case PATH: - match = matcher(accountId, request.getPathParameters()); + match = matcher(accountIds, request.getPathParameters()); break; case HEADER: List headerValues = getHeaderParameters(mappingParameter.getAccountIdKey(), request.getRequestHeaderParameters()); - match = matcher(accountId, headerValues); + match = matcher(accountIds, headerValues); break; case BODY: List bodyValues = getBodyParameters(mappingParameter.getAccountIdKey(), request.getRequestBodyParameters()); - match = matcher(accountId, bodyValues); + match = matcher(accountIds, bodyValues); break; } if(match){ @@ -96,12 +98,18 @@ private static List getQueryString(String accountId, Map values) { - if(values == null || values.isEmpty() || StringUtils.isBlank(accountId)) { - return false; + private static boolean matcher(List accountIds, List values) { + for (String accountId : accountIds) { + if(values == null || values.isEmpty() || StringUtils.isBlank(accountId)) { + continue; + } + String lowerCaseAccountId = accountId.toLowerCase(); + boolean contains = values.contains(lowerCaseAccountId); + if(contains){ + return true; + } } - String lowerCaseAccountId = accountId.toLowerCase(); - return values.contains(lowerCaseAccountId); + return false; } private static void parseHttpRequestParameters(HttpRequest request) { @@ -109,7 +117,11 @@ private static void parseHttpRequestParameters(HttpRequest request) { SEPARATOR_CHARS_QUESTION_MARK))); request.setQueryParameters(parseQueryParameters(request.getUrl())); request.setRequestHeaderParameters(parseRequestHeaders(request.getHeaders())); - request.setRequestBodyParameters(parseRequestBody(request.getBody(), request.getContentType(), request.getRequestBodyParameters())); + try { + request.setRequestBodyParameters(parseRequestBody(request.getBody(), request.getContentType(), request.getRequestBodyParameters())); + } catch (RestrictionModeException e) { + logger.log(LogLevel.WARNING, String.format("Request Body parsing failed reason %s", e.getMessage()), RestrictionUtility.class.getName()); + } request.setRequestBodyParameters(parseRequestParameterMap(request.getParameterMap(), request.getRequestBodyParameters())); request.setRequestParsed(true); } @@ -138,7 +150,7 @@ private static Map> parseRequestParameterMap(Map> parseRequestBody(StringBuilder body, String contentType, Map> requestBodyParameters) { + private static Map> parseRequestBody(StringBuilder body, String contentType, Map> requestBodyParameters) throws RestrictionModeException { if(StringUtils.isBlank(body.toString())) { return requestBodyParameters; } @@ -166,7 +178,7 @@ private static Map> parseRequestBody(StringBuilder body, St } - private static Map> parseXmlRequestBody(String body) { + private static Map> parseXmlRequestBody(String body) throws RestrictionModeException { //write logic to xml parsing Map> requestBodyParameters = new HashMap<>(); try { @@ -177,7 +189,8 @@ private static Map> parseXmlRequestBody(String bod Element root = document.getDocumentElement(); parseXmlNode(root, StringUtils.EMPTY, requestBodyParameters); } catch (Exception e) { - // TODO: log error + logger.log(LogLevel.FINER, String.format("JSON Request Body parsing failed for %s : reason %s", body, e.getMessage()), RestrictionUtility.class.getName()); + throw new RestrictionModeException(String.format("XML Request Body parsing failed : reason %s", e.getMessage()), e); } return requestBodyParameters; } @@ -200,7 +213,7 @@ private static void parseXmlNode(Node node, String baseKey, Map> parseJsonRequestBody(String body) { + private static Map> parseJsonRequestBody(String body) throws RestrictionModeException { JsonNode node; ObjectMapper mapper = new ObjectMapper(); try { @@ -208,10 +221,9 @@ private static Map> parseJsonRequestBody(String bo Map> requestBodyParameters = new HashMap<>(); return parseJsonNode(node, StringUtils.EMPTY, requestBodyParameters); } catch (JsonProcessingException e) { - //TODO log error + logger.log(LogLevel.FINER, String.format("JSON Request Body parsing failed for %s : reason %s", body, e.getMessage()), RestrictionUtility.class.getName()); + throw new RestrictionModeException(String.format("JSON Request Body parsing failed : reason %s", e.getMessage())+ e.getMessage(), e); } - return Collections.emptyMap(); - } private static Map> parseJsonNode(JsonNode node, String baseKey, Map> requestBodyParameters) { diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java index bec8860eb..e32607c94 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java @@ -12,7 +12,7 @@ public interface IUtilConstants { String RESTRICTION_CRITERIA_SCAN_TIME_SCHEDULE = "security.restriction_criteria.scan_time.schedule"; String RESTRICTION_CRITERIA_SCAN_TIME_DURATION = "security.restriction_criteria.scan_time.duration"; String RESTRICTION_CRITERIA = "security.restriction_criteria"; - String RESTRICTION_CRITERIA_ACCOUNT_INFO_ACCOUNT_ID = "security.restriction_criteria.account_info.account_id"; + String RESTRICTION_CRITERIA_ACCOUNT_INFO_ACCOUNT_ID = "security.restriction_criteria.account_info.account_id_value"; String RESTRICTION_CRITERIA_MAPPING_PARAMETERS = "security.restriction_criteria.mapping_parameters"; String RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS = "security.restriction_criteria.skip_scan_parameters"; String RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_HEADER = "security.restriction_criteria.skip_scan_parameters.header"; diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/AccountInfo.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/AccountInfo.java index 0d0e679ab..5d79142b1 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/AccountInfo.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/AccountInfo.java @@ -1,18 +1,27 @@ package com.newrelic.api.agent.security.schema.policy; +import java.util.List; + public class AccountInfo { - private final String accountId; + private final List accountIds; public AccountInfo() { - this.accountId = null; + this.accountIds = null; + } + + public AccountInfo(List accountIds) { + this.accountIds = accountIds; } - public AccountInfo(String accountId) { - this.accountId = accountId; + public List getAccountIds() { + return accountIds; } - public String getAccountId() { - return accountId; + public boolean isEmpty() { + if(accountIds == null) { + return true; + } + return accountIds.isEmpty(); } } From 8ddf7660232d72b42ee589c197a6a56b1188d54a Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 8 Aug 2024 12:51:35 +0530 Subject: [PATCH 05/44] set default values for config default schedule will be at 12 AM everyday --- .../newrelic/agent/security/AgentConfig.java | 19 ++++++++++--------- .../schema/policy/StrictMappings.java | 7 +++++++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index bc8826697..53c3f4587 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -39,6 +39,11 @@ public class AgentConfig { public static final String AGENT_JAR_LOCATION = "agent_jar_location"; public static final String AGENT_HOME = "agent_home"; + public static final String INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE = "Invalid cron expression provided for IAST Restricted Mode"; + public static final String ACCOUNT_ID_IS_REQUIRED_FOR_IAST_RESTRICTED_MODE = "Account ID is required for IAST Restricted Mode"; + public static final String ACCOUNT_ID_LOCATION = "account_id_location"; + public static final String ACCOUNT_ID_KEY = "account_id_key"; + public static final String ROUTE = "route"; private String NR_CSEC_HOME; private String logLevel; @@ -130,7 +135,7 @@ private void readIastRestrictedConfig() throws RestrictionModeException { RestrictionCriteria restrictionCriteria = this.agentMode.getIastScan().getRestrictionCriteria(); restrictionCriteria.setAccountInfo(new AccountInfo(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_ACCOUNT_INFO_ACCOUNT_ID))); if(restrictionCriteria.getAccountInfo().isEmpty()) { - throw new RestrictionModeException("Account ID is required for IAST Restricted Mode"); + throw new RestrictionModeException(ACCOUNT_ID_IS_REQUIRED_FOR_IAST_RESTRICTED_MODE); } restrictionCriteria.getScanTime().setDuration(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SCAN_TIME_DURATION, 5)); @@ -139,20 +144,16 @@ private void readIastRestrictedConfig() throws RestrictionModeException { try { restrictionCriteria.getScanTime().setNextScanTime(new CronExpression(restrictionCriteria.getScanTime().getSchedule()).getTimeAfter(new Date())); } catch (ParseException e) { - throw new RestrictionModeException("Invalid cron expression provided for IAST Restricted Mode", e); + throw new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE, e); } } else { - throw new RestrictionModeException("Invalid cron expression provided for IAST Restricted Mode"); + throw new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE); } //Mapping parameters List> mappingParameters = NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS, Collections.emptyList()); - ObjectMapper mapper = new ObjectMapper(); - mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() { - - }); for (Map mappingParameter : mappingParameters) { - MappingParameters matchingCriteria = new MappingParameters(HttpParameterLocation.valueOf(mappingParameter.get("account_id_location")), mappingParameter.get("account_id_key")); + MappingParameters matchingCriteria = new MappingParameters(HttpParameterLocation.valueOf(mappingParameter.get(ACCOUNT_ID_LOCATION)), mappingParameter.get(ACCOUNT_ID_KEY)); // MappingParameters matchingCriteria = mapper.convertValue(mappingParameter, MappingParameters.class); restrictionCriteria.getMappingParameters().add(matchingCriteria); } @@ -164,7 +165,7 @@ private void readIastRestrictedConfig() throws RestrictionModeException { //Strict Criteria List> strictCriteria = NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_STRICT, Collections.emptyList()); for (Map strictCriterion : strictCriteria) { - StrictMappings matchingCriteria = mapper.convertValue(strictCriterion, StrictMappings.class); + StrictMappings matchingCriteria = new StrictMappings(strictCriterion.get(ROUTE), HttpParameterLocation.valueOf(strictCriterion.get(ACCOUNT_ID_LOCATION)), strictCriterion.get(ACCOUNT_ID_KEY)); restrictionCriteria.getStrictMappings().add(matchingCriteria); } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/StrictMappings.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/StrictMappings.java index 8b26f1238..0ea0669e7 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/StrictMappings.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/StrictMappings.java @@ -15,6 +15,13 @@ public class StrictMappings { public StrictMappings() { } + public StrictMappings(String route, HttpParameterLocation accountIdLocation, String accountIdKey) { + this.route = route; + this.accountIdLocation = accountIdLocation; + this.accountIdKey = accountIdKey; + this.routePattern = Pattern.compile(route); + } + public String getRoute() { return route; } From 79bb67167756824012aeea9bfd4dea5ed9a7ce23 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 8 Aug 2024 15:52:50 +0530 Subject: [PATCH 06/44] Send notice error on failure of IAST restriction config --- .../com/newrelic/agent/security/AgentConfig.java | 13 +++++++++++-- .../java/com/newrelic/api/agent/security/Agent.java | 7 +++++++ .../api/agent/security/schema/policy/RASPScan.java | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index 53c3f4587..57faaa6d8 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -9,6 +9,7 @@ import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.agent.security.intcodeagent.models.collectorconfig.AgentMode; import com.newrelic.agent.security.intcodeagent.utils.CronExpression; +import com.newrelic.api.agent.security.Agent; import com.newrelic.api.agent.security.schema.policy.*; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.agent.security.intcodeagent.filelogging.LogWriter; @@ -76,6 +77,7 @@ public long instantiate(){ isNRSecurityEnabled = NewRelic.getAgent().getConfig().getValue(IUtilConstants.NR_SECURITY_ENABLED, false); // Set required Group groupName = applyRequiredGroup(); + Agent.getCustomNoticeErrorParameters().put(IUtilConstants.SECURITY_MODE, groupName); // Enable low severity hooks // Set required LogLevel logLevel = applyRequiredLogLevel(); @@ -108,7 +110,7 @@ private void instantiateAgentMode(String groupName) { this.agentMode = new AgentMode(groupName); switch (groupName){ case IAST: - //this is default case which requires no changes + readIastConfig(); break; case RASP: readRaspConfig(); @@ -119,7 +121,7 @@ private void instantiateAgentMode(String groupName) { } catch (RestrictionModeException e) { System.err.println("[NR-CSEC-JA] Error while reading IAST Restricted Mode Configuration. IAST Restricted Mode will be disabled."); NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Restricted Mode Configuration. IAST Restricted Mode will be disabled."); - //TODO Send Notice Error + NewRelic.noticeError(e, Agent.getCustomNoticeErrorParameters(), true); this.agentMode.getIastScan().setEnabled(false); } break; @@ -130,8 +132,14 @@ private void instantiateAgentMode(String groupName) { } + private void readIastConfig() { + this.agentMode.getIastScan().setEnabled(true); + this.agentMode.getRaspScan().setEnabled(false); + } + private void readIastRestrictedConfig() throws RestrictionModeException { this.agentMode.getIastScan().setRestricted(true); + Agent.getCustomNoticeErrorParameters().put(IAST_RESTRICTED, String.valueOf(true)); RestrictionCriteria restrictionCriteria = this.agentMode.getIastScan().getRestrictionCriteria(); restrictionCriteria.setAccountInfo(new AccountInfo(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_ACCOUNT_INFO_ACCOUNT_ID))); if(restrictionCriteria.getAccountInfo().isEmpty()) { @@ -226,6 +234,7 @@ public boolean setK2HomePath() throws IOException { return false; } NR_CSEC_HOME = k2homePath.toString(); + Agent.getCustomNoticeErrorParameters().put(IUtilConstants.NR_SECURITY_HOME, NR_CSEC_HOME); AgentUtils.getInstance().getStatusLogValues().put("csec-home", NR_CSEC_HOME); AgentUtils.getInstance().getStatusLogValues().put("csec-home-permissions", String.valueOf(k2homePath.toFile().canWrite() && k2homePath.toFile().canRead())); AgentUtils.getInstance().getStatusLogValues().put("agent-location", agentJarLocation); 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 3f1d40827..3f729a4f7 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 @@ -43,6 +43,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; @@ -70,6 +71,8 @@ public class Agent implements SecurityAgent { private java.net.URL agentJarURL; private Instrumentation instrumentation; + private static final Map customNoticeErrorParameters = new ConcurrentHashMap<>(); + private static final class InstanceHolder { static final Agent instance = new Agent(); } @@ -91,6 +94,10 @@ private Agent(){ System.setProperty("org.slf4j.simpleLogger.logFile", "System.out"); } + public static Map getCustomNoticeErrorParameters() { + return customNoticeErrorParameters; + } + private void initialise() { if (!isInitialised()) { diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RASPScan.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RASPScan.java index d1d1e0f25..91c5cc09f 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RASPScan.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RASPScan.java @@ -2,7 +2,7 @@ public class RASPScan { - private Boolean enabled = true; + private Boolean enabled = false; public RASPScan() { } From 815009899a78abb0e2e18809414de50c83ce7a4f Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Fri, 9 Aug 2024 17:18:35 +0530 Subject: [PATCH 07/44] send skip scan parameter in each event --- .../newrelic/agent/security/AgentConfig.java | 21 +++++++++++++++++-- .../instrumentator/dispatcher/Dispatcher.java | 4 ++++ .../agent/security/schema/AgentMetaData.java | 18 ++++++++++++---- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index 57faaa6d8..f92150994 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -45,6 +45,7 @@ public class AgentConfig { public static final String ACCOUNT_ID_LOCATION = "account_id_location"; public static final String ACCOUNT_ID_KEY = "account_id_key"; public static final String ROUTE = "route"; + public static final String MAPPING_PARAMETERS_ARE_REQUIRED_FOR_IAST_RESTRICTED_MODE = "Mapping Parameters are required for IAST Restricted Mode"; private String NR_CSEC_HOME; private String logLevel; @@ -98,7 +99,7 @@ public long trigerIAST() { return date-currentTime; } } catch (Exception e){ - //TODO send notice error + NewRelic.noticeError(new RestrictionModeException("Error while calculating next scan time for IAST Restricted Mode", e), Agent.getCustomNoticeErrorParameters(), true); System.err.println("[NR-CSEC-JA] Error while calculating next scan time for IAST Restricted Mode. IAST Restricted Mode will be disabled."); NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while calculating next scan time for IAST Restricted Mode. IAST Restricted Mode will be disabled."); return Long.MAX_VALUE; @@ -118,11 +119,12 @@ private void instantiateAgentMode(String groupName) { case IAST_RESTRICTED: try { readIastRestrictedConfig(); + updateSkipScanParameters(); } catch (RestrictionModeException e) { System.err.println("[NR-CSEC-JA] Error while reading IAST Restricted Mode Configuration. IAST Restricted Mode will be disabled."); NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Restricted Mode Configuration. IAST Restricted Mode will be disabled."); NewRelic.noticeError(e, Agent.getCustomNoticeErrorParameters(), true); - this.agentMode.getIastScan().setEnabled(false); + AgentInfo.getInstance().agentStatTrigger(false); } break; default: @@ -132,6 +134,18 @@ private void instantiateAgentMode(String groupName) { } + private void updateSkipScanParameters() { + for (MappingParameters mappingParameter : this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters()) { + if(mappingParameter.getAccountIdLocation().equals(HttpParameterLocation.HEADER)){ + this.agentMode.getIastScan().getRestrictionCriteria().getSkipScanParameters().getHeader().add(mappingParameter.getAccountIdKey()); + } else if(mappingParameter.getAccountIdLocation().equals(HttpParameterLocation.QUERY)){ + this.agentMode.getIastScan().getRestrictionCriteria().getSkipScanParameters().getQuery().add(mappingParameter.getAccountIdKey()); + } else if(mappingParameter.getAccountIdLocation().equals(HttpParameterLocation.BODY)){ + this.agentMode.getIastScan().getRestrictionCriteria().getSkipScanParameters().getBody().add(mappingParameter.getAccountIdKey()); + } + } + } + private void readIastConfig() { this.agentMode.getIastScan().setEnabled(true); this.agentMode.getRaspScan().setEnabled(false); @@ -160,6 +174,9 @@ private void readIastRestrictedConfig() throws RestrictionModeException { //Mapping parameters List> mappingParameters = NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS, Collections.emptyList()); + if(mappingParameters.isEmpty()) { + throw new RestrictionModeException(MAPPING_PARAMETERS_ARE_REQUIRED_FOR_IAST_RESTRICTED_MODE); + } for (Map mappingParameter : mappingParameters) { MappingParameters matchingCriteria = new MappingParameters(HttpParameterLocation.valueOf(mappingParameter.get(ACCOUNT_ID_LOCATION)), mappingParameter.get(ACCOUNT_ID_KEY)); // MappingParameters matchingCriteria = mapper.convertValue(mappingParameter, MappingParameters.class); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java index 9aa06df9e..5766ea20b 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java @@ -1,6 +1,7 @@ package com.newrelic.agent.security.instrumentator.dispatcher; import com.google.gson.Gson; +import com.newrelic.agent.security.AgentConfig; import com.newrelic.agent.security.AgentInfo; import com.newrelic.agent.security.instrumentator.helper.DynamoDBRequestConverter; import com.newrelic.agent.security.instrumentator.utils.AgentUtils; @@ -720,6 +721,9 @@ private JavaAgentEventBean setGenericProperties(AbstractOperation objectBean, Ja private JavaAgentEventBean prepareEvent(HttpRequest httpRequestBean, AgentMetaData metaData, VulnerabilityCaseType vulnerabilityCaseType, K2RequestIdentifier k2RequestIdentifier) { + if(AgentConfig.getInstance().getAgentMode().getIastScan().getRestricted()) { + metaData.setSkipScanParameters(AgentConfig.getInstance().getAgentMode().getIastScan().getRestrictionCriteria().getSkipScanParameters()); + } JavaAgentEventBean eventBean = new JavaAgentEventBean(); eventBean.setHttpRequest(httpRequestBean); eventBean.setMetaData(metaData); diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/AgentMetaData.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/AgentMetaData.java index e7362aa95..dd35b63b0 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/AgentMetaData.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/AgentMetaData.java @@ -1,11 +1,9 @@ package com.newrelic.api.agent.security.schema; import com.newrelic.api.agent.security.schema.annotations.JsonIgnore; +import com.newrelic.api.agent.security.schema.policy.SkipScanParameters; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; public class AgentMetaData { @@ -26,6 +24,8 @@ public class AgentMetaData { private Map reflectedMetaData; + private SkipScanParameters skipScanParameters; + @JsonIgnore private StackTraceElement[] serviceTrace; @@ -56,6 +56,7 @@ public AgentMetaData() { this.reflectedMetaData = new HashMap<>(); this.appServerInfo = new AppServerInfo(); this.framework = StringUtils.EMPTY; + this.skipScanParameters = new SkipScanParameters(); } public AgentMetaData(AgentMetaData agentMetaData) { @@ -77,6 +78,7 @@ public AgentMetaData(AgentMetaData agentMetaData) { this.foundAnnotedUserLevelServiceMethod = agentMetaData.foundAnnotedUserLevelServiceMethod; this.fromJumpRequiredInStackTrace = agentMetaData.getFromJumpRequiredInStackTrace(); this.framework = agentMetaData.framework; + this.skipScanParameters = agentMetaData.skipScanParameters; } public boolean isTriggerViaRCI() { @@ -219,4 +221,12 @@ public void setFramework(Framework framework) { this.framework = framework.name(); } } + + public SkipScanParameters getSkipScanParameters() { + return skipScanParameters; + } + + public void setSkipScanParameters(SkipScanParameters skipScanParameters) { + this.skipScanParameters = skipScanParameters; + } } From 9ecfd771144fdd8864d1987371f6072a5c2fa7f0 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Wed, 14 Aug 2024 10:54:47 +0530 Subject: [PATCH 08/44] Adds Configuration for IAST_SCHEDULE and IAST_SCAN_IGNORE feature Implements IAST_SCHEDULE --- .../newrelic/agent/security/AgentConfig.java | 87 ++++++--- .../instrumentator/dispatcher/Dispatcher.java | 4 +- .../ControlCommandProcessor.java | 7 + .../models/collectorconfig/AgentMode.java | 24 +++ .../utils/RestrictionUtility.java | 23 +++ .../intcodeagent/websocket/WSClient.java | 1 + .../agent/security/util/IUtilConstants.java | 23 ++- .../newrelic/api/agent/security/Agent.java | 34 +++- .../newrelic/api/agent/security/Agent.java | 7 + .../api/agent/security/NoOpAgent.java | 7 + .../api/agent/security/SecurityAgent.java | 3 + .../instrumentation/helpers/FileHelper.java | 2 +- .../helpers/GenericHelper.java | 67 +++++++ .../instrumentation/helpers/JdbcHelper.java | 8 +- .../instrumentation/helpers/R2dbcHelper.java | 18 +- .../schema/policy/IastDetectionCategory.java | 167 ++++++++++++++++++ .../schema/policy/RestrictionCriteria.java | 10 +- .../{ScanTime.java => ScanSchedule.java} | 16 +- .../security/schema/policy/SkipScan.java | 55 ++++++ 19 files changed, 497 insertions(+), 66 deletions(-) create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java rename newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/{ScanTime.java => ScanSchedule.java} (71%) create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScan.java diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index f92150994..8aa440320 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -1,7 +1,5 @@ package com.newrelic.agent.security; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.newrelic.agent.security.instrumentator.os.OSVariables; import com.newrelic.agent.security.instrumentator.os.OsVariablesInstance; import com.newrelic.agent.security.instrumentator.utils.AgentUtils; @@ -30,6 +28,7 @@ import java.text.ParseException; import java.time.Instant; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; import static com.newrelic.agent.security.util.IUtilConstants.*; @@ -40,12 +39,13 @@ public class AgentConfig { public static final String AGENT_JAR_LOCATION = "agent_jar_location"; public static final String AGENT_HOME = "agent_home"; - public static final String INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE = "Invalid cron expression provided for IAST Restricted Mode"; + public static final String INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE = "Invalid cron expression provided for IAST Mode"; public static final String ACCOUNT_ID_IS_REQUIRED_FOR_IAST_RESTRICTED_MODE = "Account ID is required for IAST Restricted Mode"; public static final String ACCOUNT_ID_LOCATION = "account_id_location"; public static final String ACCOUNT_ID_KEY = "account_id_key"; public static final String ROUTE = "route"; public static final String MAPPING_PARAMETERS_ARE_REQUIRED_FOR_IAST_RESTRICTED_MODE = "Mapping Parameters are required for IAST Restricted Mode"; + public static final String DEFAULT_SCAN_SCHEDULE_EXPRESSION = "0 0 0 * * ?"; private String NR_CSEC_HOME; private String logLevel; @@ -88,15 +88,14 @@ public long instantiate(){ instantiateAgentMode(groupName); - return trigerIAST(); + return triggerIAST(); } - public long trigerIAST() { + public long triggerIAST() { try { - if(agentMode.getIastScan().getEnabled() && agentMode.getIastScan().getRestricted()){ - long date = agentMode.getIastScan().getRestrictionCriteria().getScanTime().getNextScanTime().getTime(); - long currentTime = Instant.now().toEpochMilli(); - return date-currentTime; + if(agentMode.getScanSchedule().getNextScanTime() != null) { + logger.log(LogLevel.FINER, "Security Agent scan time is set to : " + agentMode.getScanSchedule().getNextScanTime(), AgentConfig.class.getName()); + return agentMode.getScanSchedule().getNextScanTime().getTime() - Instant.now().toEpochMilli(); } } catch (Exception e){ NewRelic.noticeError(new RestrictionModeException("Error while calculating next scan time for IAST Restricted Mode", e), Agent.getCustomNoticeErrorParameters(), true); @@ -132,16 +131,63 @@ private void instantiateAgentMode(String groupName) { break; } + try { + readScanSchedule(); + } catch (RestrictionModeException e){ + System.err.println("[NR-CSEC-JA] Error while reading Scan Schedule Configuration. Security will be disabled."); + NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading Scan Schedule Configuration. Security will be disabled."); + NewRelic.noticeError(e, Agent.getCustomNoticeErrorParameters(), true); + AgentInfo.getInstance().agentStatTrigger(false); + } + readSkipScan(); + + } + + private void readSkipScan() { + agentMode.getSkipScan().setApis(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_API, Collections.emptyList())); + agentMode.getSkipScan().getParameters().setQuery(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_QUERY, Collections.emptyList())); + agentMode.getSkipScan().getParameters().setHeader(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_HEADER, Collections.emptyList())); + agentMode.getSkipScan().getParameters().setBody(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_BODY, Collections.emptyList())); + agentMode.getSkipScan().getIastDetectionCategory().setInsecureSettingsEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INSECURE_SETTINGS, true)); + agentMode.getSkipScan().getIastDetectionCategory().setInvalidFileAccessEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INVALID_FILE_ACCESS, true)); + agentMode.getSkipScan().getIastDetectionCategory().setSqlInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_SQL_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setNoSqlInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_NOSQL_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setLdapInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_LDAP_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setJavascriptInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_JAVASCRIPT_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setCommandInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_COMMAND_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setXpathInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_XPATH_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setSsrfEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_SSRF, true)); + agentMode.getSkipScan().getIastDetectionCategory().setRxssEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_RXSS, true)); + agentMode.getSkipScan().getIastDetectionCategory().generateDisabledCategoriesCSV(); + } + + private void readScanSchedule() throws RestrictionModeException { + agentMode.getScanSchedule().setDelay(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_DELAY, 0)); + agentMode.getScanSchedule().setDuration(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_DURATION, 0)); + agentMode.getScanSchedule().setSchedule(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_SCHEDULE, StringUtils.EMPTY)); + if(agentMode.getScanSchedule().getDelay() > 0) { + agentMode.getScanSchedule().setNextScanTime(new Date(Instant.now().toEpochMilli() + TimeUnit.MINUTES.toMillis(agentMode.getScanSchedule().getDelay()))); + } else if(StringUtils.isNotBlank(agentMode.getScanSchedule().getSchedule())) { + if(CronExpression.isValidExpression(agentMode.getScanSchedule().getSchedule())){ + try { + agentMode.getScanSchedule().setNextScanTime(new CronExpression(agentMode.getScanSchedule().getSchedule()).getTimeAfter(new Date())); + } catch (ParseException e) { + throw new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE, e); + } + } else { + throw new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE); + } + } } private void updateSkipScanParameters() { for (MappingParameters mappingParameter : this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters()) { if(mappingParameter.getAccountIdLocation().equals(HttpParameterLocation.HEADER)){ - this.agentMode.getIastScan().getRestrictionCriteria().getSkipScanParameters().getHeader().add(mappingParameter.getAccountIdKey()); + this.agentMode.getSkipScan().getParameters().getHeader().add(mappingParameter.getAccountIdKey()); } else if(mappingParameter.getAccountIdLocation().equals(HttpParameterLocation.QUERY)){ - this.agentMode.getIastScan().getRestrictionCriteria().getSkipScanParameters().getQuery().add(mappingParameter.getAccountIdKey()); + this.agentMode.getSkipScan().getParameters().getQuery().add(mappingParameter.getAccountIdKey()); } else if(mappingParameter.getAccountIdLocation().equals(HttpParameterLocation.BODY)){ - this.agentMode.getIastScan().getRestrictionCriteria().getSkipScanParameters().getBody().add(mappingParameter.getAccountIdKey()); + this.agentMode.getSkipScan().getParameters().getBody().add(mappingParameter.getAccountIdKey()); } } } @@ -149,6 +195,7 @@ private void updateSkipScanParameters() { private void readIastConfig() { this.agentMode.getIastScan().setEnabled(true); this.agentMode.getRaspScan().setEnabled(false); + } private void readIastRestrictedConfig() throws RestrictionModeException { @@ -160,18 +207,6 @@ private void readIastRestrictedConfig() throws RestrictionModeException { throw new RestrictionModeException(ACCOUNT_ID_IS_REQUIRED_FOR_IAST_RESTRICTED_MODE); } - restrictionCriteria.getScanTime().setDuration(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SCAN_TIME_DURATION, 5)); - restrictionCriteria.getScanTime().setSchedule(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SCAN_TIME_SCHEDULE, "0 0 0 * * ?")); - if(CronExpression.isValidExpression(restrictionCriteria.getScanTime().getSchedule())){ - try { - restrictionCriteria.getScanTime().setNextScanTime(new CronExpression(restrictionCriteria.getScanTime().getSchedule()).getTimeAfter(new Date())); - } catch (ParseException e) { - throw new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE, e); - } - } else { - throw new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE); - } - //Mapping parameters List> mappingParameters = NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS, Collections.emptyList()); if(mappingParameters.isEmpty()) { @@ -182,10 +217,6 @@ private void readIastRestrictedConfig() throws RestrictionModeException { // MappingParameters matchingCriteria = mapper.convertValue(mappingParameter, MappingParameters.class); restrictionCriteria.getMappingParameters().add(matchingCriteria); } - //Skip Scan Parameters - restrictionCriteria.getSkipScanParameters().setBody(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_BODY, Collections.emptyList())); - restrictionCriteria.getSkipScanParameters().setHeader(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_HEADER, Collections.emptyList())); - restrictionCriteria.getSkipScanParameters().setQuery(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_QUERY, Collections.emptyList())); //Strict Criteria List> strictCriteria = NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_STRICT, Collections.emptyList()); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java index 5766ea20b..cdef3f194 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/dispatcher/Dispatcher.java @@ -721,9 +721,7 @@ private JavaAgentEventBean setGenericProperties(AbstractOperation objectBean, Ja private JavaAgentEventBean prepareEvent(HttpRequest httpRequestBean, AgentMetaData metaData, VulnerabilityCaseType vulnerabilityCaseType, K2RequestIdentifier k2RequestIdentifier) { - if(AgentConfig.getInstance().getAgentMode().getIastScan().getRestricted()) { - metaData.setSkipScanParameters(AgentConfig.getInstance().getAgentMode().getIastScan().getRestrictionCriteria().getSkipScanParameters()); - } + metaData.setSkipScanParameters(AgentConfig.getInstance().getAgentMode().getSkipScan().getParameters()); JavaAgentEventBean eventBean = new JavaAgentEventBean(); eventBean.setHttpRequest(httpRequestBean); eventBean.setMetaData(metaData); 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 3113cf3d5..e280ccc2e 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 @@ -69,6 +69,8 @@ public class ControlCommandProcessor implements Runnable { private long receiveTimestamp; + private static Instant iastReplayRequestMsgReceiveTime; + private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); public ControlCommandProcessor(String controlCommandMessage, long receiveTimestamp) { @@ -166,6 +168,7 @@ public void run() { case IntCodeControlCommand.FUZZ_REQUEST: logger.log(LogLevel.FINER, FUZZ_REQUEST + controlCommandMessage, ControlCommandProcessor.class.getName()); + iastReplayRequestMsgReceiveTime = Instant.now(); IASTDataTransferRequestProcessor.getInstance().setLastFuzzCCTimestamp(Instant.now().toEpochMilli()); RestRequestProcessor.processControlCommand(controlCommand); break; @@ -271,4 +274,8 @@ public static void processControlCommand(String controlCommandMessage, long rece ControlCommandProcessorThreadPool.getInstance().executor .submit(new ControlCommandProcessor(controlCommandMessage, receiveTimestamp)); } + + public static Instant getIastReplayRequestMsgReceiveTime() { + return iastReplayRequestMsgReceiveTime; + } } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/collectorconfig/AgentMode.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/collectorconfig/AgentMode.java index 6f24cc64f..81183118e 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/collectorconfig/AgentMode.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/collectorconfig/AgentMode.java @@ -5,6 +5,8 @@ import com.newrelic.agent.security.intcodeagent.websocket.JsonConverter; import com.newrelic.api.agent.security.schema.policy.IASTScan; import com.newrelic.api.agent.security.schema.policy.RASPScan; +import com.newrelic.api.agent.security.schema.policy.ScanSchedule; +import com.newrelic.api.agent.security.schema.policy.SkipScan; @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder(alphabetic = true) @@ -16,12 +18,18 @@ public class AgentMode { private RASPScan raspScan; + private SkipScan skipScan; + + private ScanSchedule scanSchedule; + public AgentMode() {} public AgentMode(String mode) { this.mode = mode; iastScan = new IASTScan(); raspScan = new RASPScan(); + skipScan = new SkipScan(); + scanSchedule = new ScanSchedule(); } public String getMode() { @@ -48,6 +56,22 @@ public void setRaspScan(RASPScan raspScan) { this.raspScan = raspScan; } + public SkipScan getSkipScan() { + return skipScan; + } + + public void setSkipScan(SkipScan skipScan) { + this.skipScan = skipScan; + } + + public ScanSchedule getScanSchedule() { + return scanSchedule; + } + + public void setScanSchedule(ScanSchedule scanSchedule) { + this.scanSchedule = scanSchedule; + } + @Override public String toString() { return JsonConverter.toJSON(this); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java index 07b3a9609..240dc3591 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java @@ -10,6 +10,7 @@ import com.newrelic.api.agent.security.schema.HttpRequest; import com.newrelic.api.agent.security.schema.policy.MappingParameters; import com.newrelic.api.agent.security.schema.policy.RestrictionCriteria; +import com.newrelic.api.agent.security.schema.policy.SkipScan; import com.newrelic.api.agent.security.utils.logging.LogLevel; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; @@ -23,6 +24,7 @@ import javax.xml.parsers.DocumentBuilderFactory; import java.io.StringReader; import java.util.*; +import java.util.regex.Pattern; public class RestrictionUtility { @@ -40,6 +42,27 @@ public class RestrictionUtility { private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); + public static boolean skippedApiDetected(SkipScan skipScan, HttpRequest httpRequest) { + if (skipScan == null) { + return false; + } + if (httpRequest == null) { + return false; + } + + if(skipScan.getApiRoutes().isEmpty()) { + return false; + } + + for (Pattern pattern : skipScan.getApiRoutes()) { + if (pattern.matcher(httpRequest.getUrl()).matches()) { + return true; + } + } + + return false; + } + public static boolean hasValidAccountId(RestrictionCriteria restrictionCriteria, HttpRequest request) { List accountIds = restrictionCriteria.getAccountInfo().getAccountIds(); if (request == null) { 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 09986e15b..c5cda2b05 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 @@ -147,6 +147,7 @@ private WSClient() throws URISyntaxException { this.addHeader("NR-CSEC-JSON-VERSION", AgentInfo.getInstance().getBuildInfo().getJsonVersion()); this.addHeader("NR-ACCOUNT-ID", AgentConfig.getInstance().getConfig().getCustomerInfo().getAccountId()); this.addHeader("NR-CSEC-IAST-DATA-TRANSFER-MODE", "PULL"); + this.addHeader("NR-CSEC-IGNORED-VUL-CATEGORIES", AgentConfig.getInstance().getAgentMode().getSkipScan().getIastDetectionCategory().getDisabledCategoriesCSV()); Proxy proxy = proxyManager(); if(proxy != null) { this.setProxy(proxy); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java index e32607c94..8f882cdd7 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java @@ -8,7 +8,28 @@ public interface IUtilConstants { String IAST = "IAST"; String IAST_RESTRICTED = "IAST_RESTRICTED"; - String RESTRICTION_CRITERIA_SCAN_TIME = "security.restriction_criteria.scan_time"; + String SCAN_TIME_DELAY = "security.scan_schedule.delay"; + String SCAN_TIME_SCHEDULE = "security.scan_schedule.schedule"; + String SCAN_TIME_DURATION = "security.scan_schedule.duration"; + + String SKIP_IAST_SCAN = "security.skip_iast_scan"; + String SKIP_IAST_SCAN_API = SKIP_IAST_SCAN + ".api"; + String SKIP_IAST_SCAN_PARAMETERS = SKIP_IAST_SCAN + ".parameters"; + String SKIP_IAST_SCAN_PARAMETERS_HEADER = SKIP_IAST_SCAN + ".parameters.header"; + String SKIP_IAST_SCAN_PARAMETERS_QUERY = SKIP_IAST_SCAN + ".parameters.query"; + String SKIP_IAST_SCAN_PARAMETERS_BODY = SKIP_IAST_SCAN + ".parameters.body"; + String SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY = SKIP_IAST_SCAN + ".iast_detection_category"; + String SKIP_INSECURE_SETTINGS = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".insecure_settings"; + String SKIP_INVALID_FILE_ACCESS = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".invalid_file_access"; + String SKIP_SQL_INJECTION = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".sql_injection"; + String SKIP_NOSQL_INJECTION = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".nosql_injection"; + String SKIP_LDAP_INJECTION = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".ldap_injection"; + String SKIP_JAVASCRIPT_INJECTION = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".javascript_injection"; + String SKIP_COMMAND_INJECTION = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".command_injection"; + String SKIP_XPATH_INJECTION = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".xpath_injection"; + String SKIP_SSRF = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".ssrf"; + String SKIP_RXSS = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".rxss"; + String RESTRICTION_CRITERIA_SCAN_TIME_SCHEDULE = "security.restriction_criteria.scan_time.schedule"; String RESTRICTION_CRITERIA_SCAN_TIME_DURATION = "security.restriction_criteria.scan_time.duration"; String RESTRICTION_CRITERIA = "security.restriction_criteria"; 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 3f729a4f7..3c93eb2df 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,17 +4,21 @@ 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; import com.newrelic.agent.security.intcodeagent.constants.HttpStatusCodes; +import com.newrelic.agent.security.intcodeagent.controlcommand.ControlCommandProcessor; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.agent.security.intcodeagent.filelogging.LogFileHelper; +import com.newrelic.agent.security.intcodeagent.models.collectorconfig.AgentMode; import com.newrelic.agent.security.intcodeagent.models.javaagent.*; import com.newrelic.agent.security.intcodeagent.utils.EncryptorUtils; import com.newrelic.agent.security.intcodeagent.utils.RestrictionUtility; import com.newrelic.agent.security.intcodeagent.utils.RuntimeErrorReporter; import com.newrelic.api.agent.security.instrumentation.helpers.*; +import com.newrelic.api.agent.security.schema.policy.IastDetectionCategory; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.agent.security.intcodeagent.logging.HealthCheckScheduleThread; import com.newrelic.agent.security.intcodeagent.logging.IAgentConstants; @@ -59,6 +63,7 @@ public class Agent implements SecurityAgent { public static final String DROPPING_EVENT_AS_IT_WAS_GENERATED_BY_K_2_INTERNAL_API_CALL = "Dropping event as it was generated by agent internal API call : "; private static final AtomicBoolean firstEventProcessed = new AtomicBoolean(false); public static final String ERROR_WHILE_GENERATING_TRACE_ID_FOR_CATEGORY_S = "Error while generating trace id for category : %s"; + public static final String SKIPPING_THE_API_S_AS_IT_IS_PART_OF_THE_SKIP_SCAN_LIST = "Skipping the API %s as it is part of the skip scan list"; private AgentInfo info; @@ -163,18 +168,26 @@ private void triggerNrSecurity() { } private void scheduleShutdownTrigger() { - if(AgentConfig.getInstance().getAgentMode().getIastScan().getEnabled() && AgentConfig.getInstance().getAgentMode().getIastScan().getRestricted()){ - int duration = AgentConfig.getInstance().getAgentMode().getIastScan().getRestrictionCriteria().getScanTime().getDuration(); + if(AgentConfig.getInstance().getAgentMode().getScanSchedule().getDuration() > 0) { + int duration = AgentConfig.getInstance().getAgentMode().getScanSchedule().getDuration(); Instant now = Instant.now(); - Instant shutdownInstant = now.plus(duration, ChronoUnit.HOURS); + Instant shutdownInstant = now.plus(duration, ChronoUnit.MINUTES); long shutdownTime = shutdownInstant.getEpochSecond() - now.getEpochSecond(); - SchedulerHelper.getInstance().scheduleIastTrigger(this::IastRestrictedShutdown, shutdownTime, TimeUnit.SECONDS); + SchedulerHelper.getInstance().scheduleIastTrigger(this::IastShutdown, shutdownTime, TimeUnit.SECONDS); } } + private void IastShutdown() { + if(ControlCommandProcessor.getIastReplayRequestMsgReceiveTime().isBefore(Instant.now().minus(5, ChronoUnit.MINUTES))){ + logger.log(LogLevel.WARNING, "IAST scan is still in progress, may have undetected vulnerabilities. Please increase scan duration and restart application.", Agent.class.getName()); + } + logger.log(LogLevel.FINER, "Scan duration completed, IAST Scan shutting down.", Agent.class.getName()); + InstrumentationUtils.shutdownLogic(); + } + private void IastRestrictedShutdown() { InstrumentationUtils.shutdownLogic(); - long delay = config.trigerIAST(); + long delay = config.triggerIAST(); SchedulerHelper.getInstance().scheduleIastTrigger(this::triggerNrSecurity, delay, TimeUnit.MILLISECONDS); } @@ -229,6 +242,11 @@ private void startK2Services() { } + @Override + public IastDetectionCategory getIastDetectionCategory() { + return AgentConfig.getInstance().getAgentMode().getSkipScan().getIastDetectionCategory(); + } + @Override public boolean refreshState(java.net.URL agentJarURL, Instrumentation instrumentation) { /** @@ -290,7 +308,13 @@ public void registerOperation(AbstractOperation operation) { boolean lockAcquired = ThreadLocalLockHelper.acquireLock(); try { if(lockAcquired) { + SecurityMetaData securityMetaData = NewRelicSecurity.getAgent().getSecurityMetaData(); + if(RestrictionUtility.skippedApiDetected(AgentConfig.getInstance().getAgentMode().getSkipScan(), securityMetaData.getRequest())){ + logger.log(LogLevel.FINER, String.format(SKIPPING_THE_API_S_AS_IT_IS_PART_OF_THE_SKIP_SCAN_LIST, securityMetaData.getRequest().getUrl()), Agent.class.getName()); + return; + } + if (securityMetaData != null && securityMetaData.getRequest().getIsGrpc()) { securityMetaData.getRequest().setBody( new StringBuilder(JsonConverter.toJSON(securityMetaData.getCustomAttribute(GrpcHelper.NR_SEC_GRPC_REQUEST_DATA, List.class)))); 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 3f47b0954..931b5e0a4 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 @@ -8,6 +8,7 @@ import com.newrelic.api.agent.security.schema.ServerConnectionConfiguration; import com.newrelic.api.agent.security.schema.operation.FileIntegrityOperation; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; +import com.newrelic.api.agent.security.schema.policy.IastDetectionCategory; import com.newrelic.api.agent.security.utils.logging.LogLevel; import java.lang.instrument.Instrumentation; @@ -24,6 +25,7 @@ public class Agent implements SecurityAgent { public static final String OPERATIONS = "operations"; public static final String EXIT_OPERATIONS = "exit-operations"; private static Agent instance; + private final IastDetectionCategory defaultIastDetectionCategory = new IastDetectionCategory(); private AgentPolicy policy = new AgentPolicy(); @@ -50,6 +52,11 @@ private Agent() { private void initialise() { } + @Override + public IastDetectionCategory getIastDetectionCategory() { + return defaultIastDetectionCategory; + } + @Override public boolean refreshState(URL agentJarURL, Instrumentation instrumentation) { return true; 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 d5e0f6e74..1a05caf52 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 @@ -12,6 +12,7 @@ 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; +import com.newrelic.api.agent.security.schema.policy.IastDetectionCategory; import com.newrelic.api.agent.security.utils.logging.LogLevel; import java.lang.instrument.Instrumentation; @@ -25,11 +26,17 @@ class NoOpAgent implements SecurityAgent { private static final SecurityAgent INSTANCE = new NoOpAgent(); public static final String EMPTY = ""; + private final IastDetectionCategory defaultIastDetectionCategory = new IastDetectionCategory(); public static SecurityAgent getInstance() { return INSTANCE; } + @Override + public IastDetectionCategory getIastDetectionCategory() { + return defaultIastDetectionCategory; + } + @Override public boolean refreshState(URL agentJarURL, Instrumentation instrumentation) { return true; 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 82b573974..bf977d776 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 @@ -11,6 +11,7 @@ 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; +import com.newrelic.api.agent.security.schema.policy.IastDetectionCategory; import com.newrelic.api.agent.security.utils.logging.LogLevel; import java.lang.instrument.Instrumentation; @@ -22,6 +23,8 @@ */ public interface SecurityAgent { + IastDetectionCategory getIastDetectionCategory(); + boolean refreshState(URL agentJarURL, Instrumentation instrumentation); boolean deactivateSecurity(); diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/FileHelper.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/FileHelper.java index e5fc7954f..ffc269e9a 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/FileHelper.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/FileHelper.java @@ -186,7 +186,7 @@ public static void releaseFileLock() { } catch (Throwable ignored){} } - private static String getNrSecCustomAttribName() { + public static String getNrSecCustomAttribName() { return NR_SEC_CUSTOM_ATTRIB_NAME + Thread.currentThread().getId(); } } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GenericHelper.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GenericHelper.java index 8d4cf3f0f..36e7b1ba5 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GenericHelper.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GenericHelper.java @@ -1,6 +1,7 @@ package com.newrelic.api.agent.security.instrumentation.helpers; import com.newrelic.api.agent.security.NewRelicSecurity; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import java.util.regex.Pattern; @@ -49,6 +50,64 @@ public static boolean isLockAcquired(String nrSecCustomAttrName, int hashCode) { return false; } + public static boolean acquireLockIfPossible(VulnerabilityCaseType caseType, String nrSecCustomAttrName, int hashCode) { + boolean enabled = false; + if(!NewRelicSecurity.isHookProcessingActive()) { + return false; + } + switch (caseType) { + case SYSTEM_COMMAND: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getCommandInjectionEnabled(); + break; + case FILE_OPERATION: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getInvalidFileAccessEnabled(); + break; + case SQL_DB_COMMAND: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getSqlInjectionEnabled(); + break; + case NOSQL_DB_COMMAND: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getNoSqlInjectionEnabled(); + break; + case DYNAMO_DB_COMMAND: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getNoSqlInjectionEnabled(); + break; + case HTTP_REQUEST: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getSsrfEnabled(); + break; + case LDAP: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getLdapInjectionEnabled(); + break; + case XPATH: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getXpathInjectionEnabled(); + break; + case REFLECTED_XSS: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled(); + break; + case FILE_INTEGRITY: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getInvalidFileAccessEnabled(); + break; + case JAVASCRIPT_INJECTION: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getJavascriptInjectionEnabled(); + break; + case XQUERY_INJECTION: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getXpathInjectionEnabled(); + break; + case SECURE_COOKIE: + case CRYPTO: + case RANDOM: + case TRUSTBOUNDARY: + case HASH: + enabled = NewRelicSecurity.getAgent().getIastDetectionCategory().getInsecureSettingsEnabled(); + break; + default: + break; + } + if(enabled) { + return false; + } + return acquireLockIfPossible(nrSecCustomAttrName, hashCode); + } + public static boolean acquireLockIfPossible(String nrSecCustomAttrName, int hashCode) { try { if (NewRelicSecurity.isHookProcessingActive() && @@ -68,6 +127,10 @@ public static void releaseLock(String nrSecCustomAttrName, int hashCode) { } catch (Throwable ignored){} } + public static boolean acquireLockIfPossible(VulnerabilityCaseType caseType, String nrSecCustomAttrName) { + return acquireLockIfPossible(caseType, nrSecCustomAttrName, 0); + } + public static boolean acquireLockIfPossible(String nrSecCustomAttrName) { return acquireLockIfPossible(nrSecCustomAttrName, 0); } @@ -75,4 +138,8 @@ public static boolean acquireLockIfPossible(String nrSecCustomAttrName) { public static void releaseLock(String nrSecCustomAttrName) { releaseLock(nrSecCustomAttrName, 0); } + + public static void onTransactionFinish() { + + } } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/JdbcHelper.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/JdbcHelper.java index b4081527b..265ce1e79 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/JdbcHelper.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/JdbcHelper.java @@ -85,14 +85,10 @@ public static boolean acquireLockIfPossible() { } public static void releaseLock() { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), null); - } - } catch (Throwable ignored){} + GenericHelper.releaseLock(JdbcHelper.getNrSecCustomAttribName()); } - private static String getNrSecCustomAttribName() { + public static String getNrSecCustomAttribName() { return NR_SEC_CUSTOM_ATTRIB_NAME + Thread.currentThread().getId(); } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/R2dbcHelper.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/R2dbcHelper.java index c23e60285..680dec0ec 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/R2dbcHelper.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/R2dbcHelper.java @@ -3,6 +3,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.R2DBCVendor; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SQLOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -72,23 +73,12 @@ public static boolean isLockAcquired() { return false; } - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && - !isLockAcquired()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), true); - return true; - } - } catch (Throwable ignored){} - return false; + public static boolean acquireLockIfPossible(VulnerabilityCaseType sqlDbCommand) { + return GenericHelper.acquireLockIfPossible(sqlDbCommand, getNrSecCustomAttribName()); } public static void releaseLock() { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), null); - } - } catch (Throwable ignored){} + GenericHelper.releaseLock(getNrSecCustomAttribName()); } private static String getNrSecCustomAttribName() { diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java new file mode 100644 index 000000000..46933e1b0 --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java @@ -0,0 +1,167 @@ +package com.newrelic.api.agent.security.schema.policy; + +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; + +public class IastDetectionCategory { + + public static final String STR_COMMA = ","; + Boolean sqlInjectionEnabled = true; + Boolean insecureSettingsEnabled = true; + Boolean invalidFileAccessEnabled = true; + Boolean noSqlInjectionEnabled = true; + Boolean rxssEnabled = true; + Boolean commandInjectionEnabled = true; + Boolean ldapInjectionEnabled = true; + Boolean javascriptInjectionEnabled = true; + Boolean xpathInjectionEnabled = true; + Boolean ssrfEnabled = true; + + private String disabledCategoriesCSV; + + public IastDetectionCategory() { + } + + public Boolean getSqlInjectionEnabled() { + return sqlInjectionEnabled; + } + + public void setSqlInjectionEnabled(Boolean sqlInjectionEnabled) { + this.sqlInjectionEnabled = sqlInjectionEnabled; + } + + public Boolean getInsecureSettingsEnabled() { + return insecureSettingsEnabled; + } + + public void setInsecureSettingsEnabled(Boolean insecureSettingsEnabled) { + this.insecureSettingsEnabled = insecureSettingsEnabled; + } + + public Boolean getInvalidFileAccessEnabled() { + return invalidFileAccessEnabled; + } + + public void setInvalidFileAccessEnabled(Boolean invalidFileAccessEnabled) { + this.invalidFileAccessEnabled = invalidFileAccessEnabled; + } + + public Boolean getNoSqlInjectionEnabled() { + return noSqlInjectionEnabled; + } + + public void setNoSqlInjectionEnabled(Boolean noSqlInjectionEnabled) { + this.noSqlInjectionEnabled = noSqlInjectionEnabled; + } + + public Boolean getRxssEnabled() { + return rxssEnabled; + } + + public void setRxssEnabled(Boolean rxssEnabled) { + this.rxssEnabled = rxssEnabled; + } + + public Boolean getCommandInjectionEnabled() { + return commandInjectionEnabled; + } + + public void setCommandInjectionEnabled(Boolean commandInjectionEnabled) { + this.commandInjectionEnabled = commandInjectionEnabled; + } + + public Boolean getLdapInjectionEnabled() { + return ldapInjectionEnabled; + } + + public void setLdapInjectionEnabled(Boolean ldapInjectionEnabled) { + this.ldapInjectionEnabled = ldapInjectionEnabled; + } + + public Boolean getJavascriptInjectionEnabled() { + return javascriptInjectionEnabled; + } + + public void setJavascriptInjectionEnabled(Boolean javascriptInjectionEnabled) { + this.javascriptInjectionEnabled = javascriptInjectionEnabled; + } + + public Boolean getXpathInjectionEnabled() { + return xpathInjectionEnabled; + } + + public void setXpathInjectionEnabled(Boolean xpathInjectionEnabled) { + this.xpathInjectionEnabled = xpathInjectionEnabled; + } + + public Boolean getSsrfEnabled() { + return ssrfEnabled; + } + + public void setSsrfEnabled(Boolean ssrfEnabled) { + this.ssrfEnabled = ssrfEnabled; + } + + public void generateDisabledCategoriesCSV() { + StringBuilder disabledCategoriesCSVBuilder = new StringBuilder(); + if (sqlInjectionEnabled) { + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.SQL_DB_COMMAND); + disabledCategoriesCSVBuilder.append(STR_COMMA); + } + if (insecureSettingsEnabled) { + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.HASH); + disabledCategoriesCSVBuilder.append(STR_COMMA); + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.RANDOM); + disabledCategoriesCSVBuilder.append(STR_COMMA); + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.SECURE_COOKIE); + disabledCategoriesCSVBuilder.append(STR_COMMA); + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.TRUSTBOUNDARY); + disabledCategoriesCSVBuilder.append(STR_COMMA); + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.CRYPTO); + disabledCategoriesCSVBuilder.append(STR_COMMA); + } + if (invalidFileAccessEnabled) { + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.FILE_INTEGRITY); + disabledCategoriesCSVBuilder.append(STR_COMMA); + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.FILE_OPERATION); + disabledCategoriesCSVBuilder.append(STR_COMMA); + } + if (noSqlInjectionEnabled) { + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.NOSQL_DB_COMMAND); + disabledCategoriesCSVBuilder.append(STR_COMMA); + } + if (rxssEnabled) { + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.REFLECTED_XSS); + disabledCategoriesCSVBuilder.append(STR_COMMA); + } + if (commandInjectionEnabled) { + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.SYSTEM_COMMAND); + disabledCategoriesCSVBuilder.append(STR_COMMA); + } + if (ldapInjectionEnabled) { + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.LDAP); + disabledCategoriesCSVBuilder.append(STR_COMMA); + } + if (javascriptInjectionEnabled) { + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.JAVASCRIPT_INJECTION); + disabledCategoriesCSVBuilder.append(STR_COMMA); + } + if (xpathInjectionEnabled) { + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.XPATH); + disabledCategoriesCSVBuilder.append(STR_COMMA); + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.XQUERY_INJECTION); + disabledCategoriesCSVBuilder.append(STR_COMMA); + } + if (ssrfEnabled) { + disabledCategoriesCSVBuilder.append(VulnerabilityCaseType.HTTP_REQUEST); + disabledCategoriesCSVBuilder.append(STR_COMMA); + } + if (disabledCategoriesCSVBuilder.length() > 0) { + disabledCategoriesCSVBuilder.deleteCharAt(disabledCategoriesCSVBuilder.length() - 1); + } + disabledCategoriesCSV = disabledCategoriesCSVBuilder.toString(); + } + + public String getDisabledCategoriesCSV() { + return disabledCategoriesCSV; + } +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java index 7a9e227cb..8d87ce1c6 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java @@ -5,7 +5,7 @@ public class RestrictionCriteria { - private ScanTime scanTime = new ScanTime(); + private ScanSchedule scanSchedule = new ScanSchedule(); private AccountInfo accountInfo = new AccountInfo(); @@ -18,12 +18,12 @@ public class RestrictionCriteria { public RestrictionCriteria() { } - public ScanTime getScanTime() { - return scanTime; + public ScanSchedule getScanTime() { + return scanSchedule; } - public void setScanTime(ScanTime scanTime) { - this.scanTime = scanTime; + public void setScanTime(ScanSchedule scanSchedule) { + this.scanSchedule = scanSchedule; } public AccountInfo getAccountInfo() { diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanTime.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanSchedule.java similarity index 71% rename from newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanTime.java rename to newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanSchedule.java index dd5d8901f..75084afb0 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanTime.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanSchedule.java @@ -2,15 +2,17 @@ import java.util.Date; -public class ScanTime { +public class ScanSchedule { - private int duration; + private int duration = -1; private String schedule; private Date nextScanTime; - public ScanTime() { + private int delay = 0; + + public ScanSchedule() { } public int getDuration() { @@ -36,4 +38,12 @@ public Date getNextScanTime() { public void setNextScanTime(Date nextScanTime) { this.nextScanTime = nextScanTime; } + + public int getDelay() { + return delay; + } + + public void setDelay(int delay) { + this.delay = delay; + } } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScan.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScan.java new file mode 100644 index 000000000..042f28366 --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScan.java @@ -0,0 +1,55 @@ +package com.newrelic.api.agent.security.schema.policy; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +public class SkipScan { + private List apis = new ArrayList<>(); + + private List apiRoutes = new ArrayList<>(); + + private SkipScanParameters parameters = new SkipScanParameters(); + + private IastDetectionCategory iastDetectionCategory = new IastDetectionCategory(); + + public SkipScan() { + } + + public List getApis() { + return apis; + } + + public void setApis(List apis) { + this.apis = apis; + if(apis != null) { + for (String api : apis) { + apiRoutes.add(Pattern.compile(api)); + } + } + } + + public List getApiRoutes() { + return apiRoutes; + } + + public void setApiRoutes(List apiRoutes) { + this.apiRoutes = apiRoutes; + } + + public SkipScanParameters getParameters() { + return parameters; + } + + public void setParameters(SkipScanParameters parameters) { + this.parameters = parameters; + } + + public IastDetectionCategory getIastDetectionCategory() { + return iastDetectionCategory; + } + + public void setIastDetectionCategory(IastDetectionCategory iastDetectionCategory) { + this.iastDetectionCategory = iastDetectionCategory; + } +} From 8e12347e7816a6644bc5936a880803b67496f5af Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Wed, 14 Aug 2024 10:55:51 +0530 Subject: [PATCH 09/44] Add feature to IAST_SCAN_IGNORE --- .../http/scaladsl/server/AkkaCoreUtils.java | 3 ++ .../akka/http/scaladsl/AkkaCoreUtils.java | 3 ++ .../scaladsl/HttpExt_Instrumentation.java | 7 +-- .../akka/http/scaladsl/AkkaCoreUtils.java | 3 ++ .../scaladsl/HttpExt_Instrumentation.java | 7 +-- .../akka/http/scaladsl/AkkaCoreUtils.java | 3 ++ .../scaladsl/HttpExt_Instrumentation.java | 7 +-- .../akka/http/scaladsl/AkkaCoreUtils.java | 3 ++ .../scaladsl/HttpExt_Instrumentation.java | 7 +-- .../LdapAsyncConnection_Instrumentation.java | 11 ++-- .../api/LdapConnection_Instrumentation.java | 11 ++-- .../org/asynchttpclient/AsynchttpHelper.java | 12 ++--- .../AsyncHttpClient_Instrumentation.java | 3 +- .../BuilderSupport_Instrumentation.java | 7 +-- .../core/SessionManager_Instrumentation.java | 3 +- .../core/SimpleStatement_Instrumentation.java | 4 +- .../cassandra3/CassandraUtils.java | 4 +- .../driver/core/Session_Instrumentation.java | 3 +- .../cassandra4/CassandraUtils.java | 4 +- ...hContextReferenceImpl_Instrumentation.java | 13 ++--- .../AmazonDynamoDBClient_Instrumentation.java | 3 +- .../dynamodb_1_11_390/DynamoDBUtil.java | 5 +- .../AmazonDynamoDBClient_Instrumentation.java | 3 +- .../dynamodb_1_11_453/DynamoDBUtil.java | 5 +- .../AmazonDynamoDBClient_Instrumentation.java | 3 +- .../dynamodb_1_11_459/DynamoDBUtil.java | 5 +- .../AmazonDynamoDBClient_Instrumentation.java | 3 +- .../dynamodb_1_11_80/DynamoDBUtil.java | 5 +- .../dynamodb_210/DynamoDBUtil.java | 3 +- .../AsyncClientHandler_Instrumentation.java | 5 +- .../SyncClientHandler_Instrumentation.java | 5 +- .../dynamodb_212/DynamoDBUtil.java | 5 +- .../AsyncClientHandler_Instrumentation.java | 6 +-- .../SyncClientHandler_Instrumentation.java | 6 +-- .../dynamodb_215/DynamoDBUtil.java | 5 +- .../AsyncClientHandler_Instrumentation.java | 6 +-- .../SyncClientHandler_Instrumentation.java | 6 +-- .../random/java/io/File_Instrumentation.java | 16 ++---- .../io/FileInputStream_Instrumentation.java | 16 +++--- .../io/FileOutputStream_Instrumentation.java | 16 +++--- .../java/java/io/File_Instrumentation.java | 50 ++++++++----------- .../io/RandomAccessFile_Instrumentation.java | 16 +++--- .../java/nio/file/Files_Instrumentation.java | 16 ++---- .../FileSystemProvider_Instrumentation.java | 43 ++++++++-------- .../PolyglotContextImpl_Instrumentation.java | 7 +-- .../PolyglotContextImpl_Instrumentation.java | 7 +-- .../grpc1220/GrpcClientUtils.java | 26 ++-------- .../grpc1220/GrpcServerUtils.java | 3 ++ .../io/grpc/ClientCall_Instrumentation.java | 3 +- .../grpc140/GrpcClientUtils.java | 27 ++-------- .../grpc140/GrpcServerUtils.java | 3 ++ .../io/grpc/ClientCall_Instrumentation.java | 3 +- .../grpc1400/GrpcClientUtils.java | 25 ++-------- .../grpc1400/GrpcServerUtils.java | 3 ++ .../io/grpc/ClientCall_Instrumentation.java | 3 +- .../HttpAsyncClient4_Instrumentation.java | 17 ++++--- .../HttpMethodBase_Instrumentation.java | 7 +-- .../HttpClient_Instrumentation.java | 21 ++++---- .../HttpAsyncClient_Instrumentation.java | 7 +-- .../HttpClient_Instrumentation.java | 21 ++++---- .../http/HttpClientImpl_Instrumentation.java | 7 +-- .../javax/naming/Context_Instrumentation.java | 13 ++--- .../directory/DirContext_Instrumentation.java | 13 ++--- .../xpath/internal/XPath_Instrumentation.java | 9 ++-- .../xml/xpath/XPath_Instrumentation.java | 13 ++--- .../org/jaxen/BaseXPath_Instrumentation.java | 7 +-- .../org/jaxen/BaseXPath_Instrumentation.java | 7 +-- .../jcache_1_0_0/JCacheHelper.java | 5 +- .../javax/cache/Cache_Instrumentation.java | 31 ++++++------ .../PreparedStatement_Instrumentation.java | 20 +++----- .../java/sql/Statement_Instrumentation.java | 36 ++++++------- ...JtdsPreparedStatement_Instrumentation.java | 14 +++--- .../jdbc/JtdsStatement_Instrumentation.java | 26 +++++----- ...bstractJdbc2Statement_Instrumentation.java | 24 ++++----- .../jdbc/PgStatement_Instrumentation.java | 20 ++++---- .../jedis_2_7_1/JedisHelper.java | 5 +- .../jedis/Connection_Instrumentation.java | 3 +- .../jedis_3_0_0/JedisHelper.java | 5 +- .../jedis/Connection_Instrumentation.java | 3 +- .../jedis_4_0_0/JedisHelper.java | 5 +- .../jedis/Connection_Instrumentation.java | 3 +- .../ContainerResponse_Instrumentation.java | 3 +- .../ContainerResponse_Instrumentation.java | 3 +- .../ContainerResponse_Instrumentation.java | 3 +- .../jetty11/HttpServletHelper.java | 6 ++- .../jetty12/server/HttpServletHelper.java | 6 ++- .../jetty9/HttpServletHelper.java | 6 ++- .../AbstractOperation_Instrumentation.java | 10 ++-- .../AbstractOperation_Instrumentation.java | 7 +-- ...actRedisAsyncCommands_Instrumentation.java | 7 +-- ...actRedisAsyncCommands_Instrumentation.java | 7 +-- .../java/util/Random_Instrumentation.java | 21 ++++---- .../CommandReadOperation_Instrumentation.java | 5 +- ...CommandWriteOperation_Instrumentation.java | 5 +- .../OperationExecutor_Instrumentation.java | 9 ++-- .../instrumentation/mongo/MongoUtil.java | 5 +- .../OperationExecutor_Instrumentation.java | 13 ++--- .../CommandReadOperation_Instrumentation.java | 5 +- ...CommandWriteOperation_Instrumentation.java | 5 +- .../instrumentation/mongo/MongoUtil.java | 5 +- .../OperationExecutor_Instrumentation.java | 13 ++--- .../CommandReadOperation_Instrumentation.java | 5 +- ...CommandWriteOperation_Instrumentation.java | 5 +- .../instrumentation/mongo/MongoUtil.java | 5 +- .../OperationExecutor_Instrumentation.java | 13 ++--- .../CommandReadOperation_Instrumentation.java | 5 +- ...CommandWriteOperation_Instrumentation.java | 5 +- .../instrumentation/mongo/MongoUtil.java | 5 +- ...ttpRequestToMuleEvent_Instrumentation.java | 7 ++- .../async/RequestHandler_Instrumentation.java | 6 ++- ...ttpRequestToMuleEvent_Instrumentation.java | 6 ++- .../async/RequestHandler_Instrumentation.java | 6 ++- .../NashornScriptEngine_Instrumentation.java | 9 ++-- ...ChannelInboundHandler_Instrumentation.java | 3 +- ...hannelOutboundHandler_Instrumentation.java | 3 +- .../io/netty400/utils/NettyUtils.java | 18 ++----- ...ChannelInboundHandler_Instrumentation.java | 3 +- ...hannelOutboundHandler_Instrumentation.java | 3 +- .../io/netty400/utils/NettyUtils.java | 18 ++----- .../ning/http_1_0/NingHelper.java | 8 ++- .../AsyncHttpProvider_Instrumentation.java | 3 +- .../ning/http_1_1/NingHelper.java | 5 +- .../AsyncHttpProvider_Instrumentation.java | 3 +- .../ning/http_1_6_1/NingHelper.java | 5 +- .../AsyncHttpProvider_Instrumentation.java | 3 +- .../okhttp30/OkhttpHelper.java | 30 +---------- .../okhttp30/RealCall_Instrumentation.java | 14 ++---- .../okhttp35/OkhttpHelper.java | 30 +---------- .../http/HttpCodec_Instrumentation.java | 16 ++---- .../ExchangeCodec_Instrumentation.java | 14 ++---- .../okhttp40/OkhttpHelper.java | 30 +---------- .../io/r2dbc/spi/Batch_Instrumentation.java | 3 +- .../io/r2dbc/spi/Statement_Instrumention.java | 3 +- .../h2/client/Client_Instrumentation.java | 11 +--- .../ScriptRuntime_Instrumentation.java | 7 +-- .../saxpath/XPathReader_Instrumentation.java | 7 +-- .../servlet/FilterChain_Instrumentation.java | 3 ++ .../javax/servlet/Filter_Instrumentation.java | 3 ++ .../servlet/Servlet_Instrumentation.java | 3 ++ .../servlet/FilterChain_Instrumentation.java | 3 ++ .../servlet/Filter_Instrumentation.java | 3 ++ .../servlet/Servlet_Instrumentation.java | 3 ++ .../servlet/FilterChain_Instrumentation.java | 3 ++ .../servlet/Filter_Instrumentation.java | 3 ++ .../servlet/Servlet_Instrumentation.java | 3 ++ .../ResponseRendering_Instrumentation.java | 3 +- .../SprayToResponseMarshallingContext.java | 3 +- .../ExchangeFunction_Instrumentation.java | 7 +-- .../MemcachedClient_Instrumentation.java | 7 +-- .../httpserver/Filter_Instrumentation.java | 3 ++ .../HttpHandler_Instrumentation.java | 3 ++ .../sdk/LDAPInterface_Instrumentation.java | 7 +-- .../vertx/VertxClientHelper.java | 5 +- ...HttpClientRequestImpl_Instrumentation.java | 5 +- .../vertx/VertxClientHelper.java | 5 +- ...HttpClientRequestImpl_Instrumentation.java | 5 +- ...HttpClientRequestImpl_Instrumentation.java | 13 ++--- .../vertx/web/VertxClientHelper.java | 5 +- ...HttpClientRequestImpl_Instrumentation.java | 7 +-- .../apache/xpath/XPath_Instrumentation.java | 7 +-- 160 files changed, 663 insertions(+), 732 deletions(-) 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 3a243a2a5..430dedb60 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 @@ -60,6 +60,9 @@ public static boolean acquireServletLockIfPossible() { } public static void postProcessHttpRequest(Boolean isServletLockAcquired, StringBuilder responseBody, String contentType, String className, String methodName, Token token) { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } try { token.linkAndExpire(); ServletHelper.executeBeforeExitingTransaction(); 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 904e8fb83..cfd6c386c 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 @@ -63,6 +63,9 @@ public static boolean acquireServletLockIfPossible() { public static void postProcessHttpRequest(Boolean isServletLockAcquired, StringBuilder response, String contentType, int responseCode, String className, String methodName, Token token) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } token.linkAndExpire(); if(!isServletLockAcquired || !NewRelicSecurity.isHookProcessingActive()){ diff --git a/instrumentation-security/akka-http-core-10.0/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java b/instrumentation-security/akka-http-core-10.0/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java index e28c30ad5..deada6535 100644 --- a/instrumentation-security/akka-http-core-10.0/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java +++ b/instrumentation-security/akka-http-core-10.0/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java @@ -20,6 +20,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -65,7 +66,7 @@ public Future bindAndHandleSync( public Future singleRequest(HttpRequest httpRequest, HttpsConnectionContext connectionContext, ConnectionPoolSettings settings, LoggingAdapter log, Materializer fm) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -163,9 +164,9 @@ private void releaseLock() { } } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { try { - return GenericHelper.acquireLockIfPossible(AkkaCoreUtils.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); + return GenericHelper.acquireLockIfPossible(httpRequest, AkkaCoreUtils.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); } catch (Throwable ignored) { } return false; 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 064790902..124589903 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 @@ -63,6 +63,9 @@ public static boolean acquireServletLockIfPossible() { public static void postProcessHttpRequest(Boolean isServletLockAcquired, StringBuilder responseBody, String contentType, int responseCode, String className, String methodName, Token token) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } token.linkAndExpire(); if(!isServletLockAcquired || !NewRelicSecurity.isHookProcessingActive()){ diff --git a/instrumentation-security/akka-http-core-2.11_10.0.11/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java b/instrumentation-security/akka-http-core-2.11_10.0.11/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java index ea8efb5ba..65d5da00b 100644 --- a/instrumentation-security/akka-http-core-2.11_10.0.11/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java +++ b/instrumentation-security/akka-http-core-2.11_10.0.11/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java @@ -20,6 +20,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -66,7 +67,7 @@ public Future bindAndHandleSync( public Future singleRequestImpl(HttpRequest httpRequest, HttpsConnectionContext connectionContext, ConnectionPoolSettings poolSettings, LoggingAdapter loggingAdapter) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase SecurityMetaData securityMetaData = NewRelicSecurity.getAgent().getSecurityMetaData(); @@ -167,9 +168,9 @@ private void releaseLock() { } } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { try { - return GenericHelper.acquireLockIfPossible(AkkaCoreUtils.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); + return GenericHelper.acquireLockIfPossible(httpRequest, AkkaCoreUtils.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/akka-http-core-2.13_10.1.8/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java b/instrumentation-security/akka-http-core-2.13_10.1.8/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java index 0a0d4fb68..cc2c65f3a 100644 --- a/instrumentation-security/akka-http-core-2.13_10.1.8/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java +++ b/instrumentation-security/akka-http-core-2.13_10.1.8/src/main/scala/akka/http/scaladsl/AkkaCoreUtils.java @@ -63,6 +63,9 @@ public static boolean acquireServletLockIfPossible() { public static void postProcessHttpRequest(Boolean isServletLockAcquired, StringBuilder responseBody, String contentType, String className, String methodName, Token token) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } token.linkAndExpire(); if(!isServletLockAcquired || !NewRelicSecurity.isHookProcessingActive()){ return; diff --git a/instrumentation-security/akka-http-core-2.13_10.1.8/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java b/instrumentation-security/akka-http-core-2.13_10.1.8/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java index ea8efb5ba..65d5da00b 100644 --- a/instrumentation-security/akka-http-core-2.13_10.1.8/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java +++ b/instrumentation-security/akka-http-core-2.13_10.1.8/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java @@ -20,6 +20,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -66,7 +67,7 @@ public Future bindAndHandleSync( public Future singleRequestImpl(HttpRequest httpRequest, HttpsConnectionContext connectionContext, ConnectionPoolSettings poolSettings, LoggingAdapter loggingAdapter) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase SecurityMetaData securityMetaData = NewRelicSecurity.getAgent().getSecurityMetaData(); @@ -167,9 +168,9 @@ private void releaseLock() { } } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { try { - return GenericHelper.acquireLockIfPossible(AkkaCoreUtils.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); + return GenericHelper.acquireLockIfPossible(httpRequest, AkkaCoreUtils.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); } catch (Throwable ignored) { } return false; 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 88a5c57bd..0f36ab5e6 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 @@ -63,6 +63,9 @@ public static boolean acquireServletLockIfPossible() { public static void postProcessHttpRequest(Boolean isServletLockAcquired, StringBuilder responseBody, String contentType, int responseCode, String className, String methodName, Token token) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } token.linkAndExpire(); if(!isServletLockAcquired || !NewRelicSecurity.isHookProcessingActive()){ return; diff --git a/instrumentation-security/akka-http-core-2.13_10.2.0/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java b/instrumentation-security/akka-http-core-2.13_10.2.0/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java index 623f578e7..41c69c12e 100644 --- a/instrumentation-security/akka-http-core-2.13_10.2.0/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java +++ b/instrumentation-security/akka-http-core-2.13_10.2.0/src/main/scala/akka/http/scaladsl/HttpExt_Instrumentation.java @@ -22,6 +22,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -74,7 +75,7 @@ public Future singleRequest(HttpRequest httpRequest, HttpsConnecti LoggingAdapter loggingAdapter) { final Segment segment = NewRelic.getAgent().getTransaction().startSegment("Akka", "singleRequest"); - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase SecurityMetaData securityMetaData = NewRelicSecurity.getAgent().getSecurityMetaData(); @@ -176,9 +177,9 @@ private void releaseLock() { } } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { try { - return GenericHelper.acquireLockIfPossible(AkkaCoreUtils.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); + return GenericHelper.acquireLockIfPossible(httpRequest, AkkaCoreUtils.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/apache-ldap/src/main/java/org/apache/directory/ldap/client/api/LdapAsyncConnection_Instrumentation.java b/instrumentation-security/apache-ldap/src/main/java/org/apache/directory/ldap/client/api/LdapAsyncConnection_Instrumentation.java index 3b61abe30..6c7a53102 100644 --- a/instrumentation-security/apache-ldap/src/main/java/org/apache/directory/ldap/client/api/LdapAsyncConnection_Instrumentation.java +++ b/instrumentation-security/apache-ldap/src/main/java/org/apache/directory/ldap/client/api/LdapAsyncConnection_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.LDAPOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -61,16 +62,16 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType caseType) { try { - return GenericHelper.acquireLockIfPossible(LDAPUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(caseType, LDAPUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } public SearchFuture searchAsync(Dn baseDn, String filter, SearchScope scope, String... attributes ) throws LdapException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(baseDn.getName(), filter, LDAPUtils.METHOD_SEARCH_ASYNC); @@ -90,7 +91,7 @@ public SearchFuture searchAsync(Dn baseDn, String filter, SearchScope scope, Str public SearchFuture searchAsync(String baseDn, String filter, SearchScope scope, String... attributes ) throws LdapException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(baseDn, filter, LDAPUtils.METHOD_SEARCH_ASYNC); @@ -109,7 +110,7 @@ public SearchFuture searchAsync(String baseDn, String filter, SearchScope scope, } public SearchFuture searchAsync( SearchRequest searchRequest ) throws LdapException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(searchRequest.getBase().getName(), searchRequest.getFilter().toString(), LDAPUtils.METHOD_SEARCH_ASYNC); diff --git a/instrumentation-security/apache-ldap/src/main/java/org/apache/directory/ldap/client/api/LdapConnection_Instrumentation.java b/instrumentation-security/apache-ldap/src/main/java/org/apache/directory/ldap/client/api/LdapConnection_Instrumentation.java index 12fe4c455..e8283a5fe 100644 --- a/instrumentation-security/apache-ldap/src/main/java/org/apache/directory/ldap/client/api/LdapConnection_Instrumentation.java +++ b/instrumentation-security/apache-ldap/src/main/java/org/apache/directory/ldap/client/api/LdapConnection_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.LDAPOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -61,16 +62,16 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType caseType) { try { - return GenericHelper.acquireLockIfPossible(LDAPUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(caseType, LDAPUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } public EntryCursor search(Dn baseDn, String filter, SearchScope scope, String... attributes ) throws LdapException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(baseDn.getName(), filter, LDAPUtils.METHOD_SEARCH); @@ -90,7 +91,7 @@ public EntryCursor search(Dn baseDn, String filter, SearchScope scope, String... public EntryCursor search( String baseDn, String filter, SearchScope scope, String... attributes ) throws LdapException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(baseDn, filter, LDAPUtils.METHOD_SEARCH); @@ -109,7 +110,7 @@ public EntryCursor search( String baseDn, String filter, SearchScope scope, Stri } public SearchCursor search(SearchRequest searchRequest ) throws LdapException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(searchRequest.getBase().getName(), searchRequest.getFilter().toString(), LDAPUtils.METHOD_SEARCH); diff --git a/instrumentation-security/async-http-client-2.0.0/src/main/java/com/newrelic/agent/security/instrumentation/org/asynchttpclient/AsynchttpHelper.java b/instrumentation-security/async-http-client-2.0.0/src/main/java/com/newrelic/agent/security/instrumentation/org/asynchttpclient/AsynchttpHelper.java index 94062e622..8088f8749 100644 --- a/instrumentation-security/async-http-client-2.0.0/src/main/java/com/newrelic/agent/security/instrumentation/org/asynchttpclient/AsynchttpHelper.java +++ b/instrumentation-security/async-http-client-2.0.0/src/main/java/com/newrelic/agent/security/instrumentation/org/asynchttpclient/AsynchttpHelper.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -36,15 +37,8 @@ public static boolean isLockAcquired() { return false; } - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && - !isLockAcquired()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), true); - return true; - } - } catch (Throwable ignored){} - return false; + public static boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, getNrSecCustomAttribName()); } public static void releaseLock() { diff --git a/instrumentation-security/async-http-client-2.0.0/src/main/java/org/asynchttpclient/AsyncHttpClient_Instrumentation.java b/instrumentation-security/async-http-client-2.0.0/src/main/java/org/asynchttpclient/AsyncHttpClient_Instrumentation.java index 9c12e6542..2a538a84b 100644 --- a/instrumentation-security/async-http-client-2.0.0/src/main/java/org/asynchttpclient/AsyncHttpClient_Instrumentation.java +++ b/instrumentation-security/async-http-client-2.0.0/src/main/java/org/asynchttpclient/AsyncHttpClient_Instrumentation.java @@ -9,6 +9,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -27,7 +28,7 @@ public abstract class AsyncHttpClient_Instrumentation { public ListenableFuture executeRequest(Request request, AsyncHandler handler) { URI uri = null; - boolean isLockAcquired = AsynchttpHelper.acquireLockIfPossible(); + boolean isLockAcquired = AsynchttpHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { try { diff --git a/instrumentation-security/camel-xpath/src/main/java/org/apache/camel/builder/BuilderSupport_Instrumentation.java b/instrumentation-security/camel-xpath/src/main/java/org/apache/camel/builder/BuilderSupport_Instrumentation.java index 5be2a50df..4c4b94439 100644 --- a/instrumentation-security/camel-xpath/src/main/java/org/apache/camel/builder/BuilderSupport_Instrumentation.java +++ b/instrumentation-security/camel-xpath/src/main/java/org/apache/camel/builder/BuilderSupport_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.XPathOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -56,15 +57,15 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType xpath) { try { - return GenericHelper.acquireLockIfPossible(XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(xpath, XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } public ValueBuilder xpath(String value, Class resultType, Namespaces namespaces) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(value, XPATHUtils.METHOD_XPATH); diff --git a/instrumentation-security/cassandra-datastax-3/src/main/java/com/datastax/driver/core/SessionManager_Instrumentation.java b/instrumentation-security/cassandra-datastax-3/src/main/java/com/datastax/driver/core/SessionManager_Instrumentation.java index 4a3fc9849..fef64e303 100644 --- a/instrumentation-security/cassandra-datastax-3/src/main/java/com/datastax/driver/core/SessionManager_Instrumentation.java +++ b/instrumentation-security/cassandra-datastax-3/src/main/java/com/datastax/driver/core/SessionManager_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -16,7 +17,7 @@ abstract class SessionManager_Instrumentation { abstract Configuration configuration(); public ResultSetFuture executeAsync(Statement statement) { - boolean isLockAcquired = CassandraUtils.acquireLockIfPossible(statement.hashCode()); + boolean isLockAcquired = CassandraUtils.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, statement.hashCode()); ResultSetFuture result = null; AbstractOperation cqlOperation = null; diff --git a/instrumentation-security/cassandra-datastax-3/src/main/java/com/datastax/driver/core/SimpleStatement_Instrumentation.java b/instrumentation-security/cassandra-datastax-3/src/main/java/com/datastax/driver/core/SimpleStatement_Instrumentation.java index 09621a27f..2d8e68f24 100644 --- a/instrumentation-security/cassandra-datastax-3/src/main/java/com/datastax/driver/core/SimpleStatement_Instrumentation.java +++ b/instrumentation-security/cassandra-datastax-3/src/main/java/com/datastax/driver/core/SimpleStatement_Instrumentation.java @@ -16,7 +16,7 @@ public abstract class SimpleStatement_Instrumentation { public SimpleStatement_Instrumentation(String query, Object... values) { - boolean isLockAcquired = CassandraUtils.acquireLockIfPossible(hashCode()); + boolean isLockAcquired = CassandraUtils.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, hashCode()); try{ if(isLockAcquired){ @@ -41,7 +41,7 @@ public SimpleStatement_Instrumentation(String query, Object... values) { } public SimpleStatement_Instrumentation(String query, Map values){ - boolean isLockAcquired = CassandraUtils.acquireLockIfPossible(hashCode()); + boolean isLockAcquired = CassandraUtils.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, hashCode()); try{ if(isLockAcquired){ diff --git a/instrumentation-security/cassandra-datastax-3/src/main/java/com/newrelic/agent/security/instrumentation/cassandra3/CassandraUtils.java b/instrumentation-security/cassandra-datastax-3/src/main/java/com/newrelic/agent/security/instrumentation/cassandra3/CassandraUtils.java index 8e886e480..f5f3343c4 100644 --- a/instrumentation-security/cassandra-datastax-3/src/main/java/com/newrelic/agent/security/instrumentation/cassandra3/CassandraUtils.java +++ b/instrumentation-security/cassandra-datastax-3/src/main/java/com/newrelic/agent/security/instrumentation/cassandra3/CassandraUtils.java @@ -29,9 +29,9 @@ public class CassandraUtils { public static final String NR_SEC_CASSANDRA_LOCK = "CASSANDRA_OPERATION_LOCK"; public static final String CASSANDRA_DATASTAX_3 = "CASSANDRA-DATASTAX-3"; - public static boolean acquireLockIfPossible(int hashcode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashcode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CASSANDRA_LOCK + hashcode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, NR_SEC_CASSANDRA_LOCK + hashcode); } catch (Exception ignored){ } return false; diff --git a/instrumentation-security/cassandra-datastax-4/src/main/java/com/datastax/driver/core/Session_Instrumentation.java b/instrumentation-security/cassandra-datastax-4/src/main/java/com/datastax/driver/core/Session_Instrumentation.java index 1fead9d5e..bf7e750b5 100644 --- a/instrumentation-security/cassandra-datastax-4/src/main/java/com/datastax/driver/core/Session_Instrumentation.java +++ b/instrumentation-security/cassandra-datastax-4/src/main/java/com/datastax/driver/core/Session_Instrumentation.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -17,7 +18,7 @@ public class Session_Instrumentation { public ResultT execute(RequestT request, GenericType resultType) { AbstractOperation cqlOperation = null; - boolean isLockAcquired = CassandraUtils.acquireLockIfPossible(request.hashCode()); + boolean isLockAcquired = CassandraUtils.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, request.hashCode()); ResultT result = null; try { diff --git a/instrumentation-security/cassandra-datastax-4/src/main/java/com/newrelic/agent/security/instrumentation/cassandra4/CassandraUtils.java b/instrumentation-security/cassandra-datastax-4/src/main/java/com/newrelic/agent/security/instrumentation/cassandra4/CassandraUtils.java index bab7aba4e..be4ff6d1a 100644 --- a/instrumentation-security/cassandra-datastax-4/src/main/java/com/newrelic/agent/security/instrumentation/cassandra4/CassandraUtils.java +++ b/instrumentation-security/cassandra-datastax-4/src/main/java/com/newrelic/agent/security/instrumentation/cassandra4/CassandraUtils.java @@ -31,9 +31,9 @@ public class CassandraUtils { public static final String NR_SEC_CASSANDRA_LOCK = "CASSANDRA_OPERATION_LOCK"; public static final String CASSANDRA_DATASTAX_4 = "CASSANDRA-DATASTAX-4"; - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CASSANDRA_LOCK, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, NR_SEC_CASSANDRA_LOCK, hashCode); } catch (Exception ignored){ } return false; diff --git a/instrumentation-security/commons-jxpath/src/main/java/org/apache/commons/jxpath/ri/compiler/JXPathContextReferenceImpl_Instrumentation.java b/instrumentation-security/commons-jxpath/src/main/java/org/apache/commons/jxpath/ri/compiler/JXPathContextReferenceImpl_Instrumentation.java index f3902044c..b4abba71d 100644 --- a/instrumentation-security/commons-jxpath/src/main/java/org/apache/commons/jxpath/ri/compiler/JXPathContextReferenceImpl_Instrumentation.java +++ b/instrumentation-security/commons-jxpath/src/main/java/org/apache/commons/jxpath/ri/compiler/JXPathContextReferenceImpl_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.XPathOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -18,7 +19,7 @@ public class JXPathContextReferenceImpl_Instrumentation { public Object getValue(String xpath, Expression expr) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(xpath, XPATHUtils.METHOD_GETVALUE); @@ -37,7 +38,7 @@ public Object getValue(String xpath, Expression expr) { } public Iterator iterate(String xpath, Expression expr) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(xpath, XPATHUtils.METHOD_ITERATE); @@ -56,7 +57,7 @@ public Iterator iterate(String xpath, Expression expr) { } public void removePath(String xpath, Expression expr) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(xpath, XPATHUtils.METHOD_REMOVE_PATH); @@ -73,7 +74,7 @@ public void removePath(String xpath, Expression expr) { } public void removeAll(String xpath, Expression expr) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(xpath, XPATHUtils.METHOD_REMOVE_ALL); @@ -129,9 +130,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType xpath) { try { - return GenericHelper.acquireLockIfPossible(XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(xpath, XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/dynamodb-1.11.390/src/main/java/com/amazonaws/services/dynamodbv2_1_11_390/AmazonDynamoDBClient_Instrumentation.java b/instrumentation-security/dynamodb-1.11.390/src/main/java/com/amazonaws/services/dynamodbv2_1_11_390/AmazonDynamoDBClient_Instrumentation.java index 5b45d9372..c5b72f8f1 100644 --- a/instrumentation-security/dynamodb-1.11.390/src/main/java/com/amazonaws/services/dynamodbv2_1_11_390/AmazonDynamoDBClient_Instrumentation.java +++ b/instrumentation-security/dynamodb-1.11.390/src/main/java/com/amazonaws/services/dynamodbv2_1_11_390/AmazonDynamoDBClient_Instrumentation.java @@ -16,6 +16,7 @@ import com.amazonaws.http.ExecutionContext; import com.amazonaws.http.HttpResponseHandler; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; import com.newrelic.agent.security.instrumentation.dynamodb_1_11_390.DynamoDBUtil; @@ -36,7 +37,7 @@ public AmazonDynamoDBClient_Instrumentation(ClientConfiguration clientConfigurat private Response doInvoke(Request request, HttpResponseHandler> responseHandler, ExecutionContext executionContext, URI discoveredEndpoint) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(request.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, request.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(request, this.getClass().getName()); } diff --git a/instrumentation-security/dynamodb-1.11.390/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_390/DynamoDBUtil.java b/instrumentation-security/dynamodb-1.11.390/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_390/DynamoDBUtil.java index 2766ce945..66a2d18af 100644 --- a/instrumentation-security/dynamodb-1.11.390/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_390/DynamoDBUtil.java +++ b/instrumentation-security/dynamodb-1.11.390/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_390/DynamoDBUtil.java @@ -25,6 +25,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.helper.DynamoDBRequest; import com.newrelic.api.agent.security.schema.operation.DynamoDBOperation; @@ -94,9 +95,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/dynamodb-1.11.453/src/main/java/com/amazonaws/services/dynamodbv2_1_11_453/AmazonDynamoDBClient_Instrumentation.java b/instrumentation-security/dynamodb-1.11.453/src/main/java/com/amazonaws/services/dynamodbv2_1_11_453/AmazonDynamoDBClient_Instrumentation.java index 840b4ea9f..6b4e8153b 100644 --- a/instrumentation-security/dynamodb-1.11.453/src/main/java/com/amazonaws/services/dynamodbv2_1_11_453/AmazonDynamoDBClient_Instrumentation.java +++ b/instrumentation-security/dynamodb-1.11.453/src/main/java/com/amazonaws/services/dynamodbv2_1_11_453/AmazonDynamoDBClient_Instrumentation.java @@ -16,6 +16,7 @@ import com.amazonaws.http.ExecutionContext; import com.amazonaws.http.HttpResponseHandler; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; import com.newrelic.agent.security.instrumentation.dynamodb_1_11_453.DynamoDBUtil; @@ -35,7 +36,7 @@ public AmazonDynamoDBClient_Instrumentation(ClientConfiguration clientConfigurat private Response doInvoke(Request request, HttpResponseHandler> responseHandler, ExecutionContext executionContext, URI discoveredEndpoint, URI uriFromEndpointTrait) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(request.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, request.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(request, this.getClass().getName()); } diff --git a/instrumentation-security/dynamodb-1.11.453/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_453/DynamoDBUtil.java b/instrumentation-security/dynamodb-1.11.453/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_453/DynamoDBUtil.java index d1d2bb4ac..0478947e0 100644 --- a/instrumentation-security/dynamodb-1.11.453/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_453/DynamoDBUtil.java +++ b/instrumentation-security/dynamodb-1.11.453/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_453/DynamoDBUtil.java @@ -25,6 +25,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.helper.DynamoDBRequest; import com.newrelic.api.agent.security.schema.operation.DynamoDBOperation; @@ -95,9 +96,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/dynamodb-1.11.459/src/main/java/com/amazonaws/services/dynamodbv2_1_11_459/AmazonDynamoDBClient_Instrumentation.java b/instrumentation-security/dynamodb-1.11.459/src/main/java/com/amazonaws/services/dynamodbv2_1_11_459/AmazonDynamoDBClient_Instrumentation.java index eece5aae0..dc82520ae 100644 --- a/instrumentation-security/dynamodb-1.11.459/src/main/java/com/amazonaws/services/dynamodbv2_1_11_459/AmazonDynamoDBClient_Instrumentation.java +++ b/instrumentation-security/dynamodb-1.11.459/src/main/java/com/amazonaws/services/dynamodbv2_1_11_459/AmazonDynamoDBClient_Instrumentation.java @@ -16,6 +16,7 @@ import com.amazonaws.http.ExecutionContext; import com.amazonaws.http.HttpResponseHandler; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; import com.newrelic.agent.security.instrumentation.dynamodb_1_11_459.DynamoDBUtil; @@ -35,7 +36,7 @@ public AmazonDynamoDBClient_Instrumentation(ClientConfiguration clientConfigurat private Response doInvoke(Request request, HttpResponseHandler> responseHandler, ExecutionContext executionContext, URI discoveredEndpoint, URI uriFromEndpointTrait) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(request.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, request.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(request, this.getClass().getName()); } diff --git a/instrumentation-security/dynamodb-1.11.459/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_459/DynamoDBUtil.java b/instrumentation-security/dynamodb-1.11.459/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_459/DynamoDBUtil.java index 352b50a1c..d981b6199 100644 --- a/instrumentation-security/dynamodb-1.11.459/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_459/DynamoDBUtil.java +++ b/instrumentation-security/dynamodb-1.11.459/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_459/DynamoDBUtil.java @@ -34,6 +34,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.helper.DynamoDBRequest; import com.newrelic.api.agent.security.schema.operation.DynamoDBOperation; @@ -104,9 +105,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/dynamodb-1.11.80/src/main/java/com/amazonaws/services/dynamodbv2_1_11_80/AmazonDynamoDBClient_Instrumentation.java b/instrumentation-security/dynamodb-1.11.80/src/main/java/com/amazonaws/services/dynamodbv2_1_11_80/AmazonDynamoDBClient_Instrumentation.java index 0464b2b1f..129f18b40 100644 --- a/instrumentation-security/dynamodb-1.11.80/src/main/java/com/amazonaws/services/dynamodbv2_1_11_80/AmazonDynamoDBClient_Instrumentation.java +++ b/instrumentation-security/dynamodb-1.11.80/src/main/java/com/amazonaws/services/dynamodbv2_1_11_80/AmazonDynamoDBClient_Instrumentation.java @@ -16,6 +16,7 @@ import com.amazonaws.http.ExecutionContext; import com.amazonaws.http.HttpResponseHandler; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; import com.newrelic.agent.security.instrumentation.dynamodb_1_11_80.DynamoDBUtil; @@ -35,7 +36,7 @@ public AmazonDynamoDBClient_Instrumentation(ClientConfiguration clientConfigurat private Response doInvoke(Request request, HttpResponseHandler> responseHandler, ExecutionContext executionContext) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(request.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, request.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(request, this.getClass().getName()); } diff --git a/instrumentation-security/dynamodb-1.11.80/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_80/DynamoDBUtil.java b/instrumentation-security/dynamodb-1.11.80/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_80/DynamoDBUtil.java index 13e1a39d8..44d708f95 100644 --- a/instrumentation-security/dynamodb-1.11.80/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_80/DynamoDBUtil.java +++ b/instrumentation-security/dynamodb-1.11.80/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_1_11_80/DynamoDBUtil.java @@ -25,6 +25,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.helper.DynamoDBRequest; import com.newrelic.api.agent.security.schema.operation.DynamoDBOperation; @@ -94,9 +95,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/dynamodb-2.1.0/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_210/DynamoDBUtil.java b/instrumentation-security/dynamodb-2.1.0/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_210/DynamoDBUtil.java index cab84ab53..1e59b670f 100644 --- a/instrumentation-security/dynamodb-2.1.0/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_210/DynamoDBUtil.java +++ b/instrumentation-security/dynamodb-2.1.0/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_210/DynamoDBUtil.java @@ -11,6 +11,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.helper.DynamoDBRequest; import com.newrelic.api.agent.security.schema.operation.DynamoDBOperation; @@ -96,7 +97,7 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { diff --git a/instrumentation-security/dynamodb-2.1.0/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java b/instrumentation-security/dynamodb-2.1.0/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java index 402aeac1b..f977f3aa9 100644 --- a/instrumentation-security/dynamodb-2.1.0/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java +++ b/instrumentation-security/dynamodb-2.1.0/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java @@ -8,6 +8,7 @@ package software.amazon.awssdk.core.client.handler; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -24,7 +25,7 @@ public class AsyncClientHandler_Instrumentation { public CompletableFuture execute( ClientExecutionParams executionParams) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } @@ -44,7 +45,7 @@ public Complet ClientExecutionParams executionParams, AsyncResponseTransformer asyncResponseTransformer) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } diff --git a/instrumentation-security/dynamodb-2.1.0/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java b/instrumentation-security/dynamodb-2.1.0/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java index 44c672ec0..412f6d137 100644 --- a/instrumentation-security/dynamodb-2.1.0/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java +++ b/instrumentation-security/dynamodb-2.1.0/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java @@ -8,6 +8,7 @@ package software.amazon.awssdk.core.client.handler; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -22,7 +23,7 @@ public class SyncClientHandler_Instrumentation { public OutputT execute( ClientExecutionParams executionParams) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } @@ -42,7 +43,7 @@ public ReturnT ClientExecutionParams executionParams, ResponseTransformer responseTransformer) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } diff --git a/instrumentation-security/dynamodb-2.1.2/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_212/DynamoDBUtil.java b/instrumentation-security/dynamodb-2.1.2/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_212/DynamoDBUtil.java index 1f85651cc..73f8d5691 100644 --- a/instrumentation-security/dynamodb-2.1.2/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_212/DynamoDBUtil.java +++ b/instrumentation-security/dynamodb-2.1.2/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_212/DynamoDBUtil.java @@ -11,6 +11,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.helper.DynamoDBRequest; import com.newrelic.api.agent.security.schema.operation.DynamoDBOperation; @@ -105,9 +106,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/dynamodb-2.1.2/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java b/instrumentation-security/dynamodb-2.1.2/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java index 11de52c85..0543f2a75 100644 --- a/instrumentation-security/dynamodb-2.1.2/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java +++ b/instrumentation-security/dynamodb-2.1.2/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java @@ -9,10 +9,10 @@ import com.newrelic.agent.security.instrumentation.dynamodb_212.DynamoDBUtil; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; -import com.newrelic.agent.security.instrumentation.dynamodb_212.DynamoDBUtil; import software.amazon.awssdk.core.SdkRequest; import software.amazon.awssdk.core.SdkResponse; import software.amazon.awssdk.core.async.AsyncResponseTransformer; @@ -25,7 +25,7 @@ public class AsyncClientHandler_Instrumentation { public CompletableFuture execute( ClientExecutionParams executionParams) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } @@ -45,7 +45,7 @@ public Complet ClientExecutionParams executionParams, AsyncResponseTransformer asyncResponseTransformer) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } diff --git a/instrumentation-security/dynamodb-2.1.2/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java b/instrumentation-security/dynamodb-2.1.2/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java index 5f2c86e2f..8762c91b2 100644 --- a/instrumentation-security/dynamodb-2.1.2/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java +++ b/instrumentation-security/dynamodb-2.1.2/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java @@ -9,10 +9,10 @@ import com.newrelic.agent.security.instrumentation.dynamodb_212.DynamoDBUtil; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; -import com.newrelic.agent.security.instrumentation.dynamodb_212.DynamoDBUtil; import software.amazon.awssdk.core.SdkRequest; import software.amazon.awssdk.core.SdkResponse; import software.amazon.awssdk.core.sync.ResponseTransformer; @@ -23,7 +23,7 @@ public class SyncClientHandler_Instrumentation { public OutputT execute( ClientExecutionParams executionParams) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } @@ -43,7 +43,7 @@ public ReturnT ClientExecutionParams executionParams, ResponseTransformer responseTransformer) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } diff --git a/instrumentation-security/dynamodb-2.15.34/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_215/DynamoDBUtil.java b/instrumentation-security/dynamodb-2.15.34/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_215/DynamoDBUtil.java index 2e26b9bbe..35c9cc87a 100644 --- a/instrumentation-security/dynamodb-2.15.34/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_215/DynamoDBUtil.java +++ b/instrumentation-security/dynamodb-2.15.34/src/main/java/com/newrelic/agent/security/instrumentation/dynamodb_215/DynamoDBUtil.java @@ -11,6 +11,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.helper.DynamoDBRequest; import com.newrelic.api.agent.security.schema.operation.DynamoDBOperation; @@ -110,9 +111,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/dynamodb-2.15.34/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java b/instrumentation-security/dynamodb-2.15.34/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java index 14c57f588..107928d21 100644 --- a/instrumentation-security/dynamodb-2.15.34/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java +++ b/instrumentation-security/dynamodb-2.15.34/src/main/java/software/amazon/awssdk/core/client/handler/AsyncClientHandler_Instrumentation.java @@ -9,10 +9,10 @@ import com.newrelic.agent.security.instrumentation.dynamodb_215.DynamoDBUtil; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; -import com.newrelic.agent.security.instrumentation.dynamodb_215.DynamoDBUtil; import software.amazon.awssdk.core.SdkRequest; import software.amazon.awssdk.core.SdkResponse; import software.amazon.awssdk.core.async.AsyncResponseTransformer; @@ -25,7 +25,7 @@ public class AsyncClientHandler_Instrumentation { public CompletableFuture execute( ClientExecutionParams executionParams) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } @@ -45,7 +45,7 @@ public Complet ClientExecutionParams executionParams, AsyncResponseTransformer asyncResponseTransformer) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } diff --git a/instrumentation-security/dynamodb-2.15.34/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java b/instrumentation-security/dynamodb-2.15.34/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java index 5d38c0b9d..d312b10c5 100644 --- a/instrumentation-security/dynamodb-2.15.34/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java +++ b/instrumentation-security/dynamodb-2.15.34/src/main/java/software/amazon/awssdk/core/client/handler/SyncClientHandler_Instrumentation.java @@ -9,10 +9,10 @@ import com.newrelic.agent.security.instrumentation.dynamodb_215.DynamoDBUtil; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; -import com.newrelic.agent.security.instrumentation.dynamodb_215.DynamoDBUtil; import software.amazon.awssdk.core.SdkRequest; import software.amazon.awssdk.core.SdkResponse; import software.amazon.awssdk.core.sync.ResponseTransformer; @@ -23,7 +23,7 @@ public class SyncClientHandler_Instrumentation { public OutputT execute( ClientExecutionParams executionParams) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } @@ -43,7 +43,7 @@ public ReturnT ClientExecutionParams executionParams, ResponseTransformer responseTransformer) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = DynamoDBUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = DynamoDBUtil.processDynamoDBRequest(executionParams, this.getClass().getName()); } diff --git a/instrumentation-security/file-low-priority-instrumentation/src/main/java/com/newrelic/agent/security/instrumentation/random/java/io/File_Instrumentation.java b/instrumentation-security/file-low-priority-instrumentation/src/main/java/com/newrelic/agent/security/instrumentation/random/java/io/File_Instrumentation.java index 44f8b3183..989790c66 100644 --- a/instrumentation-security/file-low-priority-instrumentation/src/main/java/com/newrelic/agent/security/instrumentation/random/java/io/File_Instrumentation.java +++ b/instrumentation-security/file-low-priority-instrumentation/src/main/java/com/newrelic/agent/security/instrumentation/random/java/io/File_Instrumentation.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.FileOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -22,7 +23,7 @@ public abstract class File_Instrumentation { public abstract String getAbsolutePath(); public boolean exists() { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); boolean isOwaspHookEnabled = NewRelicSecurity.getAgent().isLowPriorityInstrumentationEnabled(); AbstractOperation operation = null; @@ -43,19 +44,12 @@ public boolean exists() { return returnVal; } - private static boolean acquireFileLockIfPossible() { - try { - return FileHelper.acquireFileLockIfPossible(); - } catch (Throwable ignored) { - } - return false; + private static boolean acquireFileLockIfPossible(VulnerabilityCaseType fileOperation) { + return GenericHelper.acquireLockIfPossible(fileOperation, FileHelper.getNrSecCustomAttribName()); } private static void releaseFileLock() { - try { - FileHelper.releaseFileLock(); - } catch (Throwable ignored) { - } + GenericHelper.releaseLock(FileHelper.getNrSecCustomAttribName()); } diff --git a/instrumentation-security/file-operation/src/main/java/java/io/FileInputStream_Instrumentation.java b/instrumentation-security/file-operation/src/main/java/java/io/FileInputStream_Instrumentation.java index a4a9fb3cf..817531e2d 100644 --- a/instrumentation-security/file-operation/src/main/java/java/io/FileInputStream_Instrumentation.java +++ b/instrumentation-security/file-operation/src/main/java/java/io/FileInputStream_Instrumentation.java @@ -11,6 +11,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.FileHelper; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.FileOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -22,7 +23,7 @@ public abstract class FileInputStream_Instrumentation { private void open(String name) throws FileNotFoundException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(name); @@ -37,17 +38,12 @@ private void open(String name) throws FileNotFoundException { registerExitOperation(isFileLockAcquired, operation); } - private boolean acquireFileLockIfPossible() { - try { - return FileHelper.acquireFileLockIfPossible(); - } catch (Throwable ignored) {} - return false; + private static boolean acquireFileLockIfPossible(VulnerabilityCaseType fileOperation) { + return GenericHelper.acquireLockIfPossible(fileOperation, FileHelper.getNrSecCustomAttribName()); } - private void releaseFileLock() { - try { - FileHelper.releaseFileLock(); - } catch (Throwable e) {} + private static void releaseFileLock() { + GenericHelper.releaseLock(FileHelper.getNrSecCustomAttribName()); } private void registerExitOperation(boolean isProcessingAllowed, AbstractOperation operation) { diff --git a/instrumentation-security/file-operation/src/main/java/java/io/FileOutputStream_Instrumentation.java b/instrumentation-security/file-operation/src/main/java/java/io/FileOutputStream_Instrumentation.java index 1c9a794f5..ae6e2e885 100644 --- a/instrumentation-security/file-operation/src/main/java/java/io/FileOutputStream_Instrumentation.java +++ b/instrumentation-security/file-operation/src/main/java/java/io/FileOutputStream_Instrumentation.java @@ -11,6 +11,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.FileHelper; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.FileOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -23,7 +24,7 @@ public abstract class FileOutputStream_Instrumentation { private void open(String name, boolean append) throws FileNotFoundException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(name); @@ -38,17 +39,12 @@ private void open(String name, boolean append) registerExitOperation(isFileLockAcquired, operation); } - private boolean acquireFileLockIfPossible() { - try { - return FileHelper.acquireFileLockIfPossible(); - } catch (Throwable ignored) {} - return false; + private static boolean acquireFileLockIfPossible(VulnerabilityCaseType fileOperation) { + return GenericHelper.acquireLockIfPossible(fileOperation, FileHelper.getNrSecCustomAttribName()); } - private void releaseFileLock() { - try { - FileHelper.releaseFileLock(); - } catch (Throwable e) {} + private static void releaseFileLock() { + GenericHelper.releaseLock(FileHelper.getNrSecCustomAttribName()); } private void registerExitOperation(boolean isProcessingAllowed, AbstractOperation operation) { diff --git a/instrumentation-security/file-operation/src/main/java/java/io/File_Instrumentation.java b/instrumentation-security/file-operation/src/main/java/java/io/File_Instrumentation.java index 8a76fc621..6c7372d77 100644 --- a/instrumentation-security/file-operation/src/main/java/java/io/File_Instrumentation.java +++ b/instrumentation-security/file-operation/src/main/java/java/io/File_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.FileHelper; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.FileOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -18,7 +19,7 @@ public abstract class File_Instrumentation { public boolean createNewFile() throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_CREATE_NEW_FILE, false, this); @@ -36,7 +37,7 @@ public boolean createNewFile() throws IOException { } public boolean delete() { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_DELETE, false, this); @@ -54,7 +55,7 @@ public boolean delete() { } public void deleteOnExit() { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_DELETE_ON_EXIT, false, this); @@ -70,7 +71,7 @@ public void deleteOnExit() { } public String[] list() { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_LIST, false, this); @@ -88,7 +89,7 @@ public String[] list() { } public String[] list(FilenameFilter filter) { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_LIST, false, this); @@ -106,7 +107,7 @@ public String[] list(FilenameFilter filter) { } public File[] listFiles() { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_LISTFILES, false, this); @@ -124,7 +125,7 @@ public File[] listFiles() { } public File[] listFiles(FilenameFilter filter) { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_LISTFILES, false, this); @@ -142,7 +143,7 @@ public File[] listFiles(FilenameFilter filter) { } public File[] listFiles(FileFilter filter) { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_LISTFILES, false, this); @@ -160,7 +161,7 @@ public File[] listFiles(FileFilter filter) { } public boolean mkdir() { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_MKDIR, false, this); @@ -178,7 +179,7 @@ public boolean mkdir() { } public boolean mkdirs() { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_MKDIRS, false, this); @@ -196,7 +197,7 @@ public boolean mkdirs() { } public boolean renameTo(File_Instrumentation dest) { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_RENAME_TO, false, this, dest); @@ -214,7 +215,7 @@ public boolean renameTo(File_Instrumentation dest) { } public boolean setReadOnly() { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_SET_READ_ONLY, false, this); @@ -232,7 +233,7 @@ public boolean setReadOnly() { } public boolean setWritable(boolean writable, boolean ownerOnly) { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_SET_WRITABLE, false, this); @@ -250,7 +251,7 @@ public boolean setWritable(boolean writable, boolean ownerOnly) { } public boolean setWritable(boolean writable) { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_SET_WRITABLE, false, this); @@ -268,7 +269,7 @@ public boolean setWritable(boolean writable) { } public boolean setReadable(boolean readable, boolean ownerOnly) { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_SET_READABLE, false, this); @@ -286,7 +287,7 @@ public boolean setReadable(boolean readable, boolean ownerOnly) { } public boolean setReadable(boolean readable) { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_SET_READABLE, false, this); @@ -304,7 +305,7 @@ public boolean setReadable(boolean readable) { } public boolean setExecutable(boolean executable, boolean ownerOnly) { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_SET_EXECUTABLE, false, this); @@ -322,7 +323,7 @@ public boolean setExecutable(boolean executable, boolean ownerOnly) { } public boolean setExecutable(boolean executable) { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_SET_EXECUTABLE, false, this); @@ -345,19 +346,12 @@ public boolean setExecutable(boolean executable) { public abstract String getAbsolutePath(); - private static boolean acquireFileLockIfPossible() { - try { - return FileHelper.acquireFileLockIfPossible(); - } catch (Throwable ignored) { - } - return false; + private static boolean acquireFileLockIfPossible(VulnerabilityCaseType fileOperation) { + return GenericHelper.acquireLockIfPossible(fileOperation, FileHelper.getNrSecCustomAttribName()); } private static void releaseFileLock() { - try { - FileHelper.releaseFileLock(); - } catch (Throwable ignored) { - } + GenericHelper.releaseLock(FileHelper.getNrSecCustomAttribName()); } diff --git a/instrumentation-security/file-operation/src/main/java/java/io/RandomAccessFile_Instrumentation.java b/instrumentation-security/file-operation/src/main/java/java/io/RandomAccessFile_Instrumentation.java index 7f3760268..85517df32 100644 --- a/instrumentation-security/file-operation/src/main/java/java/io/RandomAccessFile_Instrumentation.java +++ b/instrumentation-security/file-operation/src/main/java/java/io/RandomAccessFile_Instrumentation.java @@ -11,6 +11,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.FileHelper; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.FileOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -22,7 +23,7 @@ public abstract class RandomAccessFile_Instrumentation { private void open(String name, int mode) throws FileNotFoundException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(name); @@ -37,17 +38,12 @@ private void open(String name, int mode) throws FileNotFoundException { registerExitOperation(isFileLockAcquired, operation); } - private boolean acquireFileLockIfPossible() { - try { - return FileHelper.acquireFileLockIfPossible(); - } catch (Throwable ignored) {} - return false; + private static boolean acquireFileLockIfPossible(VulnerabilityCaseType fileOperation) { + return GenericHelper.acquireLockIfPossible(fileOperation, FileHelper.getNrSecCustomAttribName()); } - private void releaseFileLock() { - try { - FileHelper.releaseFileLock(); - } catch (Throwable e) {} + private static void releaseFileLock() { + GenericHelper.releaseLock(FileHelper.getNrSecCustomAttribName()); } private void registerExitOperation(boolean isProcessingAllowed, AbstractOperation operation) { diff --git a/instrumentation-security/file-operation/src/main/java/java/nio/file/Files_Instrumentation.java b/instrumentation-security/file-operation/src/main/java/java/nio/file/Files_Instrumentation.java index 28181b03b..d2a88246b 100644 --- a/instrumentation-security/file-operation/src/main/java/java/nio/file/Files_Instrumentation.java +++ b/instrumentation-security/file-operation/src/main/java/java/nio/file/Files_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.FileHelper; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.FileOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -26,7 +27,7 @@ public static Path setPosixFilePermissions(Path path, Set perms) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if (isFileLockAcquired) { operation = preprocessSecurityHook(false, FileHelper.METHOD_NAME_SETPOSIXFILEPERMISSIONS, false, path.toFile()); @@ -43,19 +44,12 @@ public static Path setPosixFilePermissions(Path path, return returnVal; } - private static boolean acquireFileLockIfPossible() { - try { - return FileHelper.acquireFileLockIfPossible(); - } catch (Throwable ignored) { - } - return false; + private static boolean acquireFileLockIfPossible(VulnerabilityCaseType fileOperation) { + return GenericHelper.acquireLockIfPossible(fileOperation, FileHelper.getNrSecCustomAttribName()); } private static void releaseFileLock() { - try { - FileHelper.releaseFileLock(); - } catch (Throwable ignored) { - } + GenericHelper.releaseLock(FileHelper.getNrSecCustomAttribName()); } diff --git a/instrumentation-security/file-operation/src/main/java/java/nio/file/spi/FileSystemProvider_Instrumentation.java b/instrumentation-security/file-operation/src/main/java/java/nio/file/spi/FileSystemProvider_Instrumentation.java index 81db76b0a..36b95a300 100644 --- a/instrumentation-security/file-operation/src/main/java/java/nio/file/spi/FileSystemProvider_Instrumentation.java +++ b/instrumentation-security/file-operation/src/main/java/java/nio/file/spi/FileSystemProvider_Instrumentation.java @@ -11,6 +11,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.FileHelper; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.FileOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -37,7 +38,7 @@ public abstract class FileSystemProvider_Instrumentation { public void copy(Path source, Path target, CopyOption... options) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if(isFileLockAcquired) { operation = preprocessSecurityHook(FileHelper.FILE_COPY, source, target); @@ -55,7 +56,7 @@ public void copy(Path source, Path target, CopyOption... options) public InputStream newInputStream(Path path, OpenOption... options) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; InputStream returnData; if(isFileLockAcquired) { @@ -75,7 +76,7 @@ public InputStream newInputStream(Path path, OpenOption... options) public OutputStream newOutputStream(Path path, OpenOption... options) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; OutputStream returnData; if(isFileLockAcquired) { @@ -97,7 +98,7 @@ public FileChannel newFileChannel(Path path, FileAttribute... attrs) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; FileChannel returnData; if(isFileLockAcquired) { @@ -120,7 +121,7 @@ public AsynchronousFileChannel newAsynchronousFileChannel(Path path, FileAttribute... attrs) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; AsynchronousFileChannel returnData; if(isFileLockAcquired) { @@ -140,7 +141,7 @@ public AsynchronousFileChannel newAsynchronousFileChannel(Path path, public SeekableByteChannel newByteChannel(Path path, Set options, FileAttribute... attrs) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; SeekableByteChannel returnData; if(isFileLockAcquired) { @@ -159,7 +160,7 @@ public SeekableByteChannel newByteChannel(Path path, public DirectoryStream newDirectoryStream(Path dir, DirectoryStream.Filter filter) throws IOException{ - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; DirectoryStream returnData; if(isFileLockAcquired) { @@ -178,7 +179,7 @@ public DirectoryStream newDirectoryStream(Path dir, public void createDirectory(Path dir, FileAttribute... attrs) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if(isFileLockAcquired) { operation = preprocessSecurityHook(FileHelper.CREATE_DIRECTORY, dir); @@ -196,7 +197,7 @@ public void createDirectory(Path dir, FileAttribute... attrs) public void createSymbolicLink(Path link, Path target, FileAttribute... attrs) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if(isFileLockAcquired) { operation = preprocessSecurityHook(FileHelper.CREATE_SYMBOLIC_LINK, link, target); @@ -212,7 +213,7 @@ public void createSymbolicLink(Path link, Path target, FileAttribute... attrs } public void createLink(Path link, Path existing) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if(isFileLockAcquired) { operation = preprocessSecurityHook(FileHelper.CREATE_LINK, link, existing); @@ -228,7 +229,7 @@ public void createLink(Path link, Path existing) throws IOException { } public void delete(Path path) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if(isFileLockAcquired) { operation = preprocessSecurityHook(FileHelper.DELETE, path); @@ -244,7 +245,7 @@ public void delete(Path path) throws IOException { } public boolean deleteIfExists(Path path) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; boolean returnData; if(isFileLockAcquired) { @@ -263,7 +264,7 @@ public boolean deleteIfExists(Path path) throws IOException { public void move(Path source, Path target, CopyOption... options) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if(isFileLockAcquired) { operation = preprocessSecurityHook(FileHelper.MOVE, source, target); @@ -281,7 +282,7 @@ public void move(Path source, Path target, CopyOption... options) public void setAttribute(Path path, String attribute, Object value, LinkOption... options) throws IOException { - boolean isFileLockAcquired = acquireFileLockIfPossible(); + boolean isFileLockAcquired = acquireFileLockIfPossible(VulnerabilityCaseType.FILE_OPERATION); AbstractOperation operation = null; if(isFileLockAcquired) { operation = preprocessSecurityHook(FileHelper.SET_ATTRIBUTE, path); @@ -295,17 +296,13 @@ public void setAttribute(Path path, String attribute, } registerExitOperation(operation, isFileLockAcquired); } - private void releaseFileLock() { - try { - FileHelper.releaseFileLock(); - } catch (Throwable ignored){} + + private static boolean acquireFileLockIfPossible(VulnerabilityCaseType fileOperation) { + return GenericHelper.acquireLockIfPossible(fileOperation, FileHelper.getNrSecCustomAttribName()); } - private boolean acquireFileLockIfPossible() { - try { - return FileHelper.acquireFileLockIfPossible(); - } catch (Throwable ignored){} - return false; + private static void releaseFileLock() { + GenericHelper.releaseLock(FileHelper.getNrSecCustomAttribName()); } diff --git a/instrumentation-security/graalvm-jsinjection-19.0.0/src/main/java/com/oracle/truffle/polyglot/PolyglotContextImpl_Instrumentation.java b/instrumentation-security/graalvm-jsinjection-19.0.0/src/main/java/com/oracle/truffle/polyglot/PolyglotContextImpl_Instrumentation.java index 84d8f6bdf..7d7d7c6a4 100644 --- a/instrumentation-security/graalvm-jsinjection-19.0.0/src/main/java/com/oracle/truffle/polyglot/PolyglotContextImpl_Instrumentation.java +++ b/instrumentation-security/graalvm-jsinjection-19.0.0/src/main/java/com/oracle/truffle/polyglot/PolyglotContextImpl_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.JSInjectionOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -20,7 +21,7 @@ final class PolyglotContextImpl_Instrumentation { public Value eval(String languageId, Object sourceImpl) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.JAVASCRIPT_INJECTION); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(languageId, sourceImpl, JSEngineUtils.METHOD_EVAL); @@ -79,9 +80,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType javascriptInjection) { try { - return GenericHelper.acquireLockIfPossible(JSEngineUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(javascriptInjection, JSEngineUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/graalvm-jsinjection-22.0.0/src/main/java/com/oracle/truffle/polyglot/PolyglotContextImpl_Instrumentation.java b/instrumentation-security/graalvm-jsinjection-22.0.0/src/main/java/com/oracle/truffle/polyglot/PolyglotContextImpl_Instrumentation.java index 12ac4f31f..43a5cc51c 100644 --- a/instrumentation-security/graalvm-jsinjection-22.0.0/src/main/java/com/oracle/truffle/polyglot/PolyglotContextImpl_Instrumentation.java +++ b/instrumentation-security/graalvm-jsinjection-22.0.0/src/main/java/com/oracle/truffle/polyglot/PolyglotContextImpl_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.JSInjectionOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -20,7 +21,7 @@ final class PolyglotContextImpl_Instrumentation { public Value eval(String languageId, org.graalvm.polyglot.Source source) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.JAVASCRIPT_INJECTION); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(languageId, source, JSEngineUtils.METHOD_EVAL); @@ -78,9 +79,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType javascriptInjection) { try { - return GenericHelper.acquireLockIfPossible(JSEngineUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(javascriptInjection, JSEngineUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/GrpcClientUtils.java b/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/GrpcClientUtils.java index 1733cca6e..fb120f290 100644 --- a/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/GrpcClientUtils.java +++ b/instrumentation-security/grpc-1.22.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1220/GrpcClientUtils.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -67,34 +68,15 @@ public static AbstractOperation preprocessSecurityHook(String uri, Metadata meta public static void releaseLock() { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttrName(), null); - } - } catch (Throwable ignored) { - } + GenericHelper.releaseLock(getNrSecCustomAttrName()); } private static String getNrSecCustomAttrName() { return GrpcClientUtils.NR_SEC_CUSTOM_ATTRIB_NAME+Thread.currentThread().getId(); } - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && - !isLockAcquired(getNrSecCustomAttrName())) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttrName(), true); - return true; - } - } catch (Throwable ignored){} - return false; + public static boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, getNrSecCustomAttrName()); } - private static boolean isLockAcquired(String nrSecCustomAttrName) { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(nrSecCustomAttrName, Boolean.class)); - } catch (Throwable ignored) {} - return false; - } } 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 bcd9e3388..6a0f04108 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 @@ -91,6 +91,9 @@ public static void preprocessSecurityHook(ServerStream_Instrumentat public static void postProcessSecurityHook(Metadata metadata, int statusCode, String className, String methodName) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive()) { return; } diff --git a/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/ClientCall_Instrumentation.java b/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/ClientCall_Instrumentation.java index 0291a1817..47f49a1f1 100644 --- a/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/ClientCall_Instrumentation.java +++ b/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/ClientCall_Instrumentation.java @@ -3,6 +3,7 @@ import com.newrelic.agent.security.instrumentation.grpc1220.GrpcClientUtils; import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.NewField; @@ -20,7 +21,7 @@ public abstract class ClientCall_Instrumentation { MethodDescriptor methodDescriptor = null; public void start(ClientCall.Listener var1, Metadata var2) { - boolean isLockAcquired = GrpcClientUtils.acquireLockIfPossible(); + boolean isLockAcquired = GrpcClientUtils.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if (isLockAcquired) { diff --git a/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/GrpcClientUtils.java b/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/GrpcClientUtils.java index 8e6adaee6..181f8f155 100644 --- a/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/GrpcClientUtils.java +++ b/instrumentation-security/grpc-1.4.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc140/GrpcClientUtils.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -67,34 +68,14 @@ public static AbstractOperation preprocessSecurityHook(String uri, Metadata meta public static void releaseLock() { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttrName(), null); - } - } catch (Throwable ignored) { - } + GenericHelper.releaseLock(getNrSecCustomAttrName()); } private static String getNrSecCustomAttrName() { return GrpcClientUtils.NR_SEC_CUSTOM_ATTRIB_NAME+Thread.currentThread().getId(); } - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && - !isLockAcquired(getNrSecCustomAttrName())) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttrName(), true); - return true; - } - } catch (Throwable ignored){} - return false; - } - - private static boolean isLockAcquired(String nrSecCustomAttrName) { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(nrSecCustomAttrName, Boolean.class)); - } catch (Throwable ignored) {} - return false; + public static boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, getNrSecCustomAttrName()); } } 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 4481b3f70..e4e9431d4 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 @@ -95,6 +95,9 @@ public static void preprocessSecurityHook(ServerStream_Instrumentat public static void postProcessSecurityHook(Metadata metadata, int statusCode, String className, String methodName) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive()) { return; } diff --git a/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/ClientCall_Instrumentation.java b/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/ClientCall_Instrumentation.java index ca4b45320..dd1b90d11 100644 --- a/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/ClientCall_Instrumentation.java +++ b/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/ClientCall_Instrumentation.java @@ -3,6 +3,7 @@ import com.newrelic.agent.security.instrumentation.grpc140.GrpcClientUtils; import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.NewField; @@ -20,7 +21,7 @@ public abstract class ClientCall_Instrumentation { MethodDescriptor methodDescriptor = null; public void start(ClientCall.Listener var1, Metadata var2) { - boolean isLockAcquired = GrpcClientUtils.acquireLockIfPossible(); + boolean isLockAcquired = GrpcClientUtils.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if (isLockAcquired) { diff --git a/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/GrpcClientUtils.java b/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/GrpcClientUtils.java index 30c9953b7..3145a0cad 100644 --- a/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/GrpcClientUtils.java +++ b/instrumentation-security/grpc-1.40.0/src/main/java/com/newrelic/agent/security/instrumentation/grpc1400/GrpcClientUtils.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -67,33 +68,15 @@ public static AbstractOperation preprocessSecurityHook(String uri, Metadata meta public static void releaseLock() { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttrName(), null); - } - } catch (Throwable ignored){} + GenericHelper.releaseLock(getNrSecCustomAttrName()); } private static String getNrSecCustomAttrName() { return GrpcClientUtils.NR_SEC_CUSTOM_ATTRIB_NAME+Thread.currentThread().getId(); } - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && - !isLockAcquired(getNrSecCustomAttrName())) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttrName(), true); - return true; - } - } catch (Throwable ignored){} - return false; + public static boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, getNrSecCustomAttrName()); } - private static boolean isLockAcquired(String nrSecCustomAttrName) { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(nrSecCustomAttrName, Boolean.class)); - } catch (Throwable ignored) {} - return false; - } } 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 441865d70..90cb822dd 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 @@ -90,6 +90,9 @@ public static void preprocessSecurityHook(ServerStream_Instrumentat public static void postProcessSecurityHook(Metadata metadata, int statusCode, String className, String methodName) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive()) { return; } diff --git a/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/ClientCall_Instrumentation.java b/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/ClientCall_Instrumentation.java index ebd0d6ec4..79ee376e0 100644 --- a/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/ClientCall_Instrumentation.java +++ b/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/ClientCall_Instrumentation.java @@ -3,6 +3,7 @@ import com.newrelic.agent.security.instrumentation.grpc1400.GrpcClientUtils; import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.NewField; @@ -20,7 +21,7 @@ public abstract class ClientCall_Instrumentation { MethodDescriptor csecMethodDescriptor = null; public void start(ClientCall.Listener var1, Metadata var2) { - boolean isLockAcquired = GrpcClientUtils.acquireLockIfPossible(); + boolean isLockAcquired = GrpcClientUtils.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if (isLockAcquired) { diff --git a/instrumentation-security/http-async-client-4/src/main/java/com/newrelic/agent/security/instrumentation/httpasyncclient4/HttpAsyncClient4_Instrumentation.java b/instrumentation-security/http-async-client-4/src/main/java/com/newrelic/agent/security/instrumentation/httpasyncclient4/HttpAsyncClient4_Instrumentation.java index 86ec258c6..63391d32a 100644 --- a/instrumentation-security/http-async-client-4/src/main/java/com/newrelic/agent/security/instrumentation/httpasyncclient4/HttpAsyncClient4_Instrumentation.java +++ b/instrumentation-security/http-async-client-4/src/main/java/com/newrelic/agent/security/instrumentation/httpasyncclient4/HttpAsyncClient4_Instrumentation.java @@ -13,6 +13,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -39,7 +40,7 @@ public class HttpAsyncClient4_Instrumentation { public Future execute(HttpAsyncRequestProducer requestProducer, HttpAsyncResponseConsumer responseConsumer, HttpContext context, FutureCallback callback) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -65,7 +66,7 @@ public Future execute(HttpAsyncRequestProducer requestProducer, HttpAsync } public Future execute(HttpAsyncRequestProducer requestProducer, HttpAsyncResponseConsumer responseConsumer, FutureCallback callback) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -91,7 +92,7 @@ public Future execute(HttpAsyncRequestProducer requestProducer, HttpAsync } public Future execute(HttpHost target, HttpRequest request, HttpContext context, FutureCallback callback) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase @@ -119,7 +120,7 @@ public Future execute(HttpHost target, HttpRequest request, HttpCo } public Future execute(HttpHost target, HttpRequest request, FutureCallback callback) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase @@ -147,7 +148,7 @@ public Future execute(HttpHost target, HttpRequest request, Future } public Future execute(HttpUriRequest request, HttpContext context, FutureCallback callback) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -167,7 +168,7 @@ public Future execute(HttpUriRequest request, HttpContext context, } public Future execute(HttpUriRequest request, FutureCallback callback) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -255,9 +256,9 @@ private void releaseLock() { } } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { try { - return GenericHelper.acquireLockIfPossible(SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); + return GenericHelper.acquireLockIfPossible(httpRequest, SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/httpclient-3/src/main/java/com/newrelic/agent/security/instrumentation/httpclient3/HttpMethodBase_Instrumentation.java b/instrumentation-security/httpclient-3/src/main/java/com/newrelic/agent/security/instrumentation/httpclient3/HttpMethodBase_Instrumentation.java index 95745b0a5..785fae956 100644 --- a/instrumentation-security/httpclient-3/src/main/java/com/newrelic/agent/security/instrumentation/httpclient3/HttpMethodBase_Instrumentation.java +++ b/instrumentation-security/httpclient-3/src/main/java/com/newrelic/agent/security/instrumentation/httpclient3/HttpMethodBase_Instrumentation.java @@ -12,6 +12,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -30,7 +31,7 @@ public abstract class HttpMethodBase_Instrumentation { public abstract void setRequestHeader(String headerName, String headerValue); public int execute(HttpState state, HttpConnection conn) throws HttpException, IOException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -150,9 +151,9 @@ private void releaseLock() { } } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { try { - return GenericHelper.acquireLockIfPossible(SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); + return GenericHelper.acquireLockIfPossible(httpRequest, SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/httpclient-4.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient40/HttpClient_Instrumentation.java b/instrumentation-security/httpclient-4.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient40/HttpClient_Instrumentation.java index 0eda0fb4b..c383b4007 100644 --- a/instrumentation-security/httpclient-4.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient40/HttpClient_Instrumentation.java +++ b/instrumentation-security/httpclient-4.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient40/HttpClient_Instrumentation.java @@ -13,6 +13,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -34,7 +35,7 @@ public abstract class HttpClient_Instrumentation { public HttpResponse execute(HttpUriRequest request) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -54,7 +55,7 @@ public HttpResponse execute(HttpUriRequest request) throws Exception { } public HttpResponse execute(HttpUriRequest request, HttpContext context) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -74,7 +75,7 @@ public HttpResponse execute(HttpUriRequest request, HttpContext context) throws } public HttpResponse execute(HttpHost target, HttpRequest request) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase @@ -102,7 +103,7 @@ public HttpResponse execute(HttpHost target, HttpRequest request) throws Excepti } public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase @@ -131,7 +132,7 @@ public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext co public T execute(HttpUriRequest request, ResponseHandler responseHandler) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -152,7 +153,7 @@ public T execute(HttpUriRequest request, ResponseHandler res public T execute(HttpUriRequest request, ResponseHandler responseHandler, HttpContext context) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -173,7 +174,7 @@ public T execute(HttpUriRequest request, ResponseHandler res public T execute(HttpHost target, HttpRequest request, ResponseHandler responseHandler) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase @@ -202,7 +203,7 @@ public T execute(HttpHost target, HttpRequest request, Response public T execute(HttpHost target, HttpRequest request, ResponseHandler responseHandler, HttpContext context) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase @@ -304,9 +305,9 @@ private void releaseLock() { } } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { try { - return GenericHelper.acquireLockIfPossible(SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); + return GenericHelper.acquireLockIfPossible(httpRequest, SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/httpclient-5.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient50/HttpAsyncClient_Instrumentation.java b/instrumentation-security/httpclient-5.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient50/HttpAsyncClient_Instrumentation.java index b837e1e7c..8c0e601cb 100644 --- a/instrumentation-security/httpclient-5.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient50/HttpAsyncClient_Instrumentation.java +++ b/instrumentation-security/httpclient-5.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient50/HttpAsyncClient_Instrumentation.java @@ -10,6 +10,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -38,7 +39,7 @@ public Future execute( FutureCallback callback) { HttpRequest request = NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(APACHE5_ASYNC_REQUEST_PRODUCER+requestProducer.hashCode(), HttpRequest.class); - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -68,9 +69,9 @@ private void releaseLock() { } } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { try { - return GenericHelper.acquireLockIfPossible(SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); + return GenericHelper.acquireLockIfPossible(httpRequest, SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/httpclient-5.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient50/HttpClient_Instrumentation.java b/instrumentation-security/httpclient-5.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient50/HttpClient_Instrumentation.java index d8358d594..e5b1a090c 100644 --- a/instrumentation-security/httpclient-5.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient50/HttpClient_Instrumentation.java +++ b/instrumentation-security/httpclient-5.0/src/main/java/com/newrelic/agent/security/instrumentation/httpclient50/HttpClient_Instrumentation.java @@ -10,6 +10,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -29,7 +30,7 @@ public class HttpClient_Instrumentation { public HttpResponse execute(ClassicHttpRequest request) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -49,7 +50,7 @@ public HttpResponse execute(ClassicHttpRequest request) throws Exception { } public HttpResponse execute(ClassicHttpRequest request, HttpContext context) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -69,7 +70,7 @@ public HttpResponse execute(ClassicHttpRequest request, HttpContext context) thr } public ClassicHttpResponse execute(HttpHost target, ClassicHttpRequest request) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -95,7 +96,7 @@ public ClassicHttpResponse execute(HttpHost target, ClassicHttpRequest request) } public HttpResponse execute(HttpHost target, ClassicHttpRequest request, HttpContext context) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -122,7 +123,7 @@ public HttpResponse execute(HttpHost target, ClassicHttpRequest request, HttpCon public T execute(ClassicHttpRequest request, HttpClientResponseHandler responseHandler) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -143,7 +144,7 @@ public T execute(ClassicHttpRequest request, HttpClientResponseHandler T execute(ClassicHttpRequest request, HttpContext context, HttpClientResponseHandler responseHandler) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -164,7 +165,7 @@ public T execute(ClassicHttpRequest request, HttpContext context, HttpClient public T execute(HttpHost target, ClassicHttpRequest request, HttpClientResponseHandler responseHandler) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -191,7 +192,7 @@ public T execute(HttpHost target, ClassicHttpRequest request, HttpClientResp public T execute(HttpHost target, ClassicHttpRequest request, HttpContext context, HttpClientResponseHandler responseHandler) throws Exception { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -229,9 +230,9 @@ private void releaseLock() { } } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { try { - return GenericHelper.acquireLockIfPossible(SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); + return GenericHelper.acquireLockIfPossible(httpRequest, SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/httpclient-jdk11/src/main/java/com/newrelic/agent/security/instrumentation/http/HttpClientImpl_Instrumentation.java b/instrumentation-security/httpclient-jdk11/src/main/java/com/newrelic/agent/security/instrumentation/http/HttpClientImpl_Instrumentation.java index d7d163f48..a86fa1c53 100644 --- a/instrumentation-security/httpclient-jdk11/src/main/java/com/newrelic/agent/security/instrumentation/http/HttpClientImpl_Instrumentation.java +++ b/instrumentation-security/httpclient-jdk11/src/main/java/com/newrelic/agent/security/instrumentation/http/HttpClientImpl_Instrumentation.java @@ -8,6 +8,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -38,7 +39,7 @@ private static void registerExitOperation(boolean isProcessingAllowed, AbstractO @Trace private CompletableFuture> sendAsync(HttpRequest request, HttpResponse.BodyHandler responseHandler, HttpResponse.PushPromiseHandler pushPromiseHandler, Executor exchangeExecutor) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; // Preprocess Phase if (isLockAcquired) { @@ -91,9 +92,9 @@ private void releaseLock() { } } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { try { - return GenericHelper.acquireLockIfPossible(SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); + return GenericHelper.acquireLockIfPossible(httpRequest, SecurityHelper.NR_SEC_CUSTOM_ATTRIB_NAME, this.hashCode()); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/javax-jndi/src/main/java/javax/naming/Context_Instrumentation.java b/instrumentation-security/javax-jndi/src/main/java/javax/naming/Context_Instrumentation.java index 507e695cd..ded02cd36 100644 --- a/instrumentation-security/javax-jndi/src/main/java/javax/naming/Context_Instrumentation.java +++ b/instrumentation-security/javax-jndi/src/main/java/javax/naming/Context_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.utils.UserDataTranslationHelper; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -18,7 +19,7 @@ public abstract class Context_Instrumentation { public Object lookup(Name name) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); List operations = null; if(isLockAcquired) { operations = preprocessSecurityHook(name.getAll(), JNDIUtils.METHOD_LOOKUP); @@ -36,7 +37,7 @@ public Object lookup(Name name) throws NamingException { } public Object lookupLink(Name name) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); List operations = null; if(isLockAcquired) { operations = preprocessSecurityHook(name.getAll(), JNDIUtils.METHOD_LOOKUP); @@ -54,7 +55,7 @@ public Object lookupLink(Name name) throws NamingException { } public Object lookup(String name) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(name, JNDIUtils.METHOD_LOOKUP); @@ -72,7 +73,7 @@ public Object lookup(String name) throws NamingException { } public Object lookupLink(String name) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(name, JNDIUtils.METHOD_LOOKUP); @@ -163,9 +164,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType ldap) { try { - return GenericHelper.acquireLockIfPossible(JNDIUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(ldap, JNDIUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/javax-ldap/src/main/java/javax/naming/directory/DirContext_Instrumentation.java b/instrumentation-security/javax-ldap/src/main/java/javax/naming/directory/DirContext_Instrumentation.java index a2f263627..927e7eb32 100644 --- a/instrumentation-security/javax-ldap/src/main/java/javax/naming/directory/DirContext_Instrumentation.java +++ b/instrumentation-security/javax-ldap/src/main/java/javax/naming/directory/DirContext_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.LDAPOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -20,7 +21,7 @@ public abstract class DirContext_Instrumentation implements Context { public NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if (isLockAcquired) { operation = preprocessSecurityHook(name.toString(), filterExpr); @@ -39,7 +40,7 @@ public NamingEnumeration search(Name name, String filterExpr, Obje } public NamingEnumeration search(String name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if (isLockAcquired) { operation = preprocessSecurityHook(name, filterExpr); @@ -58,7 +59,7 @@ public NamingEnumeration search(String name, String filterExpr, Ob } public NamingEnumeration search(String name, String filter, SearchControls cons) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if (isLockAcquired) { operation = preprocessSecurityHook(name, filter); @@ -82,7 +83,7 @@ public NamingEnumeration search(String name, String filter, Search SearchControls cons) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(name.toString(), filter); @@ -139,9 +140,9 @@ private void releaseLock() { } } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType ldap) { try { - return GenericHelper.acquireLockIfPossible(LDAPUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(ldap, LDAPUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/javax-xpath/src/main/java/com/sun/org/apache/xpath/internal/XPath_Instrumentation.java b/instrumentation-security/javax-xpath/src/main/java/com/sun/org/apache/xpath/internal/XPath_Instrumentation.java index 777896065..72e3f93cf 100644 --- a/instrumentation-security/javax-xpath/src/main/java/com/sun/org/apache/xpath/internal/XPath_Instrumentation.java +++ b/instrumentation-security/javax-xpath/src/main/java/com/sun/org/apache/xpath/internal/XPath_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.XPathOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -22,7 +23,7 @@ public XObject execute( XPathContext xctxt, int contextNode, PrefixResolver namespaceContext) throws javax.xml.transform.TransformerException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(getPatternString(), "execute"); @@ -45,7 +46,7 @@ public XObject execute( PrefixResolver namespaceContext) throws javax.xml.transform.TransformerException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(getPatternString(), "execute"); @@ -101,9 +102,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType xpath) { try { - return GenericHelper.acquireLockIfPossible("XPATH_OPERATION_LOCK_JAVAXPATH-"); + return GenericHelper.acquireLockIfPossible(xpath, "XPATH_OPERATION_LOCK_JAVAXPATH-"); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/javax-xpath/src/main/java/javax/xml/xpath/XPath_Instrumentation.java b/instrumentation-security/javax-xpath/src/main/java/javax/xml/xpath/XPath_Instrumentation.java index ce65bb97b..714cf3cba 100644 --- a/instrumentation-security/javax-xpath/src/main/java/javax/xml/xpath/XPath_Instrumentation.java +++ b/instrumentation-security/javax-xpath/src/main/java/javax/xml/xpath/XPath_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.XPathOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -19,7 +20,7 @@ public abstract class XPath_Instrumentation { public String evaluate(String expression, InputSource source) throws XPathExpressionException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(expression, "evaluate"); @@ -42,7 +43,7 @@ public Object evaluate( InputSource source, QName returnType) throws XPathExpressionException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(expression, "evaluate"); @@ -62,7 +63,7 @@ public Object evaluate( public String evaluate(String expression, Object item) throws XPathExpressionException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(expression, "evaluate"); @@ -82,7 +83,7 @@ public String evaluate(String expression, Object item) public Object evaluate(String expression, Object item, QName returnType) throws XPathExpressionException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(expression, "evaluate"); @@ -140,9 +141,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType xpath) { try { - return GenericHelper.acquireLockIfPossible("XPATH_OPERATION_LOCK_JAVAXPATH-"); + return GenericHelper.acquireLockIfPossible(xpath, "XPATH_OPERATION_LOCK_JAVAXPATH-"); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/jaxen-xpath-1.1/src/main/java/org/jaxen/BaseXPath_Instrumentation.java b/instrumentation-security/jaxen-xpath-1.1/src/main/java/org/jaxen/BaseXPath_Instrumentation.java index 591b15f90..6b837641e 100644 --- a/instrumentation-security/jaxen-xpath-1.1/src/main/java/org/jaxen/BaseXPath_Instrumentation.java +++ b/instrumentation-security/jaxen-xpath-1.1/src/main/java/org/jaxen/BaseXPath_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.XPathOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -20,7 +21,7 @@ public abstract class BaseXPath_Instrumentation { private String exprText = Weaver.callOriginal(); public List selectNodes(Object node) throws JaxenException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(this.exprText, XPATHUtils.METHOD_SELECT_NODES); @@ -78,9 +79,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType xpath) { try { - return GenericHelper.acquireLockIfPossible(XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(xpath, XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/jaxen-xpath/src/main/java/org/jaxen/BaseXPath_Instrumentation.java b/instrumentation-security/jaxen-xpath/src/main/java/org/jaxen/BaseXPath_Instrumentation.java index 94e9edf9b..2a0ec1af5 100644 --- a/instrumentation-security/jaxen-xpath/src/main/java/org/jaxen/BaseXPath_Instrumentation.java +++ b/instrumentation-security/jaxen-xpath/src/main/java/org/jaxen/BaseXPath_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.XPathOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -20,7 +21,7 @@ public abstract class BaseXPath_Instrumentation { private final String exprText = Weaver.callOriginal(); public List selectNodes(Object node) throws JaxenException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(this.exprText, XPATHUtils.METHOD_SELECT_NODES); @@ -78,9 +79,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType xpath) { try { - return GenericHelper.acquireLockIfPossible(XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(xpath, XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/jcache-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jcache_1_0_0/JCacheHelper.java b/instrumentation-security/jcache-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jcache_1_0_0/JCacheHelper.java index b2c2fb6ae..d813bcff0 100644 --- a/instrumentation-security/jcache-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jcache_1_0_0/JCacheHelper.java +++ b/instrumentation-security/jcache-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jcache_1_0_0/JCacheHelper.java @@ -3,6 +3,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.JCacheOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -54,9 +55,9 @@ public static void releaseLock(int hashcode) { } catch (Throwable ignored) {} } - public static boolean acquireLockIfPossible(int hashcode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType cachingDataStore, int hashcode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashcode); + return GenericHelper.acquireLockIfPossible(cachingDataStore, NR_SEC_CUSTOM_ATTRIB_NAME, hashcode); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/jcache-1.0.0/src/main/java/javax/cache/Cache_Instrumentation.java b/instrumentation-security/jcache-1.0.0/src/main/java/javax/cache/Cache_Instrumentation.java index 76f6a94f5..6672ebfed 100644 --- a/instrumentation-security/jcache-1.0.0/src/main/java/javax/cache/Cache_Instrumentation.java +++ b/instrumentation-security/jcache-1.0.0/src/main/java/javax/cache/Cache_Instrumentation.java @@ -2,6 +2,7 @@ import com.newrelic.agent.security.instrumentation.jcache_1_0_0.JCacheHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -17,7 +18,7 @@ @Weave(type = MatchType.Interface, originalName = "javax.cache.Cache") public abstract class Cache_Instrumentation { public V get(K key) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.READ, Collections.singletonList(key), this.getClass().getName(), "get"); @@ -35,7 +36,7 @@ public V get(K key) { } public Map getAll(Set keys) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.READ, new ArrayList() { { addAll(keys); } }, this.getClass().getName(), "getAll"); @@ -53,7 +54,7 @@ public Map getAll(Set keys) { } public boolean containsKey(K key) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.READ, Collections.singletonList(key), this.getClass().getName(), "containsKey"); @@ -71,7 +72,7 @@ public boolean containsKey(K key) { } public void loadAll(Set keys, boolean replaceExistingValues, CompletionListener completionListener) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.READ, new ArrayList() { { addAll(keys); } }, this.getClass().getName(), "loadAll"); @@ -87,7 +88,7 @@ public void loadAll(Set keys, boolean replaceExistingValues, Comple } public void put(K key, V value) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.WRITE, Arrays.asList(key, value), this.getClass().getName(), "put"); @@ -103,7 +104,7 @@ public void put(K key, V value) { } public V getAndPut(K key, V value) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.WRITE, Arrays.asList(key, value), this.getClass().getName(), "getAndPut"); @@ -121,7 +122,7 @@ public V getAndPut(K key, V value) { } public void putAll(Map map) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { List argList = new ArrayList<>(); @@ -143,7 +144,7 @@ public void putAll(Map map) { } public boolean putIfAbsent(K key, V value) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.WRITE, Arrays.asList(key, value), this.getClass().getName(), "putIfAbsent"); @@ -161,7 +162,7 @@ public boolean putIfAbsent(K key, V value) { } public boolean remove(K key) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.DELETE, Collections.singletonList(key), this.getClass().getName(), "remove"); @@ -179,7 +180,7 @@ public boolean remove(K key) { } public boolean remove(K key, V oldValue) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.DELETE, Arrays.asList(key, oldValue), this.getClass().getName(), "remove"); @@ -197,7 +198,7 @@ public boolean remove(K key, V oldValue) { } public V getAndRemove(K key) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.DELETE, Collections.singletonList(key), this.getClass().getName(), "getAndRemove"); @@ -215,7 +216,7 @@ public V getAndRemove(K key) { } public boolean replace(K key, V oldValue) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.UPDATE, Arrays.asList(key, oldValue), this.getClass().getName(), "replace"); @@ -233,7 +234,7 @@ public boolean replace(K key, V oldValue) { } public boolean replace(K key, V oldValue, V newValue) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.UPDATE, Arrays.asList(key, oldValue, newValue), this.getClass().getName(), "replace"); @@ -251,7 +252,7 @@ public boolean replace(K key, V oldValue, V newValue) { } public V getAndReplace(K key, V value) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.UPDATE, Arrays.asList(key, value), this.getClass().getName(), "getAndReplace"); @@ -269,7 +270,7 @@ public V getAndReplace(K key, V value) { } public void removeAll(Set keys) { - boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = JCacheHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, this.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = JCacheHelper.preprocessSecurityHook(JCacheHelper.DELETE, new ArrayList() { { addAll(keys); } }, this.getClass().getName(), "removeAll"); diff --git a/instrumentation-security/jdbc-generic/src/main/java/java/sql/PreparedStatement_Instrumentation.java b/instrumentation-security/jdbc-generic/src/main/java/java/sql/PreparedStatement_Instrumentation.java index 083fc98da..3fdb82046 100644 --- a/instrumentation-security/jdbc-generic/src/main/java/java/sql/PreparedStatement_Instrumentation.java +++ b/instrumentation-security/jdbc-generic/src/main/java/java/sql/PreparedStatement_Instrumentation.java @@ -12,6 +12,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.JdbcHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.JDBCVendor; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.BatchSQLOperation; import com.newrelic.api.agent.security.schema.operation.SQLOperation; @@ -96,20 +97,15 @@ private AbstractOperation preprocessSecurityHook (String sql, String methodName) } private void releaseLock() { - try { - JdbcHelper.releaseLock(); - } catch (Throwable ignored) {} + GenericHelper.releaseLock(JdbcHelper.getNrSecCustomAttribName()); } - private boolean acquireLockIfPossible() { - try { - return JdbcHelper.acquireLockIfPossible(); - } catch (Throwable ignored) {} - return false; + private boolean acquireLockIfPossible(VulnerabilityCaseType sqlDbCommand) { + return GenericHelper.acquireLockIfPossible(sqlDbCommand, JdbcHelper.getNrSecCustomAttribName()); } public ResultSet executeQuery() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { if(preparedSql == null){ @@ -130,7 +126,7 @@ public ResultSet executeQuery() throws SQLException { } public int executeUpdate() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { if(preparedSql == null){ @@ -151,7 +147,7 @@ public int executeUpdate() throws SQLException { } public boolean execute() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { if(preparedSql == null){ @@ -395,7 +391,7 @@ private void setObjectParams(int index, Object data) { objectParams.put(String.valueOf(index), data); } public void addBatch() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); SQLOperation sqlOperation = null; if(isLockAcquired) { sqlOperation = new SQLOperation(this.getClass().getName(), JdbcHelper.METHOD_EXECUTE_BATCH); diff --git a/instrumentation-security/jdbc-generic/src/main/java/java/sql/Statement_Instrumentation.java b/instrumentation-security/jdbc-generic/src/main/java/java/sql/Statement_Instrumentation.java index 2afc4310b..188de5713 100644 --- a/instrumentation-security/jdbc-generic/src/main/java/java/sql/Statement_Instrumentation.java +++ b/instrumentation-security/jdbc-generic/src/main/java/java/sql/Statement_Instrumentation.java @@ -12,6 +12,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.JdbcHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.JDBCVendor; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.BatchSQLOperation; import com.newrelic.api.agent.security.schema.operation.SQLOperation; @@ -104,7 +105,7 @@ private AbstractOperation preprocessSecurityHook(BatchSQLOperation operation){ public ResultSet executeQuery(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_QUERY); @@ -122,20 +123,15 @@ public ResultSet executeQuery(String sql) throws SQLException { } private void releaseLock() { - try { - JdbcHelper.releaseLock(); - } catch (Throwable ignored) {} + GenericHelper.releaseLock(JdbcHelper.getNrSecCustomAttribName()); } - private boolean acquireLockIfPossible() { - try { - return JdbcHelper.acquireLockIfPossible(); - } catch (Throwable ignored) {} - return false; + private boolean acquireLockIfPossible(VulnerabilityCaseType sqlDbCommand) { + return GenericHelper.acquireLockIfPossible(sqlDbCommand, JdbcHelper.getNrSecCustomAttribName()); } public int executeUpdate(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -153,7 +149,7 @@ public int executeUpdate(String sql) throws SQLException { } public boolean execute(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); @@ -171,7 +167,7 @@ public boolean execute(String sql) throws SQLException { } public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -189,7 +185,7 @@ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException } public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -207,7 +203,7 @@ public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { } public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); @@ -225,7 +221,7 @@ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { } public int executeUpdate(String sql, String[] columnNames) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -243,7 +239,7 @@ public int executeUpdate(String sql, String[] columnNames) throws SQLException { } public boolean execute(String sql, String[] columnNames) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); @@ -261,7 +257,7 @@ public boolean execute(String sql, String[] columnNames) throws SQLException { } public boolean execute(String sql, int[] columnIndexes) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); @@ -279,7 +275,7 @@ public boolean execute(String sql, int[] columnIndexes) throws SQLException { } public void addBatch(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); SQLOperation sqlOperation = null; if(isLockAcquired) { sqlOperation = new SQLOperation(this.getClass().getName(), JdbcHelper.METHOD_EXECUTE_BATCH); @@ -301,7 +297,7 @@ public void addBatch(String sql) throws SQLException { } public void clearBatch() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); if(isLockAcquired) { if (batchSQLOperation==null){ batchSQLOperation = NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(JdbcHelper.NR_SEC_CUSTOM_ATTRIB_BATCH_SQL_NAME+hashCode(), BatchSQLOperation.class); @@ -320,7 +316,7 @@ public void clearBatch() throws SQLException { } public int[] executeBatch() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { if(batchSQLOperation==null|| batchSQLOperation.isEmpty()){ diff --git a/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsPreparedStatement_Instrumentation.java b/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsPreparedStatement_Instrumentation.java index 7c679301f..4c41e222d 100644 --- a/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsPreparedStatement_Instrumentation.java +++ b/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsPreparedStatement_Instrumentation.java @@ -13,6 +13,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.JdbcHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.JDBCVendor; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SQLOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -78,16 +79,13 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { - try { - return JdbcHelper.acquireLockIfPossible(); - } catch (Throwable ignored) {} - return false; + private boolean acquireLockIfPossible(VulnerabilityCaseType sqlDbCommand) { + return GenericHelper.acquireLockIfPossible(sqlDbCommand, JdbcHelper.getNrSecCustomAttribName()); } @Trace(leaf = true) public ResultSet executeQuery() { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, getParameterValues(), JdbcHelper.METHOD_EXECUTE_QUERY); @@ -106,7 +104,7 @@ public ResultSet executeQuery() { @Trace(leaf = true) public int executeUpdate() { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, getParameterValues(), JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -125,7 +123,7 @@ public int executeUpdate() { @Trace(leaf = true) public boolean execute() { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, getParameterValues(), JdbcHelper.METHOD_EXECUTE); diff --git a/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsStatement_Instrumentation.java b/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsStatement_Instrumentation.java index 804f6a98c..c2f9dc4ee 100644 --- a/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsStatement_Instrumentation.java +++ b/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsStatement_Instrumentation.java @@ -12,6 +12,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.JdbcHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.JDBCVendor; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SQLOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -69,15 +70,12 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { - try { - return JdbcHelper.acquireLockIfPossible(); - } catch (Throwable ignored) {} - return false; + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, JdbcHelper.getNrSecCustomAttribName()); } public ResultSet executeQuery(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_QUERY); @@ -95,7 +93,7 @@ public ResultSet executeQuery(String sql) throws SQLException { } public int executeUpdate(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -113,7 +111,7 @@ public int executeUpdate(String sql) throws SQLException { } public boolean execute(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); @@ -131,7 +129,7 @@ public boolean execute(String sql) throws SQLException { } public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -150,7 +148,7 @@ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -168,7 +166,7 @@ public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { } public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); @@ -186,7 +184,7 @@ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { } public int executeUpdate(String sql, String[] columnNames) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -204,7 +202,7 @@ public int executeUpdate(String sql, String[] columnNames) throws SQLException { } public boolean execute(String sql, String[] columnNames) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); @@ -223,7 +221,7 @@ public boolean execute(String sql, String[] columnNames) throws SQLException { public boolean execute(String sql, int[] columnIndexes) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); diff --git a/instrumentation-security/jdbc-postgresql-8.0-312.jdbc3/src/main/java/org/postgresql/jdbc2/AbstractJdbc2Statement_Instrumentation.java b/instrumentation-security/jdbc-postgresql-8.0-312.jdbc3/src/main/java/org/postgresql/jdbc2/AbstractJdbc2Statement_Instrumentation.java index 49794b9f2..ba493bac3 100644 --- a/instrumentation-security/jdbc-postgresql-8.0-312.jdbc3/src/main/java/org/postgresql/jdbc2/AbstractJdbc2Statement_Instrumentation.java +++ b/instrumentation-security/jdbc-postgresql-8.0-312.jdbc3/src/main/java/org/postgresql/jdbc2/AbstractJdbc2Statement_Instrumentation.java @@ -12,6 +12,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.JdbcHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.JDBCVendor; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SQLOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -73,16 +74,11 @@ private AbstractOperation preprocessSecurityHook (String sql, String methodName) } private void releaseLock() { - try { - JdbcHelper.releaseLock(); - } catch (Throwable ignored) {} + GenericHelper.releaseLock(JdbcHelper.getNrSecCustomAttribName()); } - private boolean acquireLockIfPossible() { - try { - return JdbcHelper.acquireLockIfPossible(); - } catch (Throwable ignored) {} - return false; + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, JdbcHelper.getNrSecCustomAttribName()); } public AbstractJdbc2Statement_Instrumentation(AbstractJdbc2Connection connection, String sql, boolean isCallable, int rsType, int rsConcurrency) throws SQLException { @@ -90,7 +86,7 @@ public AbstractJdbc2Statement_Instrumentation(AbstractJdbc2Connection connection } public ResultSet executeQuery() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -111,7 +107,7 @@ public ResultSet executeQuery() throws SQLException { } public ResultSet executeQuery(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_QUERY); @@ -129,7 +125,7 @@ public ResultSet executeQuery(String sql) throws SQLException { } public int executeUpdate() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -150,7 +146,7 @@ public int executeUpdate() throws SQLException { } public int executeUpdate(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -168,7 +164,7 @@ public int executeUpdate(String sql) throws SQLException { } public boolean execute() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -189,7 +185,7 @@ public boolean execute() throws SQLException { } public boolean execute(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); diff --git a/instrumentation-security/jdbc-postgresql-9.4.1207/src/main/java/org/postgresql/jdbc/PgStatement_Instrumentation.java b/instrumentation-security/jdbc-postgresql-9.4.1207/src/main/java/org/postgresql/jdbc/PgStatement_Instrumentation.java index 588943d68..f27cb4069 100644 --- a/instrumentation-security/jdbc-postgresql-9.4.1207/src/main/java/org/postgresql/jdbc/PgStatement_Instrumentation.java +++ b/instrumentation-security/jdbc-postgresql-9.4.1207/src/main/java/org/postgresql/jdbc/PgStatement_Instrumentation.java @@ -13,6 +13,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.JdbcHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.JDBCVendor; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SQLOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -83,15 +84,12 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { - try { - return JdbcHelper.acquireLockIfPossible(); - } catch (Throwable ignored) {} - return false; + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, JdbcHelper.getNrSecCustomAttribName()); } public ResultSet executeQuery() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -112,7 +110,7 @@ public ResultSet executeQuery() throws SQLException { } public ResultSet executeQuery(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_QUERY); @@ -130,7 +128,7 @@ public ResultSet executeQuery(String sql) throws SQLException { } public int executeUpdate() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -151,7 +149,7 @@ public int executeUpdate() throws SQLException { } public int executeUpdate(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -169,7 +167,7 @@ public int executeUpdate(String sql) throws SQLException { } public boolean execute() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -191,7 +189,7 @@ public boolean execute() throws SQLException { @Trace(leaf = true) public boolean execute(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); diff --git a/instrumentation-security/jedis-2.7.1_2.7.2/src/main/java/com/newrelic/agent/security/instrumentation/jedis_2_7_1/JedisHelper.java b/instrumentation-security/jedis-2.7.1_2.7.2/src/main/java/com/newrelic/agent/security/instrumentation/jedis_2_7_1/JedisHelper.java index 54e1d0bf9..d78ef528b 100644 --- a/instrumentation-security/jedis-2.7.1_2.7.2/src/main/java/com/newrelic/agent/security/instrumentation/jedis_2_7_1/JedisHelper.java +++ b/instrumentation-security/jedis-2.7.1_2.7.2/src/main/java/com/newrelic/agent/security/instrumentation/jedis_2_7_1/JedisHelper.java @@ -3,6 +3,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RedisOperation; @@ -43,9 +44,9 @@ public static void releaseLock(int hashCode) { } catch (Throwable ignored) {} } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType cachingDataStore, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_LOCK_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(cachingDataStore, NR_SEC_LOCK_ATTRIB_NAME, hashCode); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/jedis-2.7.1_2.7.2/src/main/java/redis/clients/jedis/Connection_Instrumentation.java b/instrumentation-security/jedis-2.7.1_2.7.2/src/main/java/redis/clients/jedis/Connection_Instrumentation.java index 52f2b9f13..f889ad322 100644 --- a/instrumentation-security/jedis-2.7.1_2.7.2/src/main/java/redis/clients/jedis/Connection_Instrumentation.java +++ b/instrumentation-security/jedis-2.7.1_2.7.2/src/main/java/redis/clients/jedis/Connection_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -18,7 +19,7 @@ @Weave(type = MatchType.BaseClass, originalName = "redis.clients.jedis.Connection") public abstract class Connection_Instrumentation { protected Connection sendCommand(final ProtocolCommand cmd, final byte[]... args) { - boolean isLockAcquired = JedisHelper.acquireLockIfPossible(cmd.hashCode()); + boolean isLockAcquired = JedisHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, cmd.hashCode()); AbstractOperation operation = null; if(isLockAcquired && cmd!=null && args!=null) { List argList = new ArrayList<>(); diff --git a/instrumentation-security/jedis-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jedis_3_0_0/JedisHelper.java b/instrumentation-security/jedis-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jedis_3_0_0/JedisHelper.java index 0c1582c19..0b1b7983f 100644 --- a/instrumentation-security/jedis-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jedis_3_0_0/JedisHelper.java +++ b/instrumentation-security/jedis-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jedis_3_0_0/JedisHelper.java @@ -3,6 +3,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RedisOperation; @@ -43,9 +44,9 @@ public static void releaseLock(int hashCode) { } catch (Throwable ignored) {} } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType cachingDataStore, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_LOCK_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(cachingDataStore, NR_SEC_LOCK_ATTRIB_NAME, hashCode); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/jedis-3.0.0/src/main/java/redis/clients/jedis/Connection_Instrumentation.java b/instrumentation-security/jedis-3.0.0/src/main/java/redis/clients/jedis/Connection_Instrumentation.java index bf5e48f1b..466e71c8b 100644 --- a/instrumentation-security/jedis-3.0.0/src/main/java/redis/clients/jedis/Connection_Instrumentation.java +++ b/instrumentation-security/jedis-3.0.0/src/main/java/redis/clients/jedis/Connection_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -19,7 +20,7 @@ @Weave(type = MatchType.BaseClass, originalName = "redis.clients.jedis.Connection") public abstract class Connection_Instrumentation { public void sendCommand(final ProtocolCommand cmd, final byte[]... args) { - boolean isLockAcquired = JedisHelper.acquireLockIfPossible(cmd.hashCode()); + boolean isLockAcquired = JedisHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, cmd.hashCode()); AbstractOperation operation = null; if(isLockAcquired && args != null && args.length > 0) { // args.length>0 will ensure the event generation for the commands with data List argList = new ArrayList<>(); diff --git a/instrumentation-security/jedis-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jedis_4_0_0/JedisHelper.java b/instrumentation-security/jedis-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jedis_4_0_0/JedisHelper.java index e0c30b3e4..ddc00efb2 100644 --- a/instrumentation-security/jedis-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jedis_4_0_0/JedisHelper.java +++ b/instrumentation-security/jedis-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/jedis_4_0_0/JedisHelper.java @@ -3,6 +3,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RedisOperation; @@ -43,9 +44,9 @@ public static void releaseLock(int hashCode) { } catch (Throwable ignored) {} } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType cachingDataStore, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_LOCK_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(cachingDataStore, NR_SEC_LOCK_ATTRIB_NAME, hashCode); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/jedis-4.0.0/src/main/java/redis/clients/jedis/Connection_Instrumentation.java b/instrumentation-security/jedis-4.0.0/src/main/java/redis/clients/jedis/Connection_Instrumentation.java index 1c9b94479..c37936eac 100644 --- a/instrumentation-security/jedis-4.0.0/src/main/java/redis/clients/jedis/Connection_Instrumentation.java +++ b/instrumentation-security/jedis-4.0.0/src/main/java/redis/clients/jedis/Connection_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -17,7 +18,7 @@ @Weave(type = MatchType.BaseClass, originalName = "redis.clients.jedis.Connection") public abstract class Connection_Instrumentation { public void sendCommand(final CommandArguments args) { - boolean isLockAcquired = JedisHelper.acquireLockIfPossible(args.hashCode()); + boolean isLockAcquired = JedisHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, args.hashCode()); AbstractOperation operation = null; if(isLockAcquired && args.size()>1) { // args.size()>1 will ensure the event generation for the commands with data String command = ""; diff --git a/instrumentation-security/jersey-2.16/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java b/instrumentation-security/jersey-2.16/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java index bde87f683..0718f51b8 100644 --- a/instrumentation-security/jersey-2.16/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java +++ b/instrumentation-security/jersey-2.16/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java @@ -10,6 +10,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weaver; import org.glassfish.jersey.message.internal.OutboundJaxrsResponse; @@ -43,7 +44,7 @@ public abstract class ContainerResponse_Instrumentation { public void close() { boolean isLockAcquired = false; try { - isLockAcquired = GenericHelper.acquireLockIfPossible(SERVLET_GET_IS_OPERATION_LOCK); + isLockAcquired = GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.REFLECTED_XSS, SERVLET_GET_IS_OPERATION_LOCK); if(isLockAcquired) { HttpRequestHelper.postProcessSecurityHook(this.getClass().getName(), getWrappedMessageContext()); } diff --git a/instrumentation-security/jersey-2/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java b/instrumentation-security/jersey-2/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java index a0593e5e3..f1f898aa3 100644 --- a/instrumentation-security/jersey-2/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java +++ b/instrumentation-security/jersey-2/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java @@ -10,6 +10,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weaver; import org.glassfish.jersey.message.internal.OutboundJaxrsResponse; @@ -39,7 +40,7 @@ public abstract class ContainerResponse_Instrumentation { public void close() { boolean isLockAcquired = false; try { - isLockAcquired = GenericHelper.acquireLockIfPossible(SERVLET_GET_IS_OPERATION_LOCK); + isLockAcquired = GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.REFLECTED_XSS, SERVLET_GET_IS_OPERATION_LOCK); if(isLockAcquired) { HttpRequestHelper.postProcessSecurityHook(this.getClass().getName(), getWrappedMessageContext()); } diff --git a/instrumentation-security/jersey-3/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java b/instrumentation-security/jersey-3/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java index aa015732b..7990a24c4 100644 --- a/instrumentation-security/jersey-3/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java +++ b/instrumentation-security/jersey-3/src/main/java/com/newrelic/agent/security/instrumentation/jersey2/ContainerResponse_Instrumentation.java @@ -10,6 +10,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weaver; import org.glassfish.jersey.message.internal.OutboundJaxrsResponse; @@ -39,7 +40,7 @@ public abstract class ContainerResponse_Instrumentation { public void close() { boolean isLockAcquired = false; try { - isLockAcquired = GenericHelper.acquireLockIfPossible(SERVLET_GET_IS_OPERATION_LOCK); + isLockAcquired = GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.REFLECTED_XSS, SERVLET_GET_IS_OPERATION_LOCK); if(isLockAcquired) { HttpRequestHelper.postProcessSecurityHook(this.getClass().getName(), getWrappedMessageContext()); } 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 e0528d9e7..4e100890c 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 @@ -178,8 +178,10 @@ public static void preprocessSecurityHook(HttpServletRequest httpServletRequest) public static void postProcessSecurityHook(HttpServletRequest request, HttpServletResponse response, String className, String methodName) { try { - if (!NewRelicSecurity.isHookProcessingActive() - ) { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } + if (!NewRelicSecurity.isHookProcessingActive()) { return; } NewRelicSecurity.getAgent().getSecurityMetaData().getResponse().setResponseCode(response.getStatus()); 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 15ebf0561..18bbf3726 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 @@ -177,8 +177,10 @@ public static void preprocessSecurityHook(Request request) { public static void postProcessSecurityHook(Request request, Response response, String className, String methodName) { try { - if (!NewRelicSecurity.isHookProcessingActive() - ) { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } + if (!NewRelicSecurity.isHookProcessingActive()) { return; } NewRelicSecurity.getAgent().getSecurityMetaData().getResponse().setResponseCode(response.getStatus()); 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 07b87e142..07a489ddc 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 @@ -179,8 +179,10 @@ public static void preprocessSecurityHook(HttpServletRequest httpServletRequest) public static void postProcessSecurityHook(HttpServletRequest request, HttpServletResponse response, String className, String methodName) { try { - if (!NewRelicSecurity.isHookProcessingActive() - ) { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } + if (!NewRelicSecurity.isHookProcessingActive()) { return; } NewRelicSecurity.getAgent().getSecurityMetaData().getResponse().setResponseCode(response.getStatus()); diff --git a/instrumentation-security/ldaptive-1.0/src/main/java/org/ldaptive/AbstractOperation_Instrumentation.java b/instrumentation-security/ldaptive-1.0/src/main/java/org/ldaptive/AbstractOperation_Instrumentation.java index 1d48191a7..3d3eda502 100644 --- a/instrumentation-security/ldaptive-1.0/src/main/java/org/ldaptive/AbstractOperation_Instrumentation.java +++ b/instrumentation-security/ldaptive-1.0/src/main/java/org/ldaptive/AbstractOperation_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.LDAPOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -18,7 +19,7 @@ public abstract class AbstractOperation_Instrumentation protected Response invoke(final Q request) throws LdapException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if(isLockAcquired && request instanceof SearchRequest) { SearchRequest searchRequest = (SearchRequest) request; @@ -78,10 +79,7 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { - try { - return GenericHelper.acquireLockIfPossible(LDAPUtils.NR_SEC_CUSTOM_ATTRIB_NAME); - } catch (Throwable ignored) {} - return false; + private boolean acquireLockIfPossible(VulnerabilityCaseType ldap) { + return GenericHelper.acquireLockIfPossible(ldap, LDAPUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } } diff --git a/instrumentation-security/ldaptive-2.0/src/main/java/org/ldaptive/AbstractOperation_Instrumentation.java b/instrumentation-security/ldaptive-2.0/src/main/java/org/ldaptive/AbstractOperation_Instrumentation.java index 67f1b09c6..76a624163 100644 --- a/instrumentation-security/ldaptive-2.0/src/main/java/org/ldaptive/AbstractOperation_Instrumentation.java +++ b/instrumentation-security/ldaptive-2.0/src/main/java/org/ldaptive/AbstractOperation_Instrumentation.java @@ -3,6 +3,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.LDAPOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -17,7 +18,7 @@ public abstract class AbstractOperation_Instrumentation { @SuppressWarnings("unchecked") @Trace public AsyncCommand dispatch(RedisCommand_Instrumentation cmd) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(cmd, LettuceUtils.METHOD_DISPATCH); @@ -95,9 +96,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType cachingDataStore) { try { - return GenericHelper.acquireLockIfPossible(LettuceUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(cachingDataStore, LettuceUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/lettuce-5.0/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands_Instrumentation.java b/instrumentation-security/lettuce-5.0/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands_Instrumentation.java index 8a3d141fb..dd0c585f3 100644 --- a/instrumentation-security/lettuce-5.0/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands_Instrumentation.java +++ b/instrumentation-security/lettuce-5.0/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands_Instrumentation.java @@ -11,6 +11,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RedisOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -33,7 +34,7 @@ public abstract class AbstractRedisAsyncCommands_Instrumentation { @SuppressWarnings("unchecked") @Trace public AsyncCommand dispatch(RedisCommand_Instrumentation cmd) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(cmd, LettuceUtils.METHOD_DISPATCH); @@ -98,9 +99,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType cachingDataStore) { try { - return GenericHelper.acquireLockIfPossible(LettuceUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(cachingDataStore, LettuceUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/low-priority-instrumentation/src/main/java/com/newrelic/agent/security/instrumentation/random/java/util/Random_Instrumentation.java b/instrumentation-security/low-priority-instrumentation/src/main/java/com/newrelic/agent/security/instrumentation/random/java/util/Random_Instrumentation.java index ee490d7ae..edf826045 100644 --- a/instrumentation-security/low-priority-instrumentation/src/main/java/com/newrelic/agent/security/instrumentation/random/java/util/Random_Instrumentation.java +++ b/instrumentation-security/low-priority-instrumentation/src/main/java/com/newrelic/agent/security/instrumentation/random/java/util/Random_Instrumentation.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RandomOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -22,7 +23,7 @@ public class Random_Instrumentation { public int nextInt() { - boolean isLockAcquired = acquireLockIfPossible(hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.RANDOM, hashCode()); AbstractOperation operation = null; boolean isOwaspHookEnabled = NewRelicSecurity.getAgent().isLowPriorityInstrumentationEnabled(); if (isOwaspHookEnabled && LowSeverityHelper.isOwaspHookProcessingNeeded()){ @@ -44,7 +45,7 @@ public int nextInt() { } public int nextInt(int bound) { - boolean isLockAcquired = acquireLockIfPossible(hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.RANDOM, hashCode()); AbstractOperation operation = null; boolean isOwaspHookEnabled = NewRelicSecurity.getAgent().isLowPriorityInstrumentationEnabled(); if (isOwaspHookEnabled && LowSeverityHelper.isOwaspHookProcessingNeeded()){ @@ -66,7 +67,7 @@ public int nextInt(int bound) { } public void nextBytes(byte[] bytes) { - boolean isLockAcquired = acquireLockIfPossible(hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.RANDOM, hashCode()); AbstractOperation operation = null; boolean isOwaspHookEnabled = NewRelicSecurity.getAgent().isLowPriorityInstrumentationEnabled(); if (isOwaspHookEnabled && LowSeverityHelper.isOwaspHookProcessingNeeded()){ @@ -86,7 +87,7 @@ public void nextBytes(byte[] bytes) { } public long nextLong() { - boolean isLockAcquired = acquireLockIfPossible(hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.RANDOM, hashCode()); AbstractOperation operation = null; boolean isOwaspHookEnabled = NewRelicSecurity.getAgent().isLowPriorityInstrumentationEnabled(); if (isOwaspHookEnabled && LowSeverityHelper.isOwaspHookProcessingNeeded()){ @@ -108,7 +109,7 @@ public long nextLong() { } public float nextFloat() { - boolean isLockAcquired = acquireLockIfPossible(hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.RANDOM, hashCode()); AbstractOperation operation = null; boolean isOwaspHookEnabled = NewRelicSecurity.getAgent().isLowPriorityInstrumentationEnabled(); if (isOwaspHookEnabled && LowSeverityHelper.isOwaspHookProcessingNeeded()){ @@ -130,7 +131,7 @@ public float nextFloat() { } public double nextDouble() { - boolean isLockAcquired = acquireLockIfPossible(hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.RANDOM, hashCode()); AbstractOperation operation = null; boolean isOwaspHookEnabled = NewRelicSecurity.getAgent().isLowPriorityInstrumentationEnabled(); if (isOwaspHookEnabled && LowSeverityHelper.isOwaspHookProcessingNeeded()){ @@ -152,7 +153,7 @@ public double nextDouble() { } public double nextGaussian() { - boolean isLockAcquired = acquireLockIfPossible(hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.RANDOM, hashCode()); AbstractOperation operation = null; boolean isOwaspHookEnabled = NewRelicSecurity.getAgent().isLowPriorityInstrumentationEnabled(); if (isOwaspHookEnabled && LowSeverityHelper.isOwaspHookProcessingNeeded()){ @@ -174,7 +175,7 @@ public double nextGaussian() { } public boolean nextBoolean() { - boolean isLockAcquired = acquireLockIfPossible(hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.RANDOM, hashCode()); AbstractOperation operation = null; boolean isOwaspHookEnabled = NewRelicSecurity.getAgent().isLowPriorityInstrumentationEnabled(); if (isOwaspHookEnabled && LowSeverityHelper.isOwaspHookProcessingNeeded()){ @@ -246,9 +247,9 @@ private void releaseLock(int hashCode) { } } - private boolean acquireLockIfPossible(int hashCode) { + private boolean acquireLockIfPossible(VulnerabilityCaseType random, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(RandomUtils.NR_SEC_RANDOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(random, RandomUtils.NR_SEC_RANDOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java b/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java index dad1e220d..b7621d8ee 100644 --- a/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java +++ b/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java @@ -4,6 +4,7 @@ import com.mongodb.binding.AsyncReadBinding; import com.mongodb.binding.ReadBinding; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -17,7 +18,7 @@ public class CommandReadOperation_Instrumentation { public T execute(final ReadBinding binding) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_READ, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -35,7 +36,7 @@ public T execute(final ReadBinding binding) { public void executeAsync(final AsyncReadBinding binding, final SingleResultCallback callback) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_READ, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } diff --git a/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java b/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java index 2c89cab27..1755a4fab 100644 --- a/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java +++ b/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java @@ -4,6 +4,7 @@ import com.mongodb.binding.AsyncWriteBinding; import com.mongodb.binding.WriteBinding; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -17,7 +18,7 @@ public class CommandWriteOperation_Instrumentation { public T execute(final WriteBinding binding) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_WRITE, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -35,7 +36,7 @@ public T execute(final WriteBinding binding) { public void executeAsync(final AsyncWriteBinding binding, final SingleResultCallback callback) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_WRITE, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } diff --git a/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/OperationExecutor_Instrumentation.java b/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/OperationExecutor_Instrumentation.java index eca14e3dd..9d61a25b1 100644 --- a/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/OperationExecutor_Instrumentation.java +++ b/instrumentation-security/mongodb-3.0/src/main/java/com/mongodb/operation/OperationExecutor_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -33,9 +34,9 @@ private void releaseLock(int hashCode) { } } - private boolean acquireLockIfPossible(int hashCode) { + private boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; @@ -44,7 +45,7 @@ private boolean acquireLockIfPossible(int hashCode) { public T execute(ReadOperation operation, ReadPreference readPreference) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getReadAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -62,7 +63,7 @@ public T execute(ReadOperation operation, ReadPreference readPreference) public T execute(WriteOperation operation) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getWriteAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } diff --git a/instrumentation-security/mongodb-3.0/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java b/instrumentation-security/mongodb-3.0/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java index eb6a3fe42..2c91aba67 100644 --- a/instrumentation-security/mongodb-3.0/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java +++ b/instrumentation-security/mongodb-3.0/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java @@ -15,6 +15,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.NoSQLOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -110,9 +111,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/OperationExecutor_Instrumentation.java b/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/OperationExecutor_Instrumentation.java index 0f5c11214..a33cbe032 100644 --- a/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/OperationExecutor_Instrumentation.java +++ b/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/OperationExecutor_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -35,9 +36,9 @@ private void releaseLock(int hashCode) { } } - private boolean acquireLockIfPossible(int hashCode) { + private boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; @@ -45,7 +46,7 @@ private boolean acquireLockIfPossible(int hashCode) { public T execute(ReadOperation operation, ReadPreference readPreference, ClientSession session) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getReadAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -63,7 +64,7 @@ public T execute(ReadOperation operation, ReadPreference readPreference, public T execute(ReadOperation operation, ReadPreference readPreference) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getReadAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -82,7 +83,7 @@ public T execute(ReadOperation operation, ReadPreference readPreference) public T execute(WriteOperation operation) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getWriteAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -101,7 +102,7 @@ public T execute(WriteOperation operation) { public T execute(WriteOperation operation, ClientSession session) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getWriteAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } diff --git a/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java b/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java index dad1e220d..b7621d8ee 100644 --- a/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java +++ b/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java @@ -4,6 +4,7 @@ import com.mongodb.binding.AsyncReadBinding; import com.mongodb.binding.ReadBinding; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -17,7 +18,7 @@ public class CommandReadOperation_Instrumentation { public T execute(final ReadBinding binding) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_READ, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -35,7 +36,7 @@ public T execute(final ReadBinding binding) { public void executeAsync(final AsyncReadBinding binding, final SingleResultCallback callback) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_READ, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } diff --git a/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java b/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java index 5de24d163..be2f081e0 100644 --- a/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java +++ b/instrumentation-security/mongodb-3.6/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java @@ -4,6 +4,7 @@ import com.mongodb.binding.AsyncWriteBinding; import com.mongodb.binding.WriteBinding; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -17,7 +18,7 @@ public class CommandWriteOperation_Instrumentation { public T execute(final WriteBinding binding) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_WRITE, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -35,7 +36,7 @@ public T execute(final WriteBinding binding) { public void executeAsync(final AsyncWriteBinding binding, final SingleResultCallback callback) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_WRITE, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } diff --git a/instrumentation-security/mongodb-3.6/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java b/instrumentation-security/mongodb-3.6/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java index 24894c897..b2f7c3f69 100644 --- a/instrumentation-security/mongodb-3.6/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java +++ b/instrumentation-security/mongodb-3.6/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java @@ -15,6 +15,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.NoSQLOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -122,9 +123,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/client/internal/OperationExecutor_Instrumentation.java b/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/client/internal/OperationExecutor_Instrumentation.java index a97325997..31b2762a0 100644 --- a/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/client/internal/OperationExecutor_Instrumentation.java +++ b/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/client/internal/OperationExecutor_Instrumentation.java @@ -8,6 +8,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -37,9 +38,9 @@ private void releaseLock(int hashCode) { } } - private boolean acquireLockIfPossible(int hashCode) { + private boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; @@ -47,7 +48,7 @@ private boolean acquireLockIfPossible(int hashCode) { public T execute(ReadOperation operation, ReadPreference readPreference, @Nullable ClientSession session) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getReadAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -65,7 +66,7 @@ public T execute(ReadOperation operation, ReadPreference readPreference, public T execute(ReadOperation operation, ReadPreference readPreference) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getReadAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -84,7 +85,7 @@ public T execute(ReadOperation operation, ReadPreference readPreference) public T execute(WriteOperation operation) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getWriteAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -103,7 +104,7 @@ public T execute(WriteOperation operation) { public T execute(WriteOperation operation, @Nullable ClientSession session) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getWriteAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } diff --git a/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java b/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java index dad1e220d..b7621d8ee 100644 --- a/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java +++ b/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java @@ -4,6 +4,7 @@ import com.mongodb.binding.AsyncReadBinding; import com.mongodb.binding.ReadBinding; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -17,7 +18,7 @@ public class CommandReadOperation_Instrumentation { public T execute(final ReadBinding binding) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_READ, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -35,7 +36,7 @@ public T execute(final ReadBinding binding) { public void executeAsync(final AsyncReadBinding binding, final SingleResultCallback callback) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_READ, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } diff --git a/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java b/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java index 2c89cab27..1755a4fab 100644 --- a/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java +++ b/instrumentation-security/mongodb-3.7/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java @@ -4,6 +4,7 @@ import com.mongodb.binding.AsyncWriteBinding; import com.mongodb.binding.WriteBinding; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -17,7 +18,7 @@ public class CommandWriteOperation_Instrumentation { public T execute(final WriteBinding binding) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_WRITE, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -35,7 +36,7 @@ public T execute(final WriteBinding binding) { public void executeAsync(final AsyncWriteBinding binding, final SingleResultCallback callback) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_WRITE, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } diff --git a/instrumentation-security/mongodb-3.7/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java b/instrumentation-security/mongodb-3.7/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java index 672fb2804..4a921da83 100644 --- a/instrumentation-security/mongodb-3.7/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java +++ b/instrumentation-security/mongodb-3.7/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java @@ -15,6 +15,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.NoSQLOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -120,9 +121,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/client/internal/OperationExecutor_Instrumentation.java b/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/client/internal/OperationExecutor_Instrumentation.java index e36c58706..4e89a0475 100644 --- a/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/client/internal/OperationExecutor_Instrumentation.java +++ b/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/client/internal/OperationExecutor_Instrumentation.java @@ -9,6 +9,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -38,9 +39,9 @@ private void releaseLock(int hashCode) { } } - private boolean acquireLockIfPossible(int hashCode) { + private boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; @@ -48,7 +49,7 @@ private boolean acquireLockIfPossible(int hashCode) { public T execute(ReadOperation operation, ReadPreference readPreference, ReadConcern readConcern, @Nullable com.mongodb.client.ClientSession session) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getReadAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -66,7 +67,7 @@ public T execute(ReadOperation operation, ReadPreference readPreference, public T execute(ReadOperation operation, ReadPreference readPreference, ReadConcern readConcern) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.getReadAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -85,7 +86,7 @@ public T execute(ReadOperation operation, ReadPreference readPreference, public T execute(WriteOperation operation, ReadConcern readConcern) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); try { if (isLockAcquired) { noSQLOperation = MongoUtil.getWriteAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); @@ -109,7 +110,7 @@ public T execute(WriteOperation operation, ReadConcern readConcern) { public T execute(WriteOperation operation, ReadConcern readConcern, @Nullable ClientSession session) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = acquireLockIfPossible(operation.hashCode()); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, operation.hashCode()); try { if (isLockAcquired) { noSQLOperation = MongoUtil.getWriteAbstractOperation(operation, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); diff --git a/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java b/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java index dad1e220d..b7621d8ee 100644 --- a/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java +++ b/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/operation/CommandReadOperation_Instrumentation.java @@ -4,6 +4,7 @@ import com.mongodb.binding.AsyncReadBinding; import com.mongodb.binding.ReadBinding; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -17,7 +18,7 @@ public class CommandReadOperation_Instrumentation { public T execute(final ReadBinding binding) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_READ, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -35,7 +36,7 @@ public T execute(final ReadBinding binding) { public void executeAsync(final AsyncReadBinding binding, final SingleResultCallback callback) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_READ, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } diff --git a/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java b/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java index 2c89cab27..1755a4fab 100644 --- a/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java +++ b/instrumentation-security/mongodb-3.8/src/main/java/com/mongodb/operation/CommandWriteOperation_Instrumentation.java @@ -4,6 +4,7 @@ import com.mongodb.binding.AsyncWriteBinding; import com.mongodb.binding.WriteBinding; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -17,7 +18,7 @@ public class CommandWriteOperation_Instrumentation { public T execute(final WriteBinding binding) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_WRITE, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } @@ -35,7 +36,7 @@ public T execute(final WriteBinding binding) { public void executeAsync(final AsyncWriteBinding binding, final SingleResultCallback callback) { AbstractOperation noSQLOperation = null; - boolean isLockAcquired = MongoUtil.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = MongoUtil.acquireLockIfPossible(VulnerabilityCaseType.NOSQL_DB_COMMAND, this.hashCode()); if (isLockAcquired) { noSQLOperation = MongoUtil.recordMongoOperation(command, MongoUtil.OP_WRITE, this.getClass().getName(), MongoUtil.METHOD_EXECUTE); } diff --git a/instrumentation-security/mongodb-3.8/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java b/instrumentation-security/mongodb-3.8/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java index 255c9612f..f55664b8b 100644 --- a/instrumentation-security/mongodb-3.8/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java +++ b/instrumentation-security/mongodb-3.8/src/main/java/com/newrelic/agent/security/instrumentation/mongo/MongoUtil.java @@ -15,6 +15,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.NoSQLOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -108,9 +109,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType nosqlDbCommand, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(nosqlDbCommand, MongoUtil.NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; 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 ca9faf1b5..069d85f3e 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 @@ -87,8 +87,11 @@ private static void preprocessSecurityHook(HttpRequestContext requestContext) { private static void postProcessSecurityHook() { try { - if (!NewRelicSecurity.isHookProcessingActive() - ) { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } + + if (!NewRelicSecurity.isHookProcessingActive()) { return; } ServletHelper.executeBeforeExitingTransaction(); 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 3ebd77e15..f59a7efc4 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 @@ -81,8 +81,10 @@ private void preprocessSecurityHook(HttpRequestContext requestContext) { private void postProcessSecurityHook() { try { - if (!NewRelicSecurity.isHookProcessingActive() - ) { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } + if (!NewRelicSecurity.isHookProcessingActive()) { return; } ServletHelper.executeBeforeExitingTransaction(); 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 521808b1a..df4b18d05 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 @@ -87,8 +87,10 @@ private static void preprocessSecurityHook(HttpRequestContext requestContext) { private static void postProcessSecurityHook() { try { - if (!NewRelicSecurity.isHookProcessingActive() - ) { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } + if (!NewRelicSecurity.isHookProcessingActive()) { return; } ServletHelper.executeBeforeExitingTransaction(); 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 0d1c0d15f..cda5cf549 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 @@ -81,8 +81,10 @@ private void preprocessSecurityHook(HttpRequestContext requestContext) { private void postProcessSecurityHook() { try { - if (!NewRelicSecurity.isHookProcessingActive() - ) { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } + if (!NewRelicSecurity.isHookProcessingActive()) { return; } ServletHelper.executeBeforeExitingTransaction(); diff --git a/instrumentation-security/nashorn-jsinjection/src/main/java/jdk/nashorn/api/scripting/NashornScriptEngine_Instrumentation.java b/instrumentation-security/nashorn-jsinjection/src/main/java/jdk/nashorn/api/scripting/NashornScriptEngine_Instrumentation.java index 1236a647f..25b8007db 100644 --- a/instrumentation-security/nashorn-jsinjection/src/main/java/jdk/nashorn/api/scripting/NashornScriptEngine_Instrumentation.java +++ b/instrumentation-security/nashorn-jsinjection/src/main/java/jdk/nashorn/api/scripting/NashornScriptEngine_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.JSInjectionOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -22,7 +23,7 @@ public class NashornScriptEngine_Instrumentation { private Object evalImpl(ScriptFunction_Instrumentation script, ScriptContext ctxt, Global ctxtGlobal) throws ScriptException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.JAVASCRIPT_INJECTION); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(script, JSEngineUtils.METHOD_EVAL_IMPL); @@ -41,7 +42,7 @@ private Object evalImpl(ScriptFunction_Instrumentation script, ScriptContext ctx } private Object evalImpl(final Source src, final ScriptContext ctxt) throws ScriptException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.JAVASCRIPT_INJECTION); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(String.valueOf(src.getContent()), JSEngineUtils.METHOD_EVAL_IMPL); @@ -127,9 +128,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType javascriptInjection) { try { - return GenericHelper.acquireLockIfPossible(JSEngineUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(javascriptInjection, JSEngineUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/channel/ChannelInboundHandler_Instrumentation.java b/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/channel/ChannelInboundHandler_Instrumentation.java index 10c000dc3..8ef69f185 100644 --- a/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/channel/ChannelInboundHandler_Instrumentation.java +++ b/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/channel/ChannelInboundHandler_Instrumentation.java @@ -9,6 +9,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -23,7 +24,7 @@ public abstract class ChannelInboundHandler_Instrumentation { public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { boolean isLockAcquired = false; if (msg instanceof HttpRequest || msg instanceof HttpContent){ - isLockAcquired = NettyUtils.acquireNettyLockIfPossible(NettyUtils.NR_SEC_NETTY_OPERATIONAL_LOCK); + isLockAcquired = NettyUtils.acquireNettyLockIfPossible(VulnerabilityCaseType.REFLECTED_XSS, NettyUtils.NR_SEC_NETTY_OPERATIONAL_LOCK); } if (isLockAcquired) { NettyUtils.processSecurityRequest(ctx, msg, getClass().getName()); diff --git a/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/channel/ChannelOutboundHandler_Instrumentation.java b/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/channel/ChannelOutboundHandler_Instrumentation.java index 6a93460f1..3a6bfd8d4 100644 --- a/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/channel/ChannelOutboundHandler_Instrumentation.java +++ b/instrumentation-security/netty-4.0.0/src/main/java/security/io/netty400/channel/ChannelOutboundHandler_Instrumentation.java @@ -7,6 +7,7 @@ package security.io.netty400.channel; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -23,7 +24,7 @@ public abstract class ChannelOutboundHandler_Instrumentation { public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { boolean isLockAcquired = false; if (msg instanceof FullHttpResponse){ - isLockAcquired = NettyUtils.acquireNettyLockIfPossible(NettyUtils.NR_SEC_NETTY_OPERATIONAL_LOCK_OUTBOUND); + isLockAcquired = NettyUtils.acquireNettyLockIfPossible(VulnerabilityCaseType.REFLECTED_XSS, NettyUtils.NR_SEC_NETTY_OPERATIONAL_LOCK_OUTBOUND); } if (isLockAcquired) { NettyUtils.processSecurityResponse(ctx, msg); 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 ecdcc8fea..81c468ccc 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 @@ -8,6 +8,7 @@ import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; 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; @@ -229,22 +230,11 @@ public static boolean isNettyLockAcquired(String operationLock) { return false; } - public static boolean acquireNettyLockIfPossible(String operationLock) { - try { - if (NewRelicSecurity.isHookProcessingActive() && - !isNettyLockAcquired(operationLock)) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(operationLock + Thread.currentThread().getId(), true); - return true; - } - } catch (Throwable ignored){} - return false; + public static boolean acquireNettyLockIfPossible(VulnerabilityCaseType reflectedXss, String operationLock) { + return GenericHelper.acquireLockIfPossible(reflectedXss, operationLock+ Thread.currentThread().getId()); } public static void releaseNettyLock(String operationLock) { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(operationLock + Thread.currentThread().getId(), null); - } - } catch (Throwable ignored){} + GenericHelper.releaseLock(operationLock + Thread.currentThread().getId()); } } diff --git a/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/channel/ChannelInboundHandler_Instrumentation.java b/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/channel/ChannelInboundHandler_Instrumentation.java index 10c000dc3..8ef69f185 100644 --- a/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/channel/ChannelInboundHandler_Instrumentation.java +++ b/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/channel/ChannelInboundHandler_Instrumentation.java @@ -9,6 +9,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -23,7 +24,7 @@ public abstract class ChannelInboundHandler_Instrumentation { public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { boolean isLockAcquired = false; if (msg instanceof HttpRequest || msg instanceof HttpContent){ - isLockAcquired = NettyUtils.acquireNettyLockIfPossible(NettyUtils.NR_SEC_NETTY_OPERATIONAL_LOCK); + isLockAcquired = NettyUtils.acquireNettyLockIfPossible(VulnerabilityCaseType.REFLECTED_XSS, NettyUtils.NR_SEC_NETTY_OPERATIONAL_LOCK); } if (isLockAcquired) { NettyUtils.processSecurityRequest(ctx, msg, getClass().getName()); diff --git a/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/channel/ChannelOutboundHandler_Instrumentation.java b/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/channel/ChannelOutboundHandler_Instrumentation.java index 6a93460f1..3a6bfd8d4 100644 --- a/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/channel/ChannelOutboundHandler_Instrumentation.java +++ b/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/channel/ChannelOutboundHandler_Instrumentation.java @@ -7,6 +7,7 @@ package security.io.netty400.channel; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -23,7 +24,7 @@ public abstract class ChannelOutboundHandler_Instrumentation { public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { boolean isLockAcquired = false; if (msg instanceof FullHttpResponse){ - isLockAcquired = NettyUtils.acquireNettyLockIfPossible(NettyUtils.NR_SEC_NETTY_OPERATIONAL_LOCK_OUTBOUND); + isLockAcquired = NettyUtils.acquireNettyLockIfPossible(VulnerabilityCaseType.REFLECTED_XSS, NettyUtils.NR_SEC_NETTY_OPERATIONAL_LOCK_OUTBOUND); } if (isLockAcquired) { NettyUtils.processSecurityResponse(ctx, msg); diff --git a/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/utils/NettyUtils.java b/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/utils/NettyUtils.java index ecdcc8fea..7901d121d 100644 --- a/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/utils/NettyUtils.java +++ b/instrumentation-security/netty-4.0.8/src/main/java/security/io/netty400/utils/NettyUtils.java @@ -8,6 +8,7 @@ import com.newrelic.api.agent.security.schema.AgentMetaData; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; 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; @@ -229,22 +230,11 @@ public static boolean isNettyLockAcquired(String operationLock) { return false; } - public static boolean acquireNettyLockIfPossible(String operationLock) { - try { - if (NewRelicSecurity.isHookProcessingActive() && - !isNettyLockAcquired(operationLock)) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(operationLock + Thread.currentThread().getId(), true); - return true; - } - } catch (Throwable ignored){} - return false; + public static boolean acquireNettyLockIfPossible(VulnerabilityCaseType reflectedXss, String operationLock) { + return GenericHelper.acquireLockIfPossible(reflectedXss, operationLock + Thread.currentThread().getId()); } public static void releaseNettyLock(String operationLock) { - try { - if(NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(operationLock + Thread.currentThread().getId(), null); - } - } catch (Throwable ignored){} + GenericHelper.releaseLock(operationLock + Thread.currentThread().getId()); } } diff --git a/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_0/NingHelper.java b/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_0/NingHelper.java index 8711a0146..8234aaa1b 100644 --- a/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_0/NingHelper.java +++ b/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_0/NingHelper.java @@ -6,15 +6,13 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.ning.http.client.Request; -import java.net.URI; -import java.net.URISyntaxException; - public class NingHelper { public static final String METHOD_NAME_EXECUTE = "execute"; public static final String NR_SEC_CUSTOM_ATTRIB_NAME = "SSRF_OPERATION_LOCK_NING-"; @@ -81,9 +79,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(httpRequest, NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java b/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java index b8cd37149..7bb94be73 100644 --- a/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java +++ b/instrumentation-security/ning-async-http-client-1.0.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -20,7 +21,7 @@ public class AsyncHttpProvider_Instrumentation { public Future execute(Request request, AsyncHandler handler) throws IOException { - boolean isLockAcquired = NingHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = NingHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST, this.hashCode()); AbstractOperation operation = null; URI uri = null; Future returnObj = null; diff --git a/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java index c2d17e323..16bdab028 100644 --- a/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java +++ b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_1/NingHelper.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -73,9 +74,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(httpRequest, NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java index 04511aa11..4e0957511 100644 --- a/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java +++ b/instrumentation-security/ning-async-http-client-1.1.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java @@ -2,6 +2,7 @@ import com.newrelic.agent.security.instrumentation.ning.http_1_1.NingHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -15,7 +16,7 @@ public class AsyncHttpProvider_Instrumentation { public Future execute(Request request, AsyncHandler handler) throws IOException { - boolean isLockAcquired = NingHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = NingHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST, this.hashCode()); AbstractOperation operation = null; URI uri = null; Future returnObj = null; diff --git a/instrumentation-security/ning-async-http-client-1.6.1/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_6_1/NingHelper.java b/instrumentation-security/ning-async-http-client-1.6.1/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_6_1/NingHelper.java index c4ecbb2f2..b6db3e353 100644 --- a/instrumentation-security/ning-async-http-client-1.6.1/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_6_1/NingHelper.java +++ b/instrumentation-security/ning-async-http-client-1.6.1/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_6_1/NingHelper.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -78,9 +79,9 @@ public static void releaseLock(int hashCode) { } } - public static boolean acquireLockIfPossible(int hashCode) { + public static boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest, int hashCode) { try { - return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); + return GenericHelper.acquireLockIfPossible(httpRequest, NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); } catch (Throwable ignored) { } return false; diff --git a/instrumentation-security/ning-async-http-client-1.6.1/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java b/instrumentation-security/ning-async-http-client-1.6.1/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java index 97da6d33c..e464b2e96 100644 --- a/instrumentation-security/ning-async-http-client-1.6.1/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java +++ b/instrumentation-security/ning-async-http-client-1.6.1/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -15,7 +16,7 @@ public class AsyncHttpProvider_Instrumentation { public ListenableFuture execute(Request request, AsyncHandler handler) { - boolean isLockAcquired = NingHelper.acquireLockIfPossible(this.hashCode()); + boolean isLockAcquired = NingHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST, this.hashCode()); AbstractOperation operation = null; URI uri = null; ListenableFuture returnObj = null; diff --git a/instrumentation-security/okhttp-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp30/OkhttpHelper.java b/instrumentation-security/okhttp-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp30/OkhttpHelper.java index 21c25c193..deb8b30f2 100644 --- a/instrumentation-security/okhttp-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp30/OkhttpHelper.java +++ b/instrumentation-security/okhttp-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp30/OkhttpHelper.java @@ -27,35 +27,7 @@ public static boolean skipExistsEvent() { return false; } - public static boolean isLockAcquired() { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(getNrSecCustomAttribName(), Boolean.class)); - } catch (Throwable ignored) {} - return false; - } - - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && - !isLockAcquired()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), true); - return true; - } - } catch (Throwable ignored){} - return false; - } - - public static void releaseLock() { - try { - if (NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), null); - } - } catch (Throwable ignored) { - } - } - - private static String getNrSecCustomAttribName() { + public static String getNrSecCustomAttribName() { return NR_SEC_CUSTOM_ATTRIB_NAME + Thread.currentThread().getId(); } diff --git a/instrumentation-security/okhttp-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp30/RealCall_Instrumentation.java b/instrumentation-security/okhttp-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp30/RealCall_Instrumentation.java index 20ce78e00..942e374c7 100644 --- a/instrumentation-security/okhttp-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp30/RealCall_Instrumentation.java +++ b/instrumentation-security/okhttp-3.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp30/RealCall_Instrumentation.java @@ -10,6 +10,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -23,16 +24,11 @@ abstract class RealCall_Instrumentation { Request originalRequest = Weaver.callOriginal(); private void releaseLock() { - try { - OkhttpHelper.releaseLock(); - } catch (Throwable ignored) {} + GenericHelper.releaseLock(OkhttpHelper.getNrSecCustomAttribName()); } - private boolean acquireLockIfPossible() { - try { - return OkhttpHelper.acquireLockIfPossible(); - } catch (Throwable ignored) {} - return false; + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, OkhttpHelper.getNrSecCustomAttribName()); } /** @@ -40,7 +36,7 @@ private boolean acquireLockIfPossible() { * problem in the agent accessing constructor parameters in any non-no-arg constructor. */ public Response execute() { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = OkhttpHelper.preprocessSecurityHook(getUrl(originalRequest), this.getClass().getName(), diff --git a/instrumentation-security/okhttp-3.5.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp35/OkhttpHelper.java b/instrumentation-security/okhttp-3.5.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp35/OkhttpHelper.java index ea4ee3192..954687e05 100644 --- a/instrumentation-security/okhttp-3.5.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp35/OkhttpHelper.java +++ b/instrumentation-security/okhttp-3.5.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp35/OkhttpHelper.java @@ -27,35 +27,7 @@ public static boolean skipExistsEvent() { return false; } - public static boolean isLockAcquired() { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(getNrSecCustomAttribName(), Boolean.class)); - } catch (Throwable ignored) {} - return false; - } - - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && - !isLockAcquired()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), true); - return true; - } - } catch (Throwable ignored){} - return false; - } - - public static void releaseLock() { - try { - if (NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), null); - } - } catch (Throwable ignored) { - } - } - - private static String getNrSecCustomAttribName() { + public static String getNrSecCustomAttribName() { return NR_SEC_CUSTOM_ATTRIB_NAME + Thread.currentThread().getId(); } diff --git a/instrumentation-security/okhttp-3.5.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp35/http/HttpCodec_Instrumentation.java b/instrumentation-security/okhttp-3.5.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp35/http/HttpCodec_Instrumentation.java index 4da46eb6b..73e218b5d 100644 --- a/instrumentation-security/okhttp-3.5.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp35/http/HttpCodec_Instrumentation.java +++ b/instrumentation-security/okhttp-3.5.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp35/http/HttpCodec_Instrumentation.java @@ -10,6 +10,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -21,7 +22,7 @@ public abstract class HttpCodec_Instrumentation { public void writeRequestHeaders(Request request) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if (isLockAcquired) { operation = OkhttpHelper.preprocessSecurityHook(getUrl(request), this.getClass().getName(), @@ -42,18 +43,11 @@ public void writeRequestHeaders(Request request) { } private void releaseLock() { - try { - OkhttpHelper.releaseLock(); - } catch (Throwable ignored) { - } + GenericHelper.releaseLock(OkhttpHelper.getNrSecCustomAttribName()); } - private boolean acquireLockIfPossible() { - try { - return OkhttpHelper.acquireLockIfPossible(); - } catch (Throwable ignored) { - } - return false; + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, OkhttpHelper.getNrSecCustomAttribName()); } private String getUrl(Request originalRequest) { diff --git a/instrumentation-security/okhttp-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp40/ExchangeCodec_Instrumentation.java b/instrumentation-security/okhttp-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp40/ExchangeCodec_Instrumentation.java index d63ee8803..4831696db 100644 --- a/instrumentation-security/okhttp-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp40/ExchangeCodec_Instrumentation.java +++ b/instrumentation-security/okhttp-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp40/ExchangeCodec_Instrumentation.java @@ -10,6 +10,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -22,16 +23,11 @@ public abstract class ExchangeCodec_Instrumentation { private void releaseLock() { - try { - OkhttpHelper.releaseLock(); - } catch (Throwable ignored) {} + GenericHelper.releaseLock(OkhttpHelper.getNrSecCustomAttribName()); } - private boolean acquireLockIfPossible() { - try { - return OkhttpHelper.acquireLockIfPossible(); - } catch (Throwable ignored) {} - return false; + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, OkhttpHelper.getNrSecCustomAttribName()); } private String getUrl(Request originalRequest) { @@ -46,7 +42,7 @@ private String getUrl(Request originalRequest) { } public void writeRequestHeaders(Request request) throws IOException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = OkhttpHelper.preprocessSecurityHook(getUrl(request), this.getClass().getName(), OkhttpHelper.METHOD_EXECUTE); diff --git a/instrumentation-security/okhttp-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp40/OkhttpHelper.java b/instrumentation-security/okhttp-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp40/OkhttpHelper.java index 7f2d936da..2274e5ef7 100644 --- a/instrumentation-security/okhttp-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp40/OkhttpHelper.java +++ b/instrumentation-security/okhttp-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/okhttp40/OkhttpHelper.java @@ -27,35 +27,7 @@ public static boolean skipExistsEvent() { return false; } - public static boolean isLockAcquired() { - try { - return NewRelicSecurity.isHookProcessingActive() && - Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(getNrSecCustomAttribName(), Boolean.class)); - } catch (Throwable ignored) {} - return false; - } - - public static boolean acquireLockIfPossible() { - try { - if (NewRelicSecurity.isHookProcessingActive() && - !isLockAcquired()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), true); - return true; - } - } catch (Throwable ignored){} - return false; - } - - public static void releaseLock() { - try { - if (NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(getNrSecCustomAttribName(), null); - } - } catch (Throwable ignored) { - } - } - - private static String getNrSecCustomAttribName() { + public static String getNrSecCustomAttribName() { return NR_SEC_CUSTOM_ATTRIB_NAME + Thread.currentThread().getId(); } diff --git a/instrumentation-security/r2dbc-generic/src/main/java/io/r2dbc/spi/Batch_Instrumentation.java b/instrumentation-security/r2dbc-generic/src/main/java/io/r2dbc/spi/Batch_Instrumentation.java index f8fccbf2d..859b689f0 100644 --- a/instrumentation-security/r2dbc-generic/src/main/java/io/r2dbc/spi/Batch_Instrumentation.java +++ b/instrumentation-security/r2dbc-generic/src/main/java/io/r2dbc/spi/Batch_Instrumentation.java @@ -2,6 +2,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.R2dbcHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.NewField; import com.newrelic.api.agent.weaver.Weave; @@ -19,7 +20,7 @@ public Batch add(String s){ } public Publisher execute() { - boolean isLockAcquired = R2dbcHelper.acquireLockIfPossible(); + boolean isLockAcquired = R2dbcHelper.acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if (isLockAcquired) { operation = R2dbcHelper.preprocessSecurityHook(sql, R2dbcHelper.METHOD_EXECUTE, this.getClass().getName(), null, false); diff --git a/instrumentation-security/r2dbc-generic/src/main/java/io/r2dbc/spi/Statement_Instrumention.java b/instrumentation-security/r2dbc-generic/src/main/java/io/r2dbc/spi/Statement_Instrumention.java index 9ca41985b..34934c952 100644 --- a/instrumentation-security/r2dbc-generic/src/main/java/io/r2dbc/spi/Statement_Instrumention.java +++ b/instrumentation-security/r2dbc-generic/src/main/java/io/r2dbc/spi/Statement_Instrumention.java @@ -2,6 +2,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.R2dbcHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.NewField; import com.newrelic.api.agent.weaver.Weave; @@ -25,7 +26,7 @@ public class Statement_Instrumention { private boolean lock = false; public Publisher execute() { - boolean isLockAcquired = R2dbcHelper.acquireLockIfPossible(); + boolean isLockAcquired = R2dbcHelper.acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if (isLockAcquired) { operation = R2dbcHelper.preprocessSecurityHook(sql, R2dbcHelper.METHOD_EXECUTE, this.getClass().getName(), params, isPrepared); diff --git a/instrumentation-security/r2dbc-h2/src/main/java/io/r2dbc/h2/client/Client_Instrumentation.java b/instrumentation-security/r2dbc-h2/src/main/java/io/r2dbc/h2/client/Client_Instrumentation.java index ccada5043..99d5ea4db 100644 --- a/instrumentation-security/r2dbc-h2/src/main/java/io/r2dbc/h2/client/Client_Instrumentation.java +++ b/instrumentation-security/r2dbc-h2/src/main/java/io/r2dbc/h2/client/Client_Instrumentation.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.R2dbcHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.R2DBCVendor; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SQLOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -18,7 +19,7 @@ public class Client_Instrumentation { public void execute(String sql) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = R2dbcHelper.acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND); AbstractOperation operation = null; if (isLockAcquired) { operation = preprocessSecurityHook(sql, R2dbcHelper.METHOD_EXECUTE); @@ -81,12 +82,4 @@ private void releaseLock() { } catch (Throwable ignored) { } } - - private boolean acquireLockIfPossible() { - try { - return R2dbcHelper.acquireLockIfPossible(); - } catch (Throwable ignored) { - } - return false; - } } diff --git a/instrumentation-security/rhino-jsinjection/src/main/java/org/mozilla/javascript/ScriptRuntime_Instrumentation.java b/instrumentation-security/rhino-jsinjection/src/main/java/org/mozilla/javascript/ScriptRuntime_Instrumentation.java index eab41aa5d..7a5c2ffbc 100644 --- a/instrumentation-security/rhino-jsinjection/src/main/java/org/mozilla/javascript/ScriptRuntime_Instrumentation.java +++ b/instrumentation-security/rhino-jsinjection/src/main/java/org/mozilla/javascript/ScriptRuntime_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.JSInjectionOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -22,7 +23,7 @@ public static Object doTopCall(Callable callable, Context_Instrumentation cx, Sc AbstractOperation operation = null; if(cx != null) { code = cx.hashCode(); - isLockAcquired = acquireLockIfPossible(code); + isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.JAVASCRIPT_INJECTION, code); if (isLockAcquired) { operation = preprocessSecurityHook(code, JSEngineUtils.METHOD_EXEC, cx); } @@ -81,9 +82,9 @@ private static void releaseLock(int code) { } catch (Throwable ignored) {} } - private static boolean acquireLockIfPossible(int code) { + private static boolean acquireLockIfPossible(VulnerabilityCaseType javascriptInjection, int code) { try { - return GenericHelper.acquireLockIfPossible(JSEngineUtils.NR_SEC_CUSTOM_ATTRIB_NAME+code); + return GenericHelper.acquireLockIfPossible(javascriptInjection, JSEngineUtils.NR_SEC_CUSTOM_ATTRIB_NAME+code); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/saxpath/src/main/java/org/saxpath/XPathReader_Instrumentation.java b/instrumentation-security/saxpath/src/main/java/org/saxpath/XPathReader_Instrumentation.java index 438adef1d..fd01d9a7b 100644 --- a/instrumentation-security/saxpath/src/main/java/org/saxpath/XPathReader_Instrumentation.java +++ b/instrumentation-security/saxpath/src/main/java/org/saxpath/XPathReader_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.XPathOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -17,7 +18,7 @@ public abstract class XPathReader_Instrumentation { public void parse(String xpath) throws SAXPathException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(xpath, XPATHUtils.METHOD_PARSE); @@ -73,9 +74,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType xpath) { try { - return GenericHelper.acquireLockIfPossible(XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(xpath, XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } 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 bf9930a22..1b5a12ea2 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 @@ -93,6 +93,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp private void postProcessSecurityHook(ServletRequest request, ServletResponse response) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive() || Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute("RXSS_PROCESSED", Boolean.class)) ) { return; 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 c62d5a0a7..e4cdc168d 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 @@ -94,6 +94,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp private void postProcessSecurityHook(ServletRequest request, ServletResponse response) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive() || Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute("RXSS_PROCESSED", Boolean.class)) ) { return; 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 e3ab77671..be10a2e4d 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 @@ -99,6 +99,9 @@ private void preprocessSecurityHook(ServletRequest_Instrumentation request, Serv private void postProcessSecurityHook(ServletRequest_Instrumentation request, ServletResponse_Instrumentation response) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive() || Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute("RXSS_PROCESSED", Boolean.class)) ) { return; 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 4ffa56d11..1362bbe9c 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 @@ -92,6 +92,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp private void postProcessSecurityHook(ServletRequest request, ServletResponse response) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive() || Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute("RXSS_PROCESSED", Boolean.class)) ) { return; 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 fa7051cb3..e82bf14d1 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 @@ -94,6 +94,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp private void postProcessSecurityHook(ServletRequest request, ServletResponse response) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive() || Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute("RXSS_PROCESSED", Boolean.class)) ) { return; 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 a8b32bfe1..803e80689 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 @@ -98,6 +98,9 @@ private void preprocessSecurityHook(ServletRequest_Instrumentation request, Serv private void postProcessSecurityHook(ServletRequest_Instrumentation request, ServletResponse_Instrumentation response) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive() || Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute("RXSS_PROCESSED", Boolean.class)) ) { return; 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 3b2ff79a9..d602a19d9 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 @@ -93,6 +93,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp private void postProcessSecurityHook(ServletRequest request, ServletResponse response) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive() || Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute("RXSS_PROCESSED", Boolean.class)) ) { return; 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 c2855bd94..5edd9af5c 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 @@ -94,6 +94,9 @@ private void preprocessSecurityHook(ServletRequest request, ServletResponse resp private void postProcessSecurityHook(ServletRequest request, ServletResponse response) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive() || Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute("RXSS_PROCESSED", Boolean.class)) ) { return; 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 d7ac8309c..3eb80fe5a 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 @@ -98,6 +98,9 @@ private void preprocessSecurityHook(ServletRequest_Instrumentation request, Serv private void postProcessSecurityHook(ServletRequest_Instrumentation request, ServletResponse_Instrumentation response) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive() || Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute("RXSS_PROCESSED", Boolean.class)) ) { return; diff --git a/instrumentation-security/spray-can-1.3.1/src/main/scala/spray/can/rendering/ResponseRendering_Instrumentation.java b/instrumentation-security/spray-can-1.3.1/src/main/scala/spray/can/rendering/ResponseRendering_Instrumentation.java index ccfccafa1..36717c4e3 100644 --- a/instrumentation-security/spray-can-1.3.1/src/main/scala/spray/can/rendering/ResponseRendering_Instrumentation.java +++ b/instrumentation-security/spray-can-1.3.1/src/main/scala/spray/can/rendering/ResponseRendering_Instrumentation.java @@ -3,6 +3,7 @@ import akka.event.LoggingAdapter; import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -18,7 +19,7 @@ public class ResponseRendering_Instrumentation { private static boolean renderResponse$1(ResponseRenderingComponent component, HttpResponse response, Rendering rendering, ResponsePartRenderingContext context, LoggingAdapter adapter) { - boolean isLockAcquired = GenericHelper.acquireLockIfPossible(SprayHttpUtils.getNrSecCustomAttribNameForResponse()); + boolean isLockAcquired = GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.REFLECTED_XSS, SprayHttpUtils.getNrSecCustomAttribNameForResponse()); try { if (isLockAcquired && response.entity().nonEmpty()) { NewRelicSecurity.getAgent().getSecurityMetaData().getResponse().setResponseBody(new StringBuilder(response.entity().data().asString(StandardCharsets.UTF_8))); diff --git a/instrumentation-security/spray-http-1.3.1/src/main/scala/spray/httpx/marshalling/SprayToResponseMarshallingContext.java b/instrumentation-security/spray-http-1.3.1/src/main/scala/spray/httpx/marshalling/SprayToResponseMarshallingContext.java index 41d03a37e..0c23bf39a 100644 --- a/instrumentation-security/spray-http-1.3.1/src/main/scala/spray/httpx/marshalling/SprayToResponseMarshallingContext.java +++ b/instrumentation-security/spray-http-1.3.1/src/main/scala/spray/httpx/marshalling/SprayToResponseMarshallingContext.java @@ -11,6 +11,7 @@ import com.newrelic.api.agent.Trace; import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; @@ -25,7 +26,7 @@ public class SprayToResponseMarshallingContext { @Trace(async = true) public void marshalTo(HttpResponse httpResponse) { - boolean isLockAcquired = GenericHelper.acquireLockIfPossible(SprayHttpUtils.getNrSecCustomAttribNameForResponse()); + boolean isLockAcquired = GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.REFLECTED_XSS, SprayHttpUtils.getNrSecCustomAttribNameForResponse()); try { if (isLockAcquired && httpResponse.entity().nonEmpty()) { NewRelicSecurity.getAgent().getSecurityMetaData().getResponse().setResponseBody(new StringBuilder(httpResponse.entity().data().asString(StandardCharsets.UTF_8))); diff --git a/instrumentation-security/spring-webclient-5.0/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction_Instrumentation.java b/instrumentation-security/spring-webclient-5.0/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction_Instrumentation.java index e773eeb16..92675bf0d 100644 --- a/instrumentation-security/spring-webclient-5.0/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction_Instrumentation.java +++ b/instrumentation-security/spring-webclient-5.0/src/main/java/org/springframework/web/reactive/function/client/ExchangeFunction_Instrumentation.java @@ -10,6 +10,7 @@ import com.newrelic.agent.security.instrumentation.spring.client5.SpringWebClientHelper; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -19,7 +20,7 @@ public class ExchangeFunction_Instrumentation { public Mono exchange(ClientRequest request) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = SpringWebClientHelper.preprocessSecurityHook(request.url(), request.method(), this.getClass().getName(), SpringWebClientHelper.METHOD_EXECHANGE); @@ -45,8 +46,8 @@ private void releaseLock() { } - private boolean acquireLockIfPossible() { - return GenericHelper.acquireLockIfPossible(SpringWebClientHelper.getNrSecCustomAttribName()); + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, SpringWebClientHelper.getNrSecCustomAttribName()); } } diff --git a/instrumentation-security/spymemcached-2.12.0/src/main/java/net/spy/memcached/MemcachedClient_Instrumentation.java b/instrumentation-security/spymemcached-2.12.0/src/main/java/net/spy/memcached/MemcachedClient_Instrumentation.java index 66658d078..107c9db98 100644 --- a/instrumentation-security/spymemcached-2.12.0/src/main/java/net/spy/memcached/MemcachedClient_Instrumentation.java +++ b/instrumentation-security/spymemcached-2.12.0/src/main/java/net/spy/memcached/MemcachedClient_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.MemcachedOperation; import com.newrelic.api.agent.weaver.Weave; @@ -19,7 +20,7 @@ public class MemcachedClient_Instrumentation { private OperationFuture asyncStore(StoreType storeType, String key, int exp, T value, Transcoder tc) { - boolean isLockAcquired = GenericHelper.acquireLockIfPossible(MemcachedHelper.NR_SEC_CUSTOM_ATTRIB_NAME, value.hashCode()); + boolean isLockAcquired = GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, MemcachedHelper.NR_SEC_CUSTOM_ATTRIB_NAME, value.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = MemcachedHelper.preprocessSecurityHook(storeType.name(), MemcachedHelper.WRITE, key, value, this.getClass().getName(), MemcachedHelper.METHOD_ASYNC_STORE); @@ -38,7 +39,7 @@ private OperationFuture asyncStore(StoreType storeType, private OperationFuture asyncCat(ConcatenationType catType, long cas, String key, T value, Transcoder tc) { - boolean isLockAcquired = GenericHelper.acquireLockIfPossible(MemcachedHelper.NR_SEC_CUSTOM_ATTRIB_NAME, value.hashCode()); + boolean isLockAcquired = GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, MemcachedHelper.NR_SEC_CUSTOM_ATTRIB_NAME, value.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = MemcachedHelper.preprocessSecurityHook(catType.name(), MemcachedHelper.UPDATE, key, value, this.getClass().getName(), MemcachedHelper.METHOD_ASYNC_CAT); @@ -57,7 +58,7 @@ private OperationFuture asyncCat(ConcatenationType catType, public OperationFuture asyncCAS(String key, long casId, int exp, T value, Transcoder tc) { - boolean isLockAcquired = GenericHelper.acquireLockIfPossible(MemcachedHelper.NR_SEC_CUSTOM_ATTRIB_NAME, value.hashCode()); + boolean isLockAcquired = GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.CACHING_DATA_STORE, MemcachedHelper.NR_SEC_CUSTOM_ATTRIB_NAME, value.hashCode()); AbstractOperation operation = null; if (isLockAcquired) { operation = MemcachedHelper.preprocessSecurityHook(StoreType.set.name(), MemcachedHelper.WRITE, key, value, this.getClass().getName(), MemcachedHelper.METHOD_ASYNC_CAS); 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 742298c65..83313fc5a 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 @@ -77,6 +77,9 @@ private void preprocessSecurityHook(HttpExchange exchange) { } private void postProcessSecurityHook(HttpExchange exchange) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive()) { return; } 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 90c4cdb6d..13ffb8068 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 @@ -77,6 +77,9 @@ private void preprocessSecurityHook(HttpExchange exchange) { } private void postProcessSecurityHook(HttpExchange exchange) { try { + if(NewRelicSecurity.getAgent().getIastDetectionCategory().getRxssEnabled()){ + return; + } if (!NewRelicSecurity.isHookProcessingActive()) { return; } diff --git a/instrumentation-security/unboundid-ldapsdk/src/main/java/com/unboundid/ldap/sdk/LDAPInterface_Instrumentation.java b/instrumentation-security/unboundid-ldapsdk/src/main/java/com/unboundid/ldap/sdk/LDAPInterface_Instrumentation.java index 25132bd44..6ff09631d 100644 --- a/instrumentation-security/unboundid-ldapsdk/src/main/java/com/unboundid/ldap/sdk/LDAPInterface_Instrumentation.java +++ b/instrumentation-security/unboundid-ldapsdk/src/main/java/com/unboundid/ldap/sdk/LDAPInterface_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.LDAPOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -17,7 +18,7 @@ public class LDAPInterface_Instrumentation { public SearchResult search(final SearchRequest searchRequest) throws LDAPSearchException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(searchRequest.getBaseDN(), searchRequest.getFilter().toString(), LDAPUtils.METHOD_SEARCH); @@ -75,9 +76,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType ldap) { try { - return GenericHelper.acquireLockIfPossible(LDAPUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(ldap, LDAPUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } diff --git a/instrumentation-security/vertx-core-3.3.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/VertxClientHelper.java b/instrumentation-security/vertx-core-3.3.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/VertxClientHelper.java index 53b28229c..4436c41fe 100644 --- a/instrumentation-security/vertx-core-3.3.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/VertxClientHelper.java +++ b/instrumentation-security/vertx-core-3.3.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/VertxClientHelper.java @@ -1,6 +1,7 @@ package com.newrelic.agent.security.instrumentation.vertx; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; public class VertxClientHelper { public static final String NR_SEC_CUSTOM_ATTRIB_NAME = "VERTX_CORE_OPERATION_LOCK-"; @@ -14,7 +15,7 @@ public static void releaseLock() { GenericHelper.releaseLock(getNrSecCustomAttribName()); } - public static boolean acquireLockIfPossible() { - return GenericHelper.acquireLockIfPossible(getNrSecCustomAttribName()); + public static boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, getNrSecCustomAttribName()); } } diff --git a/instrumentation-security/vertx-core-3.3.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java b/instrumentation-security/vertx-core-3.3.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java index 2ca52df71..2e3565615 100644 --- a/instrumentation-security/vertx-core-3.3.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java +++ b/instrumentation-security/vertx-core-3.3.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -23,7 +24,7 @@ public abstract class HttpClientRequestImpl_Instrumentation { private String hostHeader() { return Weaver.callOriginal();} public void end(Buffer chunk) { - boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(); + boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { String uri = getAbsoluteUri(ssl, hostHeader(), uri()); @@ -41,7 +42,7 @@ public void end(Buffer chunk) { } public void end() { - boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(); + boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { String uri = getAbsoluteUri(ssl, hostHeader(), uri()); diff --git a/instrumentation-security/vertx-core-3.4.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/VertxClientHelper.java b/instrumentation-security/vertx-core-3.4.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/VertxClientHelper.java index e6efeac10..689089a31 100644 --- a/instrumentation-security/vertx-core-3.4.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/VertxClientHelper.java +++ b/instrumentation-security/vertx-core-3.4.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/VertxClientHelper.java @@ -1,6 +1,7 @@ package com.newrelic.agent.security.instrumentation.vertx; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; public class VertxClientHelper { public static final String NR_SEC_CUSTOM_ATTRIB_NAME = "VERTX_CORE_OPERATION_LOCK-"; @@ -15,7 +16,7 @@ public static void releaseLock() { GenericHelper.releaseLock(getNrSecCustomAttribName()); } - public static boolean acquireLockIfPossible() { - return GenericHelper.acquireLockIfPossible(getNrSecCustomAttribName()); + public static boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, getNrSecCustomAttribName()); } } diff --git a/instrumentation-security/vertx-core-3.4.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java b/instrumentation-security/vertx-core-3.4.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java index d40dd472c..bc671b229 100644 --- a/instrumentation-security/vertx-core-3.4.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java +++ b/instrumentation-security/vertx-core-3.4.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -27,7 +28,7 @@ public abstract class HttpClientRequestImpl_Instrumentation { } public void end(Buffer chunk) { - boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(); + boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(absoluteURI(), this.getClass().getName(), VertxClientHelper.METHOD_END); @@ -44,7 +45,7 @@ public void end(Buffer chunk) { } public void end() { - boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(); + boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(absoluteURI(), this.getClass().getName(), VertxClientHelper.METHOD_END); diff --git a/instrumentation-security/vertx-core-3.7.1/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java b/instrumentation-security/vertx-core-3.7.1/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java index afdbc3b3c..2b2b75db3 100644 --- a/instrumentation-security/vertx-core-3.7.1/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java +++ b/instrumentation-security/vertx-core-3.7.1/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java @@ -10,6 +10,7 @@ import com.newrelic.agent.security.instrumentation.vertx.web.VertxClientHelper; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; import io.vertx.core.AsyncResult; @@ -26,7 +27,7 @@ public abstract class HttpClientRequestImpl_Instrumentation { public abstract String absoluteURI(); public void end(Buffer chunk) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = VertxClientHelper.preprocessSecurityHook(absoluteURI(), this.getClass().getName(), @@ -45,7 +46,7 @@ public void end(Buffer chunk) { public void end(Buffer chunk, Handler> handler) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = VertxClientHelper.preprocessSecurityHook(absoluteURI(), this.getClass().getName(), @@ -64,7 +65,7 @@ public void end(Buffer chunk, Handler> handler) { public void end() { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = VertxClientHelper.preprocessSecurityHook(absoluteURI(), this.getClass().getName(), @@ -83,7 +84,7 @@ public void end() { public void end(Handler> handler) { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = VertxClientHelper.preprocessSecurityHook(absoluteURI(), this.getClass().getName(), @@ -103,7 +104,7 @@ private void releaseLock() { GenericHelper.releaseLock(VertxClientHelper.getNrSecCustomAttribName()); } - private boolean acquireLockIfPossible() { - return GenericHelper.acquireLockIfPossible(VertxClientHelper.getNrSecCustomAttribName()); + private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, VertxClientHelper.getNrSecCustomAttribName()); } } diff --git a/instrumentation-security/vertx-core-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/web/VertxClientHelper.java b/instrumentation-security/vertx-core-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/web/VertxClientHelper.java index 69bc6787e..8ead6362e 100644 --- a/instrumentation-security/vertx-core-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/web/VertxClientHelper.java +++ b/instrumentation-security/vertx-core-4.0.0/src/main/java/com/newrelic/agent/security/instrumentation/vertx/web/VertxClientHelper.java @@ -1,6 +1,7 @@ package com.newrelic.agent.security.instrumentation.vertx.web; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; public class VertxClientHelper { @@ -17,7 +18,7 @@ public static void releaseLock() { GenericHelper.releaseLock(getNrSecCustomAttribName()); } - public static boolean acquireLockIfPossible() { - return GenericHelper.acquireLockIfPossible(getNrSecCustomAttribName()); + public static boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { + return GenericHelper.acquireLockIfPossible(httpRequest, getNrSecCustomAttribName()); } } diff --git a/instrumentation-security/vertx-core-4.0.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java b/instrumentation-security/vertx-core-4.0.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java index 21c3f7f25..8c64cf881 100644 --- a/instrumentation-security/vertx-core-4.0.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java +++ b/instrumentation-security/vertx-core-4.0.0/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl_Instrumentation.java @@ -13,6 +13,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.SSRFOperation; import com.newrelic.api.agent.security.utils.SSRFUtils; @@ -35,7 +36,7 @@ public abstract class HttpClientRequestImpl_Instrumentation { public Future end(Buffer chunk) { Future result; - boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(); + boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(absoluteURI(), this.getClass().getName(), VertxClientHelper.METHOD_END); @@ -53,7 +54,7 @@ public Future end(Buffer chunk) { } public void end(Buffer chunk, Handler> handler) { - boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(); + boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(absoluteURI(), this.getClass().getName(), VertxClientHelper.METHOD_END); @@ -71,7 +72,7 @@ public void end(Buffer chunk, Handler> handler) { public void end(Handler> handler){ - boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(); + boolean isLockAcquired = VertxClientHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(absoluteURI(), this.getClass().getName(), diff --git a/instrumentation-security/xalan-xpath/src/main/java/org/apache/xpath/XPath_Instrumentation.java b/instrumentation-security/xalan-xpath/src/main/java/org/apache/xpath/XPath_Instrumentation.java index 17dd55fbc..7250b91c6 100644 --- a/instrumentation-security/xalan-xpath/src/main/java/org/apache/xpath/XPath_Instrumentation.java +++ b/instrumentation-security/xalan-xpath/src/main/java/org/apache/xpath/XPath_Instrumentation.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; import com.newrelic.api.agent.security.schema.StringUtils; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.XPathOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -23,7 +24,7 @@ public abstract class XPath_Instrumentation { abstract public String getPatternString(); public XObject execute(XPathContext var1, Node var2, PrefixResolver var3) throws TransformerException { - boolean isLockAcquired = acquireLockIfPossible(); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.XPATH); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(getPatternString(), XPATHUtils.METHOD_EXECUTE); @@ -82,9 +83,9 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible() { + private boolean acquireLockIfPossible(VulnerabilityCaseType xpath) { try { - return GenericHelper.acquireLockIfPossible(XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); + return GenericHelper.acquireLockIfPossible(xpath, XPATHUtils.NR_SEC_CUSTOM_ATTRIB_NAME); } catch (Throwable ignored) {} return false; } From f7240dcadba4d424708e11599c96052b34f42616 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Wed, 14 Aug 2024 10:56:25 +0530 Subject: [PATCH 10/44] Update gradle.properties to use 1.2.6 as json version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 8e99a4eca..9cf70671d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # The agent version. -agentVersion=1.4.0 -jsonVersion=1.2.3 +agentVersion=1.4.1 +jsonVersion=1.2.6 # Updated exposed NR APM API version. nrAPIVersion=8.12.0 From eddc24c79ed38dfc107d1fd2568a9197c1c90c41 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 15 Aug 2024 16:41:32 +0530 Subject: [PATCH 11/44] fix for delay in start fix for event being generated for HTTP request and SYSTEM COMMAND --- .../newrelic/api/agent/security/Agent.java | 9 ++++++--- .../schema/policy/IastDetectionCategory.java | 20 +++++++++---------- 2 files changed, 16 insertions(+), 13 deletions(-) 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 3c93eb2df..f06d3fc40 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 @@ -10,6 +10,7 @@ import com.newrelic.agent.security.intcodeagent.constants.AgentServices; import com.newrelic.agent.security.intcodeagent.constants.HttpStatusCodes; import com.newrelic.agent.security.intcodeagent.controlcommand.ControlCommandProcessor; +import com.newrelic.agent.security.intcodeagent.controlcommand.ControlCommandProcessorThreadPool; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.agent.security.intcodeagent.filelogging.LogFileHelper; import com.newrelic.agent.security.intcodeagent.models.collectorconfig.AgentMode; @@ -145,7 +146,7 @@ private void triggerNrSecurity() { LogLevel.INFO, "[STEP-3] => Gathering information about the application", this.getClass().getName()); - logger.logInit(LogLevel.INFO, NewRelic.getAgent().getConfig().getValue(LowSeverityHelper.LOW_SEVERITY_HOOKS_ENABLED, LowSeverityHelper.DEFAULT)? + logger.logInit(LogLevel.INFO, !config.getAgentMode().getSkipScan().getIastDetectionCategory().getInsecureSettingsEnabled()? "Low priority instrumentations are enabled.":"Low priority instrumentations are disabled!", this.getClass().getName()); if( NewRelic.getAgent().getConfig().getValue(IUtilConstants.NR_SECURITY_HOME_APP, false) ) { logger.logInit(LogLevel.INFO, "App being scanned is a Newrelic's Home Grown application", this.getClass().getName()); @@ -256,6 +257,7 @@ public boolean refreshState(java.net.URL agentJarURL, Instrumentation instrument this.instrumentation = instrumentation; if (isInitialised()) { config.setNRSecurityEnabled(false); + AgentInfo.getInstance().setAgentActive(false); cancelActiveServiceTasks(); } initialise(); @@ -266,14 +268,15 @@ public boolean refreshState(java.net.URL agentJarURL, Instrumentation instrument private void cancelActiveServiceTasks() { /** - * Drain the pools (RestClient, EventSend, Dispatcher) before websocket close * Websocket * policy * HealthCheck */ WSClient.shutDownWSClientAbnormal(false); HealthCheckScheduleThread.getInstance().cancelTask(true); + WSReconnectionST.cancelTask(true); FileCleaner.cancelTask(); + ControlCommandProcessorThreadPool.shutDownPool(); } @@ -776,7 +779,7 @@ public Instrumentation getInstrumentation() { @Override public boolean isLowPriorityInstrumentationEnabled() { - return NewRelicSecurity.isHookProcessingActive() && NewRelic.getAgent().getConfig().getValue(LowSeverityHelper.LOW_SEVERITY_HOOKS_ENABLED, LowSeverityHelper.DEFAULT); + return NewRelicSecurity.isHookProcessingActive() && !config.getAgentMode().getSkipScan().getIastDetectionCategory().getInsecureSettingsEnabled(); } public void setApplicationConnectionConfig(int port, String scheme) { diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java index 46933e1b0..c555dda1d 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java @@ -5,16 +5,16 @@ public class IastDetectionCategory { public static final String STR_COMMA = ","; - Boolean sqlInjectionEnabled = true; - Boolean insecureSettingsEnabled = true; - Boolean invalidFileAccessEnabled = true; - Boolean noSqlInjectionEnabled = true; - Boolean rxssEnabled = true; - Boolean commandInjectionEnabled = true; - Boolean ldapInjectionEnabled = true; - Boolean javascriptInjectionEnabled = true; - Boolean xpathInjectionEnabled = true; - Boolean ssrfEnabled = true; + Boolean sqlInjectionEnabled = false; + Boolean insecureSettingsEnabled = false; + Boolean invalidFileAccessEnabled = false; + Boolean noSqlInjectionEnabled = false; + Boolean rxssEnabled = false; + Boolean commandInjectionEnabled = false; + Boolean ldapInjectionEnabled = false; + Boolean javascriptInjectionEnabled = false; + Boolean xpathInjectionEnabled = false; + Boolean ssrfEnabled = false; private String disabledCategoriesCSV; From 16cbfb2a636c46df97dd9b1189800462e202fad8 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 15 Aug 2024 16:44:36 +0530 Subject: [PATCH 12/44] fix for event being generated for HTTP request and SYSTEM COMMAND --- .../lang/ProcessImpl_Instrumentation.java | 15 ++++- .../javax/naming/Context_Instrumentation.java | 16 ++--- .../instrumentation/urlconnection/Helper.java | 1 + .../URLConnection_Instrumentation.java | 64 +++++++++++-------- 4 files changed, 59 insertions(+), 37 deletions(-) diff --git a/instrumentation-security/java-lang/src/main/java/java/lang/ProcessImpl_Instrumentation.java b/instrumentation-security/java-lang/src/main/java/java/lang/ProcessImpl_Instrumentation.java index c8d193236..57029faad 100644 --- a/instrumentation-security/java-lang/src/main/java/java/lang/ProcessImpl_Instrumentation.java +++ b/instrumentation-security/java-lang/src/main/java/java/lang/ProcessImpl_Instrumentation.java @@ -3,6 +3,7 @@ import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.ForkExecOperation; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -22,8 +23,18 @@ static Process start(String[] cmdarray, ProcessBuilder.Redirect[] redirects, boolean redirectErrorStream) throws IOException { Process p = null; - AbstractOperation operation = preprocessSecurityHook(cmdarray, environment); - p = Weaver.callOriginal(); + boolean isLockAcquired = GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.SYSTEM_COMMAND, "SYSTEM_COMMAND_"); + AbstractOperation operation = null; + if(isLockAcquired) { + operation = preprocessSecurityHook(cmdarray, environment); + } + try { + p = Weaver.callOriginal(); + } finally { + if(isLockAcquired){ + GenericHelper.releaseLock("SYSTEM_COMMAND_"); + } + } registerExitOperation(operation); return p; } diff --git a/instrumentation-security/javax-jndi/src/main/java/javax/naming/Context_Instrumentation.java b/instrumentation-security/javax-jndi/src/main/java/javax/naming/Context_Instrumentation.java index ded02cd36..63c9611c3 100644 --- a/instrumentation-security/javax-jndi/src/main/java/javax/naming/Context_Instrumentation.java +++ b/instrumentation-security/javax-jndi/src/main/java/javax/naming/Context_Instrumentation.java @@ -19,7 +19,7 @@ public abstract class Context_Instrumentation { public Object lookup(Name name) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); List operations = null; if(isLockAcquired) { operations = preprocessSecurityHook(name.getAll(), JNDIUtils.METHOD_LOOKUP); @@ -37,7 +37,7 @@ public Object lookup(Name name) throws NamingException { } public Object lookupLink(Name name) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); List operations = null; if(isLockAcquired) { operations = preprocessSecurityHook(name.getAll(), JNDIUtils.METHOD_LOOKUP); @@ -55,7 +55,7 @@ public Object lookupLink(Name name) throws NamingException { } public Object lookup(String name) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(name, JNDIUtils.METHOD_LOOKUP); @@ -73,7 +73,7 @@ public Object lookup(String name) throws NamingException { } public Object lookupLink(String name) throws NamingException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.LDAP); + boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(name, JNDIUtils.METHOD_LOOKUP); @@ -100,8 +100,8 @@ private void registerExitOperation(boolean isLockAcquired, List Date: Thu, 15 Aug 2024 16:53:06 +0530 Subject: [PATCH 13/44] fix shutting of agent after a certain duration --- .../intcodeagent/controlcommand/ControlCommandProcessor.java | 2 +- .../src/main/java/com/newrelic/api/agent/security/Agent.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 e280ccc2e..7bfdaa16f 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 @@ -69,7 +69,7 @@ public class ControlCommandProcessor implements Runnable { private long receiveTimestamp; - private static Instant iastReplayRequestMsgReceiveTime; + private static Instant iastReplayRequestMsgReceiveTime = Instant.now(); private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); 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 f06d3fc40..fd09dd7d5 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 @@ -182,7 +182,7 @@ private void IastShutdown() { if(ControlCommandProcessor.getIastReplayRequestMsgReceiveTime().isBefore(Instant.now().minus(5, ChronoUnit.MINUTES))){ logger.log(LogLevel.WARNING, "IAST scan is still in progress, may have undetected vulnerabilities. Please increase scan duration and restart application.", Agent.class.getName()); } - logger.log(LogLevel.FINER, "Scan duration completed, IAST Scan shutting down.", Agent.class.getName()); + logger.log(LogLevel.INFO, "Scan duration completed, IAST Scan shutting down.", Agent.class.getName()); InstrumentationUtils.shutdownLogic(); } From 9d2f10f4c591efa8d5189e8e0bd1677193459d1b Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 15 Aug 2024 17:15:28 +0530 Subject: [PATCH 14/44] Disable agent on incorrect config --- .../newrelic/agent/security/AgentConfig.java | 72 ++++++++++--------- .../newrelic/api/agent/security/Agent.java | 21 +++--- 2 files changed, 53 insertions(+), 40 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index 083ebed70..d69bd5fbe 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -134,50 +134,58 @@ private void instantiateAgentMode(String groupName) { try { readScanSchedule(); + readSkipScan(); } catch (RestrictionModeException e){ - System.err.println("[NR-CSEC-JA] Error while reading Scan Schedule Configuration. Security will be disabled."); - NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading Scan Schedule Configuration. Security will be disabled."); + System.err.println("[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled."); + NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled. Message :{}", e.getMessage()); NewRelic.noticeError(e, Agent.getCustomNoticeErrorParameters(), true); AgentInfo.getInstance().agentStatTrigger(false); } - readSkipScan(); } - private void readSkipScan() { - agentMode.getSkipScan().setApis(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_API, Collections.emptyList())); - agentMode.getSkipScan().getParameters().setQuery(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_QUERY, Collections.emptyList())); - agentMode.getSkipScan().getParameters().setHeader(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_HEADER, Collections.emptyList())); - agentMode.getSkipScan().getParameters().setBody(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_BODY, Collections.emptyList())); - agentMode.getSkipScan().getIastDetectionCategory().setInsecureSettingsEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INSECURE_SETTINGS, true)); - agentMode.getSkipScan().getIastDetectionCategory().setInvalidFileAccessEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INVALID_FILE_ACCESS, true)); - agentMode.getSkipScan().getIastDetectionCategory().setSqlInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_SQL_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setNoSqlInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_NOSQL_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setLdapInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_LDAP_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setJavascriptInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_JAVASCRIPT_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setCommandInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_COMMAND_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setXpathInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_XPATH_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setSsrfEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_SSRF, true)); - agentMode.getSkipScan().getIastDetectionCategory().setRxssEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_RXSS, true)); - agentMode.getSkipScan().getIastDetectionCategory().generateDisabledCategoriesCSV(); + private void readSkipScan() throws RestrictionModeException { + try { + agentMode.getSkipScan().setApis(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_API, Collections.emptyList())); + agentMode.getSkipScan().getParameters().setQuery(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_QUERY, Collections.emptyList())); + agentMode.getSkipScan().getParameters().setHeader(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_HEADER, Collections.emptyList())); + agentMode.getSkipScan().getParameters().setBody(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_BODY, Collections.emptyList())); + agentMode.getSkipScan().getIastDetectionCategory().setInsecureSettingsEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INSECURE_SETTINGS, true)); + agentMode.getSkipScan().getIastDetectionCategory().setInvalidFileAccessEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INVALID_FILE_ACCESS, true)); + agentMode.getSkipScan().getIastDetectionCategory().setSqlInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_SQL_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setNoSqlInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_NOSQL_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setLdapInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_LDAP_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setJavascriptInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_JAVASCRIPT_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setCommandInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_COMMAND_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setXpathInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_XPATH_INJECTION, true)); + agentMode.getSkipScan().getIastDetectionCategory().setSsrfEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_SSRF, true)); + agentMode.getSkipScan().getIastDetectionCategory().setRxssEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_RXSS, true)); + agentMode.getSkipScan().getIastDetectionCategory().generateDisabledCategoriesCSV(); + } catch (ClassCastException | NumberFormatException e){ + throw new RestrictionModeException("Invalid Security Configuration " + e.getMessage(), e); + } } private void readScanSchedule() throws RestrictionModeException { - agentMode.getScanSchedule().setDelay(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_DELAY, 0)); - agentMode.getScanSchedule().setDuration(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_DURATION, 0)); - agentMode.getScanSchedule().setSchedule(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_SCHEDULE, StringUtils.EMPTY)); - if(agentMode.getScanSchedule().getDelay() > 0) { - agentMode.getScanSchedule().setNextScanTime(new Date(Instant.now().toEpochMilli() + TimeUnit.MINUTES.toMillis(agentMode.getScanSchedule().getDelay()))); - } else if(StringUtils.isNotBlank(agentMode.getScanSchedule().getSchedule())) { - if(CronExpression.isValidExpression(agentMode.getScanSchedule().getSchedule())){ - try { - agentMode.getScanSchedule().setNextScanTime(new CronExpression(agentMode.getScanSchedule().getSchedule()).getTimeAfter(new Date())); - } catch (ParseException e) { - throw new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE, e); + try { + agentMode.getScanSchedule().setDelay(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_DELAY, 0)); + agentMode.getScanSchedule().setDuration(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_DURATION, 0)); + agentMode.getScanSchedule().setSchedule(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_SCHEDULE, StringUtils.EMPTY)); + if (agentMode.getScanSchedule().getDelay() > 0) { + agentMode.getScanSchedule().setNextScanTime(new Date(Instant.now().toEpochMilli() + TimeUnit.MINUTES.toMillis(agentMode.getScanSchedule().getDelay()))); + } else if (StringUtils.isNotBlank(agentMode.getScanSchedule().getSchedule())) { + if (CronExpression.isValidExpression(agentMode.getScanSchedule().getSchedule())) { + try { + agentMode.getScanSchedule().setNextScanTime(new CronExpression(agentMode.getScanSchedule().getSchedule()).getTimeAfter(new Date())); + } catch (ParseException e) { + throw new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE, e); + } + } else { + throw new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE); } - } else { - throw new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE); } + } catch (ClassCastException | NumberFormatException e){ + throw new RestrictionModeException("Invalid Security Configuration " + e.getMessage(), e); } } 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 5344ab97d..be08c945e 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 @@ -251,15 +251,20 @@ public boolean refreshState(java.net.URL agentJarURL, Instrumentation instrument /** * restart k2 services **/ - this.agentJarURL = agentJarURL; - this.instrumentation = instrumentation; - if (isInitialised()) { - config.setNRSecurityEnabled(false); - AgentInfo.getInstance().setAgentActive(false); - cancelActiveServiceTasks(); + try { + this.agentJarURL = agentJarURL; + this.instrumentation = instrumentation; + if (isInitialised()) { + config.setNRSecurityEnabled(false); + AgentInfo.getInstance().setAgentActive(false); + cancelActiveServiceTasks(); + } + initialise(); + NewRelic.getAgent().getLogger().log(Level.INFO, "Security refresh was invoked, Security Agent initiation is successful."); + } catch (Exception e){ + NewRelic.getAgent().getLogger().log(Level.SEVERE, "Newrelic Security Startup failed!!!", e); + NewRelic.noticeError(e, customNoticeErrorParameters, true); } - initialise(); - NewRelic.getAgent().getLogger().log(Level.INFO, "Security refresh was invoked, Security Agent initiation is successful."); return true; } From bb427d78f258ccc378205ff487433ae5487cc83a Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Fri, 16 Aug 2024 15:00:51 +0530 Subject: [PATCH 15/44] Add feature to collect sample in IAST Scan deactivate mode. Fix default values of IAST scan ignore categories Add feature to schedule via cron expression --- .../newrelic/agent/security/AgentConfig.java | 37 +++-- .../IASTDataTransferRequestProcessor.java | 7 +- .../instrumentator/utils/AgentUtils.java | 16 -- .../agent/security/util/IUtilConstants.java | 1 + .../newrelic/api/agent/security/Agent.java | 155 +++++++++++------- .../security/schema/policy/IASTScan.java | 4 + .../schema/policy/IastDetectionCategory.java | 2 + .../security/schema/policy/ScanSchedule.java | 34 ++++ .../security/schema/policy/SkipScan.java | 3 + 9 files changed, 165 insertions(+), 94 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index d69bd5fbe..bd77424a4 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -72,7 +72,7 @@ public long instantiate(){ //Set k2 home path boolean validHomePath = setSecurityHomePath(); if(validHomePath) { - System.out.println("New Relic Security Agent: Setting csec home path to directory: " + NR_CSEC_HOME); + System.out.println("New Relic Security Agent: Setting Security home path to directory: " + NR_CSEC_HOME); } isNRSecurityEnabled = NewRelic.getAgent().getConfig().getValue(IUtilConstants.NR_SECURITY_ENABLED, false); // Set required Group @@ -96,7 +96,8 @@ public long triggerIAST() { try { if(agentMode.getScanSchedule().getNextScanTime() != null) { logger.log(LogLevel.FINER, "Security Agent scan time is set to : " + agentMode.getScanSchedule().getNextScanTime(), AgentConfig.class.getName()); - return agentMode.getScanSchedule().getNextScanTime().getTime() - Instant.now().toEpochMilli(); + long delay = agentMode.getScanSchedule().getNextScanTime().getTime() - Instant.now().toEpochMilli(); + return (delay > 0)? delay : 0; } } catch (Exception e){ NewRelic.noticeError(new RestrictionModeException("Error while calculating next scan time for IAST Restricted Mode", e), Agent.getCustomNoticeErrorParameters(), true); @@ -141,7 +142,7 @@ private void instantiateAgentMode(String groupName) { NewRelic.noticeError(e, Agent.getCustomNoticeErrorParameters(), true); AgentInfo.getInstance().agentStatTrigger(false); } - + logger.log(LogLevel.INFO, String.format("Security Agent Modes and Config : %s", agentMode), AgentConfig.class.getName()); } private void readSkipScan() throws RestrictionModeException { @@ -150,16 +151,16 @@ private void readSkipScan() throws RestrictionModeException { agentMode.getSkipScan().getParameters().setQuery(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_QUERY, Collections.emptyList())); agentMode.getSkipScan().getParameters().setHeader(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_HEADER, Collections.emptyList())); agentMode.getSkipScan().getParameters().setBody(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_BODY, Collections.emptyList())); - agentMode.getSkipScan().getIastDetectionCategory().setInsecureSettingsEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INSECURE_SETTINGS, true)); - agentMode.getSkipScan().getIastDetectionCategory().setInvalidFileAccessEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INVALID_FILE_ACCESS, true)); - agentMode.getSkipScan().getIastDetectionCategory().setSqlInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_SQL_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setNoSqlInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_NOSQL_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setLdapInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_LDAP_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setJavascriptInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_JAVASCRIPT_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setCommandInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_COMMAND_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setXpathInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_XPATH_INJECTION, true)); - agentMode.getSkipScan().getIastDetectionCategory().setSsrfEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_SSRF, true)); - agentMode.getSkipScan().getIastDetectionCategory().setRxssEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_RXSS, true)); + agentMode.getSkipScan().getIastDetectionCategory().setInsecureSettingsEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INSECURE_SETTINGS, false)); + agentMode.getSkipScan().getIastDetectionCategory().setInvalidFileAccessEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INVALID_FILE_ACCESS, false)); + agentMode.getSkipScan().getIastDetectionCategory().setSqlInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_SQL_INJECTION, false)); + agentMode.getSkipScan().getIastDetectionCategory().setNoSqlInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_NOSQL_INJECTION, false)); + agentMode.getSkipScan().getIastDetectionCategory().setLdapInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_LDAP_INJECTION, false)); + agentMode.getSkipScan().getIastDetectionCategory().setJavascriptInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_JAVASCRIPT_INJECTION, false)); + agentMode.getSkipScan().getIastDetectionCategory().setCommandInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_COMMAND_INJECTION, false)); + agentMode.getSkipScan().getIastDetectionCategory().setXpathInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_XPATH_INJECTION, false)); + agentMode.getSkipScan().getIastDetectionCategory().setSsrfEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_SSRF, false)); + agentMode.getSkipScan().getIastDetectionCategory().setRxssEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_RXSS, false)); agentMode.getSkipScan().getIastDetectionCategory().generateDisabledCategoriesCSV(); } catch (ClassCastException | NumberFormatException e){ throw new RestrictionModeException("Invalid Security Configuration " + e.getMessage(), e); @@ -171,9 +172,11 @@ private void readScanSchedule() throws RestrictionModeException { agentMode.getScanSchedule().setDelay(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_DELAY, 0)); agentMode.getScanSchedule().setDuration(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_DURATION, 0)); agentMode.getScanSchedule().setSchedule(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_SCHEDULE, StringUtils.EMPTY)); + agentMode.getScanSchedule().setCollectSamples(NewRelic.getAgent().getConfig().getValue(SCAN_TIME_COLLECT_SAMPLES, false)); if (agentMode.getScanSchedule().getDelay() > 0) { agentMode.getScanSchedule().setNextScanTime(new Date(Instant.now().toEpochMilli() + TimeUnit.MINUTES.toMillis(agentMode.getScanSchedule().getDelay()))); } else if (StringUtils.isNotBlank(agentMode.getScanSchedule().getSchedule())) { + agentMode.getScanSchedule().setScheduleOnce(false); if (CronExpression.isValidExpression(agentMode.getScanSchedule().getSchedule())) { try { agentMode.getScanSchedule().setNextScanTime(new CronExpression(agentMode.getScanSchedule().getSchedule()).getTimeAfter(new Date())); @@ -184,6 +187,10 @@ private void readScanSchedule() throws RestrictionModeException { throw new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE); } } + agentMode.getScanSchedule().setDataCollectionTime(agentMode.getScanSchedule().getNextScanTime()); + if(agentMode.getScanSchedule().isCollectSamples()){ + agentMode.getScanSchedule().setNextScanTime(new Date(Instant.now().toEpochMilli())); + } } catch (ClassCastException | NumberFormatException e){ throw new RestrictionModeException("Invalid Security Configuration " + e.getMessage(), e); } @@ -393,10 +400,6 @@ public boolean isNRSecurityEnabled() { return isNRSecurityEnabled; } - public void setNRSecurityEnabled(boolean NRSecurityEnabled) { - isNRSecurityEnabled = NRSecurityEnabled; - } - public String getSecurityHome() { return NR_CSEC_HOME; } 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 c4c732798..c73a1cbf0 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 @@ -156,7 +156,12 @@ public static IASTDataTransferRequestProcessor getInstance() { public void startDataRequestSchedule(long delay, TimeUnit timeUnit){ try { stopDataRequestSchedule(true); - future = executorService.scheduleWithFixedDelay(this::task, 0, delay, timeUnit); + long initialDelay = AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime().toInstant().getEpochSecond() - Instant.now().getEpochSecond(); + if(initialDelay < 0){ + initialDelay = 0; + } + logger.log(LogLevel.INFO, String.format("IAST data pull request is scheduled at %s", AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime()), IASTDataTransferRequestProcessor.class.getName()); + future = executorService.scheduleWithFixedDelay(this::task, initialDelay, delay, timeUnit); } catch (Throwable ignored){} } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/AgentUtils.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/AgentUtils.java index da5c72381..89f16a195 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/AgentUtils.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/AgentUtils.java @@ -427,22 +427,6 @@ public static boolean applyPolicy(AgentPolicy newPolicy) { AgentUtils.getInstance().getStatusLogValues().put(POLICY_VERSION, AgentUtils.getInstance().getAgentPolicy().getVersion()); EventSendPool.getInstance().sendEvent(AgentInfo.getInstance().getApplicationInfo()); - // Start IAST data pull if policy allows - if (NewRelicSecurity.getAgent().getCurrentPolicy().getVulnerabilityScan().getEnabled() && - NewRelicSecurity.getAgent().getCurrentPolicy().getVulnerabilityScan().getIastScan().getEnabled() - ) { - IASTDataTransferRequestProcessor.getInstance().startDataRequestSchedule( - NewRelicSecurity.getAgent().getCurrentPolicy() - .getVulnerabilityScan().getIastScan().getProbing().getInterval(), TimeUnit.SECONDS); - logger.logInit( - LogLevel.INFO, - String.format(STARTED_MODULE_LOG, AgentServices.IASTDataPullService.name()), - Agent.class.getName() - ); - } else { - IASTDataTransferRequestProcessor.getInstance().stopDataRequestSchedule(true); - } - return true; } catch (Throwable e) { logger.logInit(LogLevel.SEVERE, IAgentConstants.UNABLE_TO_SET_AGENT_POLICY_DUE_TO_ERROR, e, diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java index babebd221..80850f016 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java @@ -11,6 +11,7 @@ public interface IUtilConstants { String SCAN_TIME_DELAY = "security.scan_schedule.delay"; String SCAN_TIME_SCHEDULE = "security.scan_schedule.schedule"; String SCAN_TIME_DURATION = "security.scan_schedule.duration"; + String SCAN_TIME_COLLECT_SAMPLES = "security.scan_schedule.allow_iast_sample_collection"; String SKIP_IAST_SCAN = "security.skip_iast_scan"; String SKIP_IAST_SCAN_API = SKIP_IAST_SCAN + ".api"; 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 be08c945e..fbf5df4a1 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,20 +4,19 @@ 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.httpclient.IASTDataTransferRequestProcessor; import com.newrelic.agent.security.instrumentator.os.OsVariablesInstance; import com.newrelic.agent.security.instrumentator.utils.*; import com.newrelic.agent.security.intcodeagent.constants.AgentServices; import com.newrelic.agent.security.intcodeagent.constants.HttpStatusCodes; import com.newrelic.agent.security.intcodeagent.controlcommand.ControlCommandProcessor; import com.newrelic.agent.security.intcodeagent.controlcommand.ControlCommandProcessorThreadPool; +import com.newrelic.agent.security.intcodeagent.exceptions.RestrictionModeException; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.agent.security.intcodeagent.filelogging.LogFileHelper; import com.newrelic.agent.security.intcodeagent.models.collectorconfig.AgentMode; import com.newrelic.agent.security.intcodeagent.models.javaagent.*; -import com.newrelic.agent.security.intcodeagent.utils.EncryptorUtils; -import com.newrelic.agent.security.intcodeagent.utils.RestrictionUtility; -import com.newrelic.agent.security.intcodeagent.utils.RuntimeErrorReporter; +import com.newrelic.agent.security.intcodeagent.utils.*; import com.newrelic.api.agent.security.instrumentation.helpers.*; import com.newrelic.api.agent.security.schema.operation.SecureCookieOperationSet; import com.newrelic.api.agent.security.schema.policy.IastDetectionCategory; @@ -27,7 +26,6 @@ import com.newrelic.agent.security.intcodeagent.properties.BuildInfo; import com.newrelic.agent.security.intcodeagent.schedulers.FileCleaner; import com.newrelic.agent.security.intcodeagent.schedulers.SchedulerHelper; -import com.newrelic.agent.security.intcodeagent.utils.CommonUtils; import com.newrelic.agent.security.intcodeagent.websocket.*; import com.newrelic.agent.security.util.IUtilConstants; import com.newrelic.api.agent.NewRelic; @@ -36,6 +34,7 @@ import com.newrelic.api.agent.security.schema.operation.RXSSOperation; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; import org.apache.commons.lang3.StringUtils; +import org.java_websocket.framing.CloseFrame; import java.io.File; import java.io.IOException; @@ -43,13 +42,10 @@ import java.lang.instrument.UnmodifiableClassException; import java.net.HttpURLConnection; import java.net.URL; +import java.text.ParseException; import java.time.Instant; import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Properties; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -67,6 +63,7 @@ public class Agent implements SecurityAgent { private static final AtomicBoolean firstEventProcessed = new AtomicBoolean(false); public static final String ERROR_WHILE_GENERATING_TRACE_ID_FOR_CATEGORY_S = "Error while generating trace id for category : %s"; public static final String SKIPPING_THE_API_S_AS_IT_IS_PART_OF_THE_SKIP_SCAN_LIST = "Skipping the API %s as it is part of the skip scan list"; + public static final String INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE = "Invalid cron expression provided for IAST Mode"; private AgentInfo info; @@ -127,61 +124,84 @@ private void triggerNrSecurity() { * */ //NOTE: The bellow call sequence is critical and dependent on each other - logger = FileLoggerThreadPool.getInstance(); - logger.logInit( - LogLevel.INFO, - "[STEP-1] => Security agent is starting", - Agent.class.getName()); - logger.logInit( - LogLevel.INFO, - String.format("[STEP-2] => Generating unique identifier: %s", AgentInfo.getInstance().getApplicationUUID()), AgentInfo.class.getName()); - config.setConfig(CollectorConfigurationUtils.populateCollectorConfig()); - - info.setBuildInfo(readCollectorBuildInfo()); - logger.log(LogLevel.INFO, String.format("CSEC Collector build info : %s", info.getBuildInfo()), this.getClass().getName()); - - logger.logInit( - LogLevel.INFO, - "[STEP-3] => Gathering information about the application", - this.getClass().getName()); - logger.logInit(LogLevel.INFO, !config.getAgentMode().getSkipScan().getIastDetectionCategory().getInsecureSettingsEnabled()? - "Low priority instrumentations are enabled.":"Low priority instrumentations are disabled!", this.getClass().getName()); - if( NewRelic.getAgent().getConfig().getValue(IUtilConstants.NR_SECURITY_HOME_APP, false) ) { - logger.logInit(LogLevel.INFO, "App being scanned is a Newrelic's Home Grown application", this.getClass().getName()); + try { + logger = FileLoggerThreadPool.getInstance(); + logger.logInit( + LogLevel.INFO, + "[STEP-1] => Security agent is starting", + Agent.class.getName()); + logger.logInit( + LogLevel.INFO, + String.format("[STEP-2] => Generating unique identifier: %s", AgentInfo.getInstance().getApplicationUUID()), AgentInfo.class.getName()); + config.setConfig(CollectorConfigurationUtils.populateCollectorConfig()); + + info.setBuildInfo(readCollectorBuildInfo()); + logger.log(LogLevel.INFO, String.format("CSEC Collector build info : %s", info.getBuildInfo()), this.getClass().getName()); + + logger.logInit( + LogLevel.INFO, + "[STEP-3] => Gathering information about the application", + this.getClass().getName()); + logger.logInit(LogLevel.INFO, !config.getAgentMode().getSkipScan().getIastDetectionCategory().getInsecureSettingsEnabled() ? + "Low priority instrumentations are enabled." : "Low priority instrumentations are disabled!", this.getClass().getName()); + if (NewRelic.getAgent().getConfig().getValue(IUtilConstants.NR_SECURITY_HOME_APP, false)) { + logger.logInit(LogLevel.INFO, "App being scanned is a Newrelic's Home Grown application", this.getClass().getName()); + } + info.setIdentifier(ApplicationInfoUtils.envDetection()); + ApplicationInfoUtils.continueIdentifierProcessing(info.getIdentifier(), config.getConfig()); + info.generateAppInfo(config.getConfig()); + info.initialiseHC(); + config.populateAgentPolicy(); + config.populateAgentPolicyParameters(); + config.setupSnapshotDir(); + info.initStatusLogValues(); + setInitialised(true); + populateLinkingMetadata(); + populateApplicationTmpDir(); + startSecurityServices(); + info.agentStatTrigger(true); + //Schedule NR csec shutdown if required + scheduleShutdownTrigger(); + } catch (Exception e){ + e.printStackTrace(); } - info.setIdentifier(ApplicationInfoUtils.envDetection()); - ApplicationInfoUtils.continueIdentifierProcessing(info.getIdentifier(), config.getConfig()); - info.generateAppInfo(config.getConfig()); - info.initialiseHC(); - config.populateAgentPolicy(); - config.populateAgentPolicyParameters(); - config.setupSnapshotDir(); - info.initStatusLogValues(); - setInitialised(true); - populateLinkingMetadata(); - populateApplicationTmpDir(); - startSecurityServices(); - info.agentStatTrigger(true); - //Schedule NR csec shutdown if required - scheduleShutdownTrigger(); } private void scheduleShutdownTrigger() { if(AgentConfig.getInstance().getAgentMode().getScanSchedule().getDuration() > 0) { int duration = AgentConfig.getInstance().getAgentMode().getScanSchedule().getDuration(); Instant now = Instant.now(); + if(AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime() != null){ + now = AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime().toInstant(); + } Instant shutdownInstant = now.plus(duration, ChronoUnit.MINUTES); - long shutdownTime = shutdownInstant.getEpochSecond() - now.getEpochSecond(); - SchedulerHelper.getInstance().scheduleIastTrigger(this::IastShutdown, shutdownTime, TimeUnit.SECONDS); + long shutdownTime = shutdownInstant.getEpochSecond() - Instant.now().getEpochSecond(); + SchedulerHelper.getInstance().scheduleIastTrigger(this::IastDeactivate, shutdownTime, TimeUnit.SECONDS); } } - private void IastShutdown() { - if(ControlCommandProcessor.getIastReplayRequestMsgReceiveTime().isBefore(Instant.now().minus(5, ChronoUnit.MINUTES))){ + private void IastDeactivate() { + if(ControlCommandProcessor.getIastReplayRequestMsgReceiveTime().isAfter(Instant.now().minus(5, ChronoUnit.MINUTES))){ logger.log(LogLevel.WARNING, "IAST scan is still in progress, may have undetected vulnerabilities. Please increase scan duration and restart application.", Agent.class.getName()); } - logger.log(LogLevel.INFO, "Scan duration completed, IAST Scan shutting down.", Agent.class.getName()); - InstrumentationUtils.shutdownLogic(); + logger.log(LogLevel.INFO, "Scan duration completed, IAST going under hibernate mode.", Agent.class.getName()); + deactivateSecurity(); + if(!config.getAgentMode().getScanSchedule().isScheduleOnce()){ + try { + config.getAgentMode().getScanSchedule().setNextScanTime(new CronExpression(config.getAgentMode().getScanSchedule().getSchedule()).getTimeAfter(new Date())); + config.getAgentMode().getScanSchedule().setDataCollectionTime(config.getAgentMode().getScanSchedule().getNextScanTime()); + if(config.getAgentMode().getScanSchedule().isCollectSamples()){ + config.getAgentMode().getScanSchedule().setNextScanTime(new Date(Instant.now().toEpochMilli())); + } + long delay = config.triggerIAST(); + SchedulerHelper.getInstance().scheduleIastTrigger(this::triggerNrSecurity, delay, TimeUnit.MILLISECONDS); + } catch (ParseException e) { + System.err.println("[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled."); + NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled. Message :{}", e.getMessage()); + NewRelic.noticeError(new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE, e), Agent.getCustomNoticeErrorParameters(), true); + AgentInfo.getInstance().agentStatTrigger(false); + } + } } private void IastRestrictedShutdown() { @@ -238,6 +258,18 @@ private void startSecurityServices() { Agent.class.getName() ); logger.logInit(LogLevel.INFO, AGENT_INIT_LOG_STEP_FIVE_END, Agent.class.getName()); + // Start IAST data pull if policy allows + if (config.getAgentMode().getIastScan().getEnabled()) { + IASTDataTransferRequestProcessor.getInstance().startDataRequestSchedule( + config.getAgentMode().getIastScan().getProbing().getInterval(), TimeUnit.SECONDS); + logger.logInit( + LogLevel.INFO, + String.format(STARTED_MODULE_LOG, AgentServices.IASTDataPullService.name()), + Agent.class.getName() + ); + } else { + IASTDataTransferRequestProcessor.getInstance().stopDataRequestSchedule(true); + } } @@ -255,7 +287,6 @@ public boolean refreshState(java.net.URL agentJarURL, Instrumentation instrument this.agentJarURL = agentJarURL; this.instrumentation = instrumentation; if (isInitialised()) { - config.setNRSecurityEnabled(false); AgentInfo.getInstance().setAgentActive(false); cancelActiveServiceTasks(); } @@ -286,7 +317,6 @@ private void cancelActiveServiceTasks() { @Override public boolean deactivateSecurity() { if(isInitialised()) { - config.setNRSecurityEnabled(false); deactivateSecurityServices(); } return true; @@ -300,12 +330,17 @@ private void deactivateSecurityServices(){ * 3. event pool * 4. HealthCheck **/ - InstrumentationUtils.shutdownLogic(); - HealthCheckScheduleThread.getInstance().cancelTask(true); - FileCleaner.cancelTask(); - WSClient.shutDownWSClientAbnormal(true); - WSReconnectionST.shutDownPool(); - EventSendPool.shutDownPool(); +// InstrumentationUtils.shutdownLogic(); + IASTDataTransferRequestProcessor.getInstance().stopDataRequestSchedule(true); + if(!config.getAgentMode().getScanSchedule().isCollectSamples()) { + AgentInfo.getInstance().setAgentActive(false); + HealthCheckScheduleThread.getInstance().cancelTask(true); + FileCleaner.cancelTask(); + WSReconnectionST.cancelTask(true); + WSClient.shutDownWSClient(true, CloseFrame.NORMAL, "Deactivating Security Agent"); + } + + } @Override diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java index d5259effb..cadba8ae5 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java @@ -1,11 +1,15 @@ package com.newrelic.api.agent.security.schema.policy; +import com.newrelic.api.agent.security.schema.annotations.JsonIgnore; + public class IASTScan { private Boolean enabled = true; private Probing probing = new Probing(); + @JsonIgnore private Boolean restricted = false; + @JsonIgnore private RestrictionCriteria restrictionCriteria = new RestrictionCriteria(); /** diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java index c555dda1d..25d0439d4 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IastDetectionCategory.java @@ -1,6 +1,7 @@ package com.newrelic.api.agent.security.schema.policy; import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; +import com.newrelic.api.agent.security.schema.annotations.JsonIgnore; public class IastDetectionCategory { @@ -16,6 +17,7 @@ public class IastDetectionCategory { Boolean xpathInjectionEnabled = false; Boolean ssrfEnabled = false; + @JsonIgnore private String disabledCategoriesCSV; public IastDetectionCategory() { diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanSchedule.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanSchedule.java index 75084afb0..22cf5732d 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanSchedule.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/ScanSchedule.java @@ -1,5 +1,7 @@ package com.newrelic.api.agent.security.schema.policy; +import com.newrelic.api.agent.security.schema.annotations.JsonIgnore; + import java.util.Date; public class ScanSchedule { @@ -12,6 +14,14 @@ public class ScanSchedule { private int delay = 0; + private boolean collectSamples = false; + + @JsonIgnore + private Date dataCollectionTime; + + @JsonIgnore + private boolean scheduleOnce = true; + public ScanSchedule() { } @@ -46,4 +56,28 @@ public int getDelay() { public void setDelay(int delay) { this.delay = delay; } + + public boolean isCollectSamples() { + return collectSamples; + } + + public void setCollectSamples(boolean collectSamples) { + this.collectSamples = collectSamples; + } + + public Date getDataCollectionTime() { + return dataCollectionTime; + } + + public void setDataCollectionTime(Date dataCollectionTime) { + this.dataCollectionTime = dataCollectionTime; + } + + public boolean isScheduleOnce() { + return scheduleOnce; + } + + public void setScheduleOnce(boolean scheduleOnce) { + this.scheduleOnce = scheduleOnce; + } } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScan.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScan.java index 042f28366..b89eed6b4 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScan.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/SkipScan.java @@ -1,5 +1,7 @@ package com.newrelic.api.agent.security.schema.policy; +import com.newrelic.api.agent.security.schema.annotations.JsonIgnore; + import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; @@ -7,6 +9,7 @@ public class SkipScan { private List apis = new ArrayList<>(); + @JsonIgnore private List apiRoutes = new ArrayList<>(); private SkipScanParameters parameters = new SkipScanParameters(); From d29056c21eace6fa6e2771e3d7991e22e9e89c44 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Fri, 16 Aug 2024 17:02:44 +0530 Subject: [PATCH 16/44] Null checks for NextScanTime and fir for nr logging IAE. --- .../java/com/newrelic/agent/security/AgentConfig.java | 2 +- .../httpclient/IASTDataTransferRequestProcessor.java | 8 ++++++-- .../main/java/com/newrelic/api/agent/security/Agent.java | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index bd77424a4..2ec582429 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -138,7 +138,7 @@ private void instantiateAgentMode(String groupName) { readSkipScan(); } catch (RestrictionModeException e){ System.err.println("[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled."); - NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled. Message :{}", e.getMessage()); + NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled. Message : {0}", e.getMessage()); NewRelic.noticeError(e, Agent.getCustomNoticeErrorParameters(), true); AgentInfo.getInstance().agentStatTrigger(false); } 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 c73a1cbf0..4dcb65480 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 @@ -156,17 +156,21 @@ public static IASTDataTransferRequestProcessor getInstance() { public void startDataRequestSchedule(long delay, TimeUnit timeUnit){ try { stopDataRequestSchedule(true); - long initialDelay = AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime().toInstant().getEpochSecond() - Instant.now().getEpochSecond(); + long initialDelay = 0; + if(AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime() != null) { + initialDelay = AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime().toInstant().getEpochSecond() - Instant.now().getEpochSecond(); + } if(initialDelay < 0){ initialDelay = 0; } - logger.log(LogLevel.INFO, String.format("IAST data pull request is scheduled at %s", AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime()), IASTDataTransferRequestProcessor.class.getName()); + logger.log(LogLevel.INFO, String.format("IAST data pull request is scheduled at %s, after delay of %s seconds", AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime(), initialDelay), IASTDataTransferRequestProcessor.class.getName()); future = executorService.scheduleWithFixedDelay(this::task, initialDelay, delay, timeUnit); } catch (Throwable ignored){} } public void stopDataRequestSchedule(boolean force){ try { + logger.log(LogLevel.FINER, "deactivating data pull request until reschedule.", IASTDataTransferRequestProcessor.class.getName()); if (this.future != null) { future.cancel(force); future = null; 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 fbf5df4a1..445ba72d0 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 @@ -197,7 +197,7 @@ private void IastDeactivate() { SchedulerHelper.getInstance().scheduleIastTrigger(this::triggerNrSecurity, delay, TimeUnit.MILLISECONDS); } catch (ParseException e) { System.err.println("[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled."); - NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled. Message :{}", e.getMessage()); + NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled. Message :{0}", e.getMessage()); NewRelic.noticeError(new RestrictionModeException(INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE, e), Agent.getCustomNoticeErrorParameters(), true); AgentInfo.getInstance().agentStatTrigger(false); } From 9c7fe754e040938185459e1825901fd6a15177a7 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Fri, 16 Aug 2024 17:42:19 +0530 Subject: [PATCH 17/44] Shutdown agent if config is incorrect Prevent multiple schedules of IAST trigger --- .../newrelic/agent/security/AgentConfig.java | 13 +++++++---- .../schedulers/SchedulerHelper.java | 9 +++++++- .../newrelic/api/agent/security/Agent.java | 23 ++++++++++++++----- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index 2ec582429..cfe4d9c0e 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -68,7 +68,7 @@ public class AgentConfig { private AgentConfig(){ } - public long instantiate(){ + public long instantiate() throws RestrictionModeException { //Set k2 home path boolean validHomePath = setSecurityHomePath(); if(validHomePath) { @@ -92,7 +92,7 @@ public long instantiate(){ return triggerIAST(); } - public long triggerIAST() { + public long triggerIAST() throws RestrictionModeException { try { if(agentMode.getScanSchedule().getNextScanTime() != null) { logger.log(LogLevel.FINER, "Security Agent scan time is set to : " + agentMode.getScanSchedule().getNextScanTime(), AgentConfig.class.getName()); @@ -100,15 +100,16 @@ public long triggerIAST() { return (delay > 0)? delay : 0; } } catch (Exception e){ - NewRelic.noticeError(new RestrictionModeException("Error while calculating next scan time for IAST Restricted Mode", e), Agent.getCustomNoticeErrorParameters(), true); + RestrictionModeException restrictionModeException = new RestrictionModeException("Error while calculating next scan time for IAST Restricted Mode", e); + NewRelic.noticeError(restrictionModeException, Agent.getCustomNoticeErrorParameters(), true); System.err.println("[NR-CSEC-JA] Error while calculating next scan time for IAST Restricted Mode. IAST Restricted Mode will be disabled."); NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while calculating next scan time for IAST Restricted Mode. IAST Restricted Mode will be disabled."); - return Long.MAX_VALUE; + throw restrictionModeException; } return 0; } - private void instantiateAgentMode(String groupName) { + private void instantiateAgentMode(String groupName) throws RestrictionModeException { this.agentMode = new AgentMode(groupName); switch (groupName){ case IAST: @@ -126,6 +127,7 @@ private void instantiateAgentMode(String groupName) { NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Restricted Mode Configuration. IAST Restricted Mode will be disabled."); NewRelic.noticeError(e, Agent.getCustomNoticeErrorParameters(), true); AgentInfo.getInstance().agentStatTrigger(false); + throw e; } break; default: @@ -141,6 +143,7 @@ private void instantiateAgentMode(String groupName) { NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled. Message : {0}", e.getMessage()); NewRelic.noticeError(e, Agent.getCustomNoticeErrorParameters(), true); AgentInfo.getInstance().agentStatTrigger(false); + throw e; } logger.log(LogLevel.INFO, String.format("Security Agent Modes and Config : %s", agentMode), AgentConfig.class.getName()); } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java index 8568a08a1..e51f0659a 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java @@ -11,6 +11,7 @@ public class SchedulerHelper { + public static final String IAST_TRIGGER = "IastTrigger"; private final ScheduledExecutorService commonExecutor; private SchedulerHelper() { @@ -38,7 +39,13 @@ public static SchedulerHelper getInstance() { private final Map> scheduledFutureMap = new ConcurrentHashMap<>(); public ScheduledFuture scheduleIastTrigger(Runnable runnable, long initialDelay, TimeUnit unit) { - return commonExecutor.schedule(runnable, initialDelay, unit); + if(scheduledFutureMap.containsKey(IAST_TRIGGER)){ + ScheduledFuture currentFuture = scheduledFutureMap.get(IAST_TRIGGER); + currentFuture.cancel(false); + } + ScheduledFuture future = commonExecutor.schedule(runnable, initialDelay, unit); + scheduledFutureMap.put(IAST_TRIGGER, future); + return future; } public ScheduledFuture scheduleHealthCheck(Runnable command, 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 445ba72d0..2fd960bb8 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 @@ -103,8 +103,7 @@ public static Map getCustomNoticeErrorParameters() { return customNoticeErrorParameters; } - private void initialise() { - + private void initialise() throws RestrictionModeException { if (!isInitialised()) { config = AgentConfig.getInstance(); info = AgentInfo.getInstance(); @@ -163,7 +162,8 @@ private void triggerNrSecurity() { //Schedule NR csec shutdown if required scheduleShutdownTrigger(); } catch (Exception e){ - e.printStackTrace(); + NewRelic.getAgent().getLogger().log(Level.SEVERE, "[NR-CSEC-JA] Deactivating NewRelic Security Agent due to {0}", e.getMessage()); + NewRelic.noticeError(e, customNoticeErrorParameters, true); } } @@ -195,6 +195,9 @@ private void IastDeactivate() { } long delay = config.triggerIAST(); SchedulerHelper.getInstance().scheduleIastTrigger(this::triggerNrSecurity, delay, TimeUnit.MILLISECONDS); + } catch (RestrictionModeException | SecurityException exception){ + NewRelic.getAgent().getLogger().log(Level.SEVERE, "[NR-CSEC-JA] Deactivating NewRelic Security Agent due to {0}", exception.getMessage()); + NewRelic.noticeError(exception, customNoticeErrorParameters, true); } catch (ParseException e) { System.err.println("[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled."); NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled. Message :{0}", e.getMessage()); @@ -205,9 +208,14 @@ private void IastDeactivate() { } private void IastRestrictedShutdown() { - InstrumentationUtils.shutdownLogic(); - long delay = config.triggerIAST(); - SchedulerHelper.getInstance().scheduleIastTrigger(this::triggerNrSecurity, delay, TimeUnit.MILLISECONDS); + try { + InstrumentationUtils.shutdownLogic(); + long delay = config.triggerIAST(); + SchedulerHelper.getInstance().scheduleIastTrigger(this::triggerNrSecurity, delay, TimeUnit.MILLISECONDS); + } catch (RestrictionModeException | SecurityException exception){ + NewRelic.getAgent().getLogger().log(Level.SEVERE, "[NR-CSEC-JA] Deactivating NewRelic Security Agent due to {0}", exception.getMessage()); + NewRelic.noticeError(exception, customNoticeErrorParameters, true); + } } private void populateApplicationTmpDir() { @@ -292,6 +300,9 @@ public boolean refreshState(java.net.URL agentJarURL, Instrumentation instrument } initialise(); NewRelic.getAgent().getLogger().log(Level.INFO, "Security refresh was invoked, Security Agent initiation is successful."); + } catch (RestrictionModeException | SecurityException exception){ + NewRelic.getAgent().getLogger().log(Level.SEVERE, "[NR-CSEC-JA] Deactivating NewRelic Security Agent due to {0}", exception.getMessage()); + NewRelic.noticeError(exception, customNoticeErrorParameters, true); } catch (Exception e){ NewRelic.getAgent().getLogger().log(Level.SEVERE, "Newrelic Security Startup failed!!!", e); NewRelic.noticeError(e, customNoticeErrorParameters, true); From f42659e577c0c26842307342b0919cf47a5b697f Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Tue, 20 Aug 2024 09:56:13 +0530 Subject: [PATCH 18/44] Fix jtds, postgress lock acquire case type. Upgrade pool cleanups and reset --- .../jdbc/JtdsStatement_Instrumentation.java | 22 ++++++++--------- .../jdbc/PgStatement_Instrumentation.java | 16 ++++++------- .../dispatcher/DispatcherPool.java | 1 + .../ControlCommandProcessorThreadPool.java | 14 +++++++++++ .../intcodeagent/websocket/EventSendPool.java | 1 + .../newrelic/api/agent/security/Agent.java | 24 ++++++++++++------- 6 files changed, 51 insertions(+), 27 deletions(-) diff --git a/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsStatement_Instrumentation.java b/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsStatement_Instrumentation.java index c2f9dc4ee..95d6ad062 100644 --- a/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsStatement_Instrumentation.java +++ b/instrumentation-security/jdbc-jtds-generic/src/main/java/net/sourceforge/jtds/jdbc/JtdsStatement_Instrumentation.java @@ -70,12 +70,12 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { - return GenericHelper.acquireLockIfPossible(httpRequest, JdbcHelper.getNrSecCustomAttribName()); + private boolean acquireLockIfPossible() { + return GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND, JdbcHelper.getNrSecCustomAttribName()); } public ResultSet executeQuery(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_QUERY); @@ -93,7 +93,7 @@ public ResultSet executeQuery(String sql) throws SQLException { } public int executeUpdate(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -111,7 +111,7 @@ public int executeUpdate(String sql) throws SQLException { } public boolean execute(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); @@ -129,7 +129,7 @@ public boolean execute(String sql) throws SQLException { } public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -148,7 +148,7 @@ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -166,7 +166,7 @@ public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { } public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); @@ -184,7 +184,7 @@ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { } public int executeUpdate(String sql, String[] columnNames) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -202,7 +202,7 @@ public int executeUpdate(String sql, String[] columnNames) throws SQLException { } public boolean execute(String sql, String[] columnNames) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); @@ -221,7 +221,7 @@ public boolean execute(String sql, String[] columnNames) throws SQLException { public boolean execute(String sql, int[] columnIndexes) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); diff --git a/instrumentation-security/jdbc-postgresql-9.4.1207/src/main/java/org/postgresql/jdbc/PgStatement_Instrumentation.java b/instrumentation-security/jdbc-postgresql-9.4.1207/src/main/java/org/postgresql/jdbc/PgStatement_Instrumentation.java index f27cb4069..e032d4204 100644 --- a/instrumentation-security/jdbc-postgresql-9.4.1207/src/main/java/org/postgresql/jdbc/PgStatement_Instrumentation.java +++ b/instrumentation-security/jdbc-postgresql-9.4.1207/src/main/java/org/postgresql/jdbc/PgStatement_Instrumentation.java @@ -84,12 +84,12 @@ private void releaseLock() { } catch (Throwable ignored) {} } - private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { - return GenericHelper.acquireLockIfPossible(httpRequest, JdbcHelper.getNrSecCustomAttribName()); + private boolean acquireLockIfPossible() { + return GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND, JdbcHelper.getNrSecCustomAttribName()); } public ResultSet executeQuery() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -110,7 +110,7 @@ public ResultSet executeQuery() throws SQLException { } public ResultSet executeQuery(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_QUERY); @@ -128,7 +128,7 @@ public ResultSet executeQuery(String sql) throws SQLException { } public int executeUpdate() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -149,7 +149,7 @@ public int executeUpdate() throws SQLException { } public int executeUpdate(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -167,7 +167,7 @@ public int executeUpdate(String sql) throws SQLException { } public boolean execute() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -189,7 +189,7 @@ public boolean execute() throws SQLException { @Trace(leaf = true) public boolean execute(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); 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 fe9498539..0f9db44a7 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 @@ -269,5 +269,6 @@ public void shutDownThreadPoolExecutor() { public void reset() { executor.getQueue().clear(); + executor.purge(); } } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessorThreadPool.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessorThreadPool.java index 0ef0dcd89..badd1c22a 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessorThreadPool.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessorThreadPool.java @@ -119,6 +119,20 @@ public static ControlCommandProcessorThreadPool getInstance() { return instance; } + public static void clearAllTasks() { + if (instance != null) { + instance.clearAllTasks(true); + } + } + + private void clearAllTasks(boolean force) { + executor.getQueue().clear(); + executor.purge(); + if(force) { + + } + } + public static void shutDownPool() { if (instance != null) { instance.shutDownThreadPoolExecutor(); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java index ab9dc3650..f517a9ad1 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java @@ -177,5 +177,6 @@ public ThreadPoolExecutor getExecutor() { public void reset() { executor.getQueue().clear(); + executor.purge(); } } 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 2fd960bb8..3aa31e43d 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 @@ -5,6 +5,7 @@ import com.newrelic.agent.security.AgentInfo; import com.newrelic.agent.security.instrumentator.dispatcher.DispatcherPool; import com.newrelic.agent.security.instrumentator.httpclient.IASTDataTransferRequestProcessor; +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; @@ -321,7 +322,7 @@ private void cancelActiveServiceTasks() { HealthCheckScheduleThread.getInstance().cancelTask(true); WSReconnectionST.cancelTask(true); FileCleaner.cancelTask(); - ControlCommandProcessorThreadPool.shutDownPool(); + ControlCommandProcessorThreadPool.clearAllTasks(); } @@ -334,18 +335,25 @@ public boolean deactivateSecurity() { } private void deactivateSecurityServices(){ - /** - * ShutDown following - * 1. policy + policy parameter - * 2. websocket - * 3. event pool - * 4. HealthCheck - **/ + /* + ShutDown following + 1. policy + policy parameter + 2. websocket + 3. event pool + 4. HealthCheck + */ // InstrumentationUtils.shutdownLogic(); IASTDataTransferRequestProcessor.getInstance().stopDataRequestSchedule(true); if(!config.getAgentMode().getScanSchedule().isCollectSamples()) { AgentInfo.getInstance().setAgentActive(false); HealthCheckScheduleThread.getInstance().cancelTask(true); + ControlCommandProcessorThreadPool.clearAllTasks(); + RestRequestThreadPool.getInstance().resetIASTProcessing(); + GrpcClientRequestReplayHelper.getInstance().resetIASTProcessing(); + RestRequestThreadPool.getInstance().getRejectedIds().clear(); + GrpcClientRequestReplayHelper.getInstance().getRejectedIds().clear(); + DispatcherPool.getInstance().reset(); + EventSendPool.getInstance().reset(); FileCleaner.cancelTask(); WSReconnectionST.cancelTask(true); WSClient.shutDownWSClient(true, CloseFrame.NORMAL, "Deactivating Security Agent"); From 5408c8718fd96a2213423fea74d6cbbba2673eeb Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Tue, 20 Aug 2024 12:13:20 +0530 Subject: [PATCH 19/44] rename flag for always sample collections --- .../java/com/newrelic/agent/security/util/IUtilConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java index 80850f016..fd126a910 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java @@ -11,7 +11,7 @@ public interface IUtilConstants { String SCAN_TIME_DELAY = "security.scan_schedule.delay"; String SCAN_TIME_SCHEDULE = "security.scan_schedule.schedule"; String SCAN_TIME_DURATION = "security.scan_schedule.duration"; - String SCAN_TIME_COLLECT_SAMPLES = "security.scan_schedule.allow_iast_sample_collection"; + String SCAN_TIME_COLLECT_SAMPLES = "security.scan_schedule.always_sample_traces"; String SKIP_IAST_SCAN = "security.skip_iast_scan"; String SKIP_IAST_SCAN_API = SKIP_IAST_SCAN + ".api"; From ebe8789bd77037563064bf7c9be36dc8c2448907 Mon Sep 17 00:00:00 2001 From: idawda Date: Wed, 21 Aug 2024 11:13:40 +0530 Subject: [PATCH 20/44] NR-304574: Rate limit the IAST replay requests --- .../httpclient/IASTDataTransferRequestProcessor.java | 7 ++++++- .../com/newrelic/agent/security/util/IUtilConstants.java | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) 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 4dcb65480..f1071d4ba 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 @@ -4,6 +4,7 @@ import com.newrelic.agent.security.AgentInfo; import com.newrelic.agent.security.instrumentator.utils.INRSettingsKey; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; +import com.newrelic.agent.security.util.IUtilConstants; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.agent.security.intcodeagent.models.IASTDataTransferRequest; import com.newrelic.agent.security.intcodeagent.websocket.JsonConverter; @@ -78,6 +79,9 @@ private void task() { int currentFetchThreshold = NewRelic.getAgent().getConfig() .getValue(SECURITY_POLICY_VULNERABILITY_SCAN_IAST_SCAN_PROBING_THRESHOLD, 300); + int iastFetchInterval = Math.min(Math.max(NewRelic.getAgent().getConfig().getValue(IUtilConstants.IAST_LOAD_INTERVAL, 5), 5), 500); + int fetchRatio = iastFetchInterval/5; + int remainingRecordCapacityRest = RestRequestThreadPool.getInstance().getQueue().remainingCapacity(); int currentRecordBacklogRest = RestRequestThreadPool.getInstance().getQueue().size(); int remainingRecordCapacityGrpc = GrpcClientRequestReplayHelper.getInstance().getRequestQueue().remainingCapacity(); @@ -90,8 +94,9 @@ private void task() { if(!AgentUsageMetric.isRASPProcessingActive()){ batchSize /= 2; } + batchSize /= fetchRatio; - if (batchSize > 100 && remainingRecordCapacity > batchSize) { + if (batchSize > 100/fetchRatio && remainingRecordCapacity > batchSize) { request = new IASTDataTransferRequest(NewRelicSecurity.getAgent().getAgentUUID()); if (AgentConfig.getInstance().getConfig().getCustomerInfo() != null) { request.setAppAccountId(AgentConfig.getInstance().getConfig().getCustomerInfo().getAccountId()); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java index fd126a910..5aec9dcc5 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java @@ -12,6 +12,7 @@ public interface IUtilConstants { String SCAN_TIME_SCHEDULE = "security.scan_schedule.schedule"; String SCAN_TIME_DURATION = "security.scan_schedule.duration"; String SCAN_TIME_COLLECT_SAMPLES = "security.scan_schedule.always_sample_traces"; + String IAST_LOAD_INTERVAL = "security.scan_controllers.iast_load_interval"; String SKIP_IAST_SCAN = "security.skip_iast_scan"; String SKIP_IAST_SCAN_API = SKIP_IAST_SCAN + ".api"; From a729fcac52565b0d17bc710b1755e2347488550d Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Wed, 21 Aug 2024 17:31:41 +0530 Subject: [PATCH 21/44] fix for incompatible data type for skip scan parameters --- .../com/newrelic/agent/security/AgentConfig.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index cfe4d9c0e..720b08494 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -31,6 +31,7 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.logging.Level; +import java.util.stream.Collectors; import static com.newrelic.agent.security.util.IUtilConstants.*; @@ -151,9 +152,15 @@ private void instantiateAgentMode(String groupName) throws RestrictionModeExcept private void readSkipScan() throws RestrictionModeException { try { agentMode.getSkipScan().setApis(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_API, Collections.emptyList())); - agentMode.getSkipScan().getParameters().setQuery(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_QUERY, Collections.emptyList())); - agentMode.getSkipScan().getParameters().setHeader(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_HEADER, Collections.emptyList())); - agentMode.getSkipScan().getParameters().setBody(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_BODY, Collections.emptyList())); + agentMode.getSkipScan().getParameters().setQuery(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_QUERY, Collections.emptyList()).stream() + .map(Object::toString) + .collect(Collectors.toList())); + agentMode.getSkipScan().getParameters().setHeader(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_HEADER, Collections.emptyList()).stream() + .map(Object::toString) + .collect(Collectors.toList())); + agentMode.getSkipScan().getParameters().setBody(NewRelic.getAgent().getConfig().getValue(SKIP_IAST_SCAN_PARAMETERS_BODY, Collections.emptyList()).stream() + .map(Object::toString) + .collect(Collectors.toList())); agentMode.getSkipScan().getIastDetectionCategory().setInsecureSettingsEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INSECURE_SETTINGS, false)); agentMode.getSkipScan().getIastDetectionCategory().setInvalidFileAccessEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_INVALID_FILE_ACCESS, false)); agentMode.getSkipScan().getIastDetectionCategory().setSqlInjectionEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_SQL_INJECTION, false)); From 120ff86371ee335a138918156e926b58436a4380 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 22 Aug 2024 11:19:15 +0530 Subject: [PATCH 22/44] Update config fields --- .../newrelic/agent/security/util/IUtilConstants.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java index fd126a910..152567f4c 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java @@ -13,12 +13,12 @@ public interface IUtilConstants { String SCAN_TIME_DURATION = "security.scan_schedule.duration"; String SCAN_TIME_COLLECT_SAMPLES = "security.scan_schedule.always_sample_traces"; - String SKIP_IAST_SCAN = "security.skip_iast_scan"; + String SKIP_IAST_SCAN = "security.exclude_from_iast_scan"; String SKIP_IAST_SCAN_API = SKIP_IAST_SCAN + ".api"; - String SKIP_IAST_SCAN_PARAMETERS = SKIP_IAST_SCAN + ".parameters"; - String SKIP_IAST_SCAN_PARAMETERS_HEADER = SKIP_IAST_SCAN + ".parameters.header"; - String SKIP_IAST_SCAN_PARAMETERS_QUERY = SKIP_IAST_SCAN + ".parameters.query"; - String SKIP_IAST_SCAN_PARAMETERS_BODY = SKIP_IAST_SCAN + ".parameters.body"; + String SKIP_IAST_SCAN_PARAMETERS = SKIP_IAST_SCAN + ".http_request_parameters"; + String SKIP_IAST_SCAN_PARAMETERS_HEADER = SKIP_IAST_SCAN + ".http_request_parameters.header"; + String SKIP_IAST_SCAN_PARAMETERS_QUERY = SKIP_IAST_SCAN + ".http_request_parameters.query"; + String SKIP_IAST_SCAN_PARAMETERS_BODY = SKIP_IAST_SCAN + ".http_request_parameters.body"; String SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY = SKIP_IAST_SCAN + ".iast_detection_category"; String SKIP_INSECURE_SETTINGS = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".insecure_settings"; String SKIP_INVALID_FILE_ACCESS = SKIP_IAST_SCAN_PARAMETERS_IAST_DETECTION_CATEGORY + ".invalid_file_access"; From c361033c37316f2c6c8ffc48968cc51839569eee Mon Sep 17 00:00:00 2001 From: idawda Date: Thu, 22 Aug 2024 15:32:07 +0530 Subject: [PATCH 23/44] NR-287324: Report API endpoints immediately after 60 seconds, as soon as new endpoints are discovered --- .../agent/security/instrumentator/utils/AgentUtils.java | 1 - .../security/intcodeagent/schedulers/SchedulerHelper.java | 8 ++++++++ .../agent/security/intcodeagent/websocket/WSClient.java | 1 - .../main/java/com/newrelic/api/agent/security/Agent.java | 5 +++++ .../main/java/com/newrelic/api/agent/security/Agent.java | 5 +++++ .../java/com/newrelic/api/agent/security/NoOpAgent.java | 5 ++++- .../com/newrelic/api/agent/security/SecurityAgent.java | 2 ++ .../instrumentation/helpers/URLMappingsHelper.java | 2 ++ 8 files changed, 26 insertions(+), 3 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/AgentUtils.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/AgentUtils.java index da5c72381..e8926f7d0 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/AgentUtils.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/instrumentator/utils/AgentUtils.java @@ -667,7 +667,6 @@ private void applyNRPolicyOverride() { public static void sendApplicationURLMappings() { - //TODO mappings to be send once new mappings are discovered, after startup. ApplicationURLMappings applicationURLMappings = new ApplicationURLMappings(URLMappingsHelper.getApplicationURLMappings()); applicationURLMappings.setApplicationUUID(AgentInfo.getInstance().getApplicationUUID()); logger.logInit(LogLevel.INFO, String.format("Collected application url mappings %s", applicationURLMappings), Agent.class.getName()); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java index a68025e68..b20f74517 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/schedulers/SchedulerHelper.java @@ -86,4 +86,12 @@ public ScheduledFuture scheduleDailyLogRollover(Runnable command) { return null; } + public void scheduleURLMappingPosting(Runnable runnable) { + if(scheduledFutureMap.containsKey(IAgentConstants.JSON_SEC_APPLICATION_URL_MAPPING)){ + ScheduledFuture future = scheduledFutureMap.get(IAgentConstants.JSON_SEC_APPLICATION_URL_MAPPING); + future.cancel(false); + } + ScheduledFuture future = commonExecutor.schedule(runnable, 60, TimeUnit.SECONDS); + scheduledFutureMap.put(IAgentConstants.JSON_SEC_APPLICATION_URL_MAPPING, future); + } } 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 338fb464d..eaa5ad97c 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 @@ -257,7 +257,6 @@ public void onOpen(ServerHandshake handshakedata) { WSUtils.getInstance().notifyAll(); } WSUtils.getInstance().setConnected(true); - AgentUtils.sendApplicationURLMappings(); logger.logInit(LogLevel.INFO, String.format(IAgentConstants.APPLICATION_INFO_SENT_ON_WS_CONNECT, AgentInfo.getInstance().getApplicationInfo()), WSClient.class.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 f0241ac02..9aad9a97c 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 @@ -956,4 +956,9 @@ public boolean recordExceptions(SecurityMetaData securityMetaData, Throwable exc return RuntimeErrorReporter.getInstance().addApplicationRuntimeError(applicationRuntimeError); } + @Override + public void reportURLMapping() { + SchedulerHelper.getInstance().scheduleURLMappingPosting(AgentUtils::sendApplicationURLMappings); + } + } \ 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 3f47b0954..a16eaf983 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 @@ -211,4 +211,9 @@ public void reportApplicationRuntimeError(SecurityMetaData securityMetaData, Thr public boolean recordExceptions(SecurityMetaData securityMetaData, Throwable exception) { return false; } + + @Override + public void reportURLMapping() { + + } } \ 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 d5e0f6e74..7c6db73b3 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,7 +7,6 @@ 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.SecurityMetaData; import com.newrelic.api.agent.security.schema.ServerConnectionConfiguration; @@ -142,5 +141,9 @@ public boolean recordExceptions(SecurityMetaData securityMetaData, Throwable exc return false; } + @Override + public void reportURLMapping() { + + } } 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 82b573974..a0b9627f6 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 @@ -75,4 +75,6 @@ void reportIASTScanFailure(SecurityMetaData securityMetaData, String apiId, Thro void reportApplicationRuntimeError(SecurityMetaData securityMetaData, Throwable exception); boolean recordExceptions(SecurityMetaData securityMetaData, Throwable exception); + + void reportURLMapping(); } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/URLMappingsHelper.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/URLMappingsHelper.java index 9a045a8e2..ee8aa8315 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/URLMappingsHelper.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/URLMappingsHelper.java @@ -1,5 +1,6 @@ package com.newrelic.api.agent.security.instrumentation.helpers; +import com.newrelic.api.agent.security.NewRelicSecurity; import com.newrelic.api.agent.security.schema.ApplicationURLMapping; import com.newrelic.api.agent.security.schema.RouteSegment; import com.newrelic.api.agent.security.schema.RouteSegments; @@ -63,6 +64,7 @@ public static void addApplicationURLMapping(ApplicationURLMapping mapping) { if (mapping.getHandler() != null){ handlers.add(mapping.getHandler().hashCode()); } + NewRelicSecurity.getAgent().reportURLMapping(); } private synchronized static void generateRouteSegments(String endpoint) { From 7b6e9c878f95af472d6fe73a40058dc5426ba5c2 Mon Sep 17 00:00:00 2001 From: idawda Date: Fri, 23 Aug 2024 13:43:40 +0530 Subject: [PATCH 24/44] NR-304574: Rate limit the IAST replay requests the default value is 3600 replay req. per min --- .../IASTDataTransferRequestProcessor.java | 21 ++++++++++++------- .../agent/security/util/IUtilConstants.java | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) 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 f1071d4ba..511ca2282 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 @@ -3,6 +3,7 @@ import com.newrelic.agent.security.AgentConfig; import com.newrelic.agent.security.AgentInfo; import com.newrelic.agent.security.instrumentator.utils.INRSettingsKey; +import com.newrelic.agent.security.intcodeagent.exceptions.RestrictionModeException; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.agent.security.util.IUtilConstants; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -29,8 +30,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; -import static com.newrelic.agent.security.instrumentator.utils.INRSettingsKey.SECURITY_POLICY_VULNERABILITY_SCAN_IAST_SCAN_PROBING_THRESHOLD; - public class IASTDataTransferRequestProcessor { private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); public static final String UNABLE_TO_SEND_IAST_DATA_REQUEST_DUE_TO_ERROR_S_S = "Unable to send IAST data request due to error: %s : %s"; @@ -48,6 +47,8 @@ public class IASTDataTransferRequestProcessor { private final AtomicLong lastFuzzCCTimestamp = new AtomicLong(); + private int currentFetchThresholdPerMin = 3600; + private void task() { IASTDataTransferRequest request = null; try { @@ -76,11 +77,12 @@ private void task() { return; } - int currentFetchThreshold = NewRelic.getAgent().getConfig() - .getValue(SECURITY_POLICY_VULNERABILITY_SCAN_IAST_SCAN_PROBING_THRESHOLD, 300); + int currentFetchThreshold = currentFetchThresholdPerMin/12; + if (currentFetchThreshold <= 0){ + return; + } - int iastFetchInterval = Math.min(Math.max(NewRelic.getAgent().getConfig().getValue(IUtilConstants.IAST_LOAD_INTERVAL, 5), 5), 500); - int fetchRatio = iastFetchInterval/5; + int fetchRatio = 300/currentFetchThreshold; int remainingRecordCapacityRest = RestRequestThreadPool.getInstance().getQueue().remainingCapacity(); int currentRecordBacklogRest = RestRequestThreadPool.getInstance().getQueue().size(); @@ -94,7 +96,6 @@ private void task() { if(!AgentUsageMetric.isRASPProcessingActive()){ batchSize /= 2; } - batchSize /= fetchRatio; if (batchSize > 100/fetchRatio && remainingRecordCapacity > batchSize) { request = new IASTDataTransferRequest(NewRelicSecurity.getAgent().getAgentUUID()); @@ -168,6 +169,12 @@ public void startDataRequestSchedule(long delay, TimeUnit timeUnit){ if(initialDelay < 0){ initialDelay = 0; } + // IAST Scan Rate per minute with range [12, 3600]; default 3600 replay requests will be replayed per minute + try { + currentFetchThresholdPerMin = Math.min(Math.max(NewRelic.getAgent().getConfig().getValue(IUtilConstants.SCAN_REQUEST_RATE_LIMIT, 3600), 12), 3600); + } catch (Exception e) { + logger.log(LogLevel.WARNING, String.format("Error while reading Configuration security.scan_request_rate_limit : %s, Using default value %s replay request per min.", e.getMessage(), currentFetchThresholdPerMin), e, this.getClass().getName()); + } logger.log(LogLevel.INFO, String.format("IAST data pull request is scheduled at %s, after delay of %s seconds", AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime(), initialDelay), IASTDataTransferRequestProcessor.class.getName()); future = executorService.scheduleWithFixedDelay(this::task, initialDelay, delay, timeUnit); } catch (Throwable ignored){} diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java index 0c62b114d..4f5c1ac48 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java @@ -12,7 +12,7 @@ public interface IUtilConstants { String SCAN_TIME_SCHEDULE = "security.scan_schedule.schedule"; String SCAN_TIME_DURATION = "security.scan_schedule.duration"; String SCAN_TIME_COLLECT_SAMPLES = "security.scan_schedule.always_sample_traces"; - String IAST_LOAD_INTERVAL = "security.scan_controllers.iast_load_interval"; + String SCAN_REQUEST_RATE_LIMIT = "security.scan_request_rate_limit"; String SKIP_IAST_SCAN = "security.exclude_from_iast_scan"; String SKIP_IAST_SCAN_API = SKIP_IAST_SCAN + ".api"; From e8db0c7093b455dd60a387a589b749aec3bb8ab4 Mon Sep 17 00:00:00 2001 From: idawda Date: Mon, 26 Aug 2024 18:54:49 +0530 Subject: [PATCH 25/44] NR-303483: Server Configuration for WebSphere Liberty --- .../build.gradle | 29 +++++++++++++++ .../lib/.gitignore | 2 + .../internal/TCPChannelFactory.java | 37 +++++++++++++++++++ .../helpers/GenericHelper.java | 1 + settings.gradle | 1 + 5 files changed, 70 insertions(+) create mode 100644 instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/build.gradle create mode 100644 instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/lib/.gitignore create mode 100644 instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/src/main/java/com/ibm/ws/tcpchannel/internal/TCPChannelFactory.java diff --git a/instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/build.gradle b/instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/build.gradle new file mode 100644 index 000000000..7312021d2 --- /dev/null +++ b/instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/build.gradle @@ -0,0 +1,29 @@ +dependencies { + implementation(project(":newrelic-security-api")) + implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}") + implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}") + implementation(fileTree(include: ["*.jar"], dir: "lib")) +} + +def shouldBuild = fileTree(include: ["*.jar"], dir: "lib").size() > 0 + +compileJava { + enabled(shouldBuild) +} + +compileTestJava { + enabled(shouldBuild) +} + +tasks.getByName("writeCachedWeaveAttributes").enabled(shouldBuild) + +jar { + enabled(shouldBuild) + manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.websphere-liberty' } +} + +site { + title 'WebSphere Liberty' + type 'Appserver' + versionOverride '[8.5,)' +} \ No newline at end of file diff --git a/instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/lib/.gitignore b/instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/lib/.gitignore new file mode 100644 index 000000000..c96a04f00 --- /dev/null +++ b/instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/lib/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/src/main/java/com/ibm/ws/tcpchannel/internal/TCPChannelFactory.java b/instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/src/main/java/com/ibm/ws/tcpchannel/internal/TCPChannelFactory.java new file mode 100644 index 000000000..848fb3aeb --- /dev/null +++ b/instrumentation-security/websphere-liberty-profile-environment-8.5.5.5/src/main/java/com/ibm/ws/tcpchannel/internal/TCPChannelFactory.java @@ -0,0 +1,37 @@ +package com.ibm.ws.tcpchannel.internal; + +import com.ibm.websphere.channelfw.ChannelData; +import com.ibm.wsspi.channelfw.Channel; +import com.ibm.wsspi.channelfw.exception.ChannelException; +import com.newrelic.api.agent.security.NewRelicSecurity; +import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.utils.logging.LogLevel; +import com.newrelic.api.agent.weaver.Weave; +import com.newrelic.api.agent.weaver.Weaver; +import java.util.Map; + +@Weave +public class TCPChannelFactory { + + protected Channel createChannel(final ChannelData channelData) throws ChannelException { + try { + if (channelData.isInbound() && "defaultHttpEndpoint".equals(channelData.getExternalName())) { + Map propertyBag = channelData.getPropertyBag(); + if (propertyBag.containsKey("port")) { + try { + int port = Integer.parseInt((String) propertyBag.get("port")); + NewRelicSecurity.getAgent().setApplicationConnectionConfig(port, "http"); + } catch (NumberFormatException e) { + NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.SERVER_CONFIG_ERROR, "WEBSPHERE_LIBERTY", e.getMessage()), e, this.getClass().getName()); + } + } else { + NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.SERVER_CONFIG_ERROR, "WEBSPHERE_LIBERTY", null), null, this.getClass().getName()); + } + } else { + NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.SERVER_CONFIG_ERROR, "WEBSPHERE_LIBERTY", null), null, this.getClass().getName()); + } + } catch (Exception ignored) { + } + return Weaver.callOriginal(); + } +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GenericHelper.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GenericHelper.java index 8d4cf3f0f..c55dbd421 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GenericHelper.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/instrumentation/helpers/GenericHelper.java @@ -14,6 +14,7 @@ public class GenericHelper { public static final String NR_SEC_CUSTOM_SPRING_REDIS_ATTR = "SPRING-DATA-REDIS"; public static final String REGISTER_OPERATION_EXCEPTION_MESSAGE = "Instrumentation library: %s , error while library instrumented call processing : %s"; + public static final String SERVER_CONFIG_ERROR = "Instrumentation library: %s , error while detecting Server Configuration : %s"; public static final String EXIT_OPERATION_EXCEPTION_MESSAGE = "Instrumentation library: %s , error while generating exit operation: %s"; public static final String SECURITY_EXCEPTION_MESSAGE = "New Relic Security Exception raised for Instrumentation library: %s, reason: %s "; public static final String URI_EXCEPTION_MESSAGE = "Instrumentation library: %s , error while extracting URI : %s"; diff --git a/settings.gradle b/settings.gradle index b3b2cd194..a2b70cb0c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -216,3 +216,4 @@ include 'instrumentation:solr-5.1.0' include 'instrumentation:solr-7.0.0' include 'instrumentation:solr-8.0.0' include 'instrumentation:solr-9.0.0' +include 'instrumentation:websphere-liberty-profile-environment-8.5.5.5' \ No newline at end of file From 8a5dd01888fde1b7b9dbf5077aba41c53a345fd0 Mon Sep 17 00:00:00 2001 From: idawda Date: Wed, 28 Aug 2024 16:36:52 +0530 Subject: [PATCH 26/44] NR-303615: Fix for API Endpoint reported giving 404 response code --- .../instrumentation/apache/tomcat10/HttpServletHelper.java | 5 +++++ .../instrumentation/apache/tomcat7/HttpServletHelper.java | 5 +++++ .../security/instrumentation/jetty11/HttpServletHelper.java | 5 +++++ .../security/instrumentation/jetty9/HttpServletHelper.java | 5 +++++ .../instrumentation/servlet24/HttpServletHelper.java | 6 +++++- .../instrumentation/servlet30/HttpServletHelper.java | 5 +++++ .../instrumentation/servlet5/HttpServletHelper.java | 5 +++++ .../instrumentation/servlet6/HttpServletHelper.java | 5 +++++ 8 files changed, 40 insertions(+), 1 deletion(-) diff --git a/instrumentation-security/apache-tomcat-10/src/main/java/com/newrelic/agent/security/instrumentation/apache/tomcat10/HttpServletHelper.java b/instrumentation-security/apache-tomcat-10/src/main/java/com/newrelic/agent/security/instrumentation/apache/tomcat10/HttpServletHelper.java index 4979cbab2..f27ae5e0c 100644 --- a/instrumentation-security/apache-tomcat-10/src/main/java/com/newrelic/agent/security/instrumentation/apache/tomcat10/HttpServletHelper.java +++ b/instrumentation-security/apache-tomcat-10/src/main/java/com/newrelic/agent/security/instrumentation/apache/tomcat10/HttpServletHelper.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.instrumentation.helpers.URLMappingsHelper; import com.newrelic.api.agent.security.schema.ApplicationURLMapping; +import com.newrelic.api.agent.security.schema.StringUtils; import com.newrelic.api.agent.security.utils.logging.LogLevel; import jakarta.servlet.ServletContext; @@ -37,6 +38,10 @@ private static void getJSPMappings(ServletContext servletContext, String dir) { if(dir.endsWith(SEPARATOR)){ Collection resourcePaths = servletContext.getResourcePaths(dir); for (String path : resourcePaths) { + String entry = StringUtils.removeStart(StringUtils.removeEnd(path, SEPARATOR), StringUtils.SEPARATOR); + if (StringUtils.equalsAny(entry, "META-INF", "WEB-INF")) { + continue; + } if(path.endsWith(SEPARATOR)) { getJSPMappings(servletContext, path); } diff --git a/instrumentation-security/apache-tomcat-7/src/main/java/com/newrelic/agent/security/instrumentation/apache/tomcat7/HttpServletHelper.java b/instrumentation-security/apache-tomcat-7/src/main/java/com/newrelic/agent/security/instrumentation/apache/tomcat7/HttpServletHelper.java index 764334d19..c585c7b6c 100644 --- a/instrumentation-security/apache-tomcat-7/src/main/java/com/newrelic/agent/security/instrumentation/apache/tomcat7/HttpServletHelper.java +++ b/instrumentation-security/apache-tomcat-7/src/main/java/com/newrelic/agent/security/instrumentation/apache/tomcat7/HttpServletHelper.java @@ -4,6 +4,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.instrumentation.helpers.URLMappingsHelper; import com.newrelic.api.agent.security.schema.ApplicationURLMapping; +import com.newrelic.api.agent.security.schema.StringUtils; import com.newrelic.api.agent.security.utils.logging.LogLevel; import javax.servlet.ServletContext; @@ -36,6 +37,10 @@ private static void getJSPMappings(ServletContext servletContext, String dir) { if(dir.endsWith(SEPARATOR)){ Collection resourcePaths = servletContext.getResourcePaths(dir); for (String path : resourcePaths) { + String entry = StringUtils.removeStart(StringUtils.removeEnd(path, SEPARATOR), StringUtils.SEPARATOR); + if (StringUtils.equalsAny(entry, "META-INF", "WEB-INF")) { + continue; + } if(path.endsWith(SEPARATOR)) { getJSPMappings(servletContext, path); } 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 e0528d9e7..7d9da5b24 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 @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.schema.ApplicationURLMapping; 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.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; @@ -222,6 +223,10 @@ private static void getJSPMappings(ServletContext servletContext, String dir) { if(dir.endsWith(SEPARATOR)){ Collection resourcePaths = servletContext.getResourcePaths(dir); for (String path : resourcePaths) { + String entry = StringUtils.removeStart(StringUtils.removeEnd(path, SEPARATOR), StringUtils.SEPARATOR); + if (StringUtils.equalsAny(entry, "META-INF", "WEB-INF")) { + continue; + } if(path.endsWith(SEPARATOR)) { getJSPMappings(servletContext, path); } 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 07b87e142..fc7db6108 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 @@ -6,6 +6,7 @@ import com.newrelic.api.agent.security.schema.ApplicationURLMapping; 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.exceptions.NewRelicSecurityException; import com.newrelic.api.agent.security.schema.operation.RXSSOperation; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; @@ -224,6 +225,10 @@ private static void getJSPMappings(ServletContext servletContext, String dir) { if(dir.endsWith(SEPARATOR)){ Collection resourcePaths = servletContext.getResourcePaths(dir); for (String path : resourcePaths) { + String entry = StringUtils.removeStart(StringUtils.removeEnd(path, SEPARATOR), StringUtils.SEPARATOR); + if (StringUtils.equalsAny(entry, "META-INF", "WEB-INF")) { + continue; + } if(path.endsWith(SEPARATOR)) { getJSPMappings(servletContext, path); } 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..272fe95d2 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 @@ -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.StringUtils; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -13,7 +14,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 { @@ -142,6 +142,10 @@ public static void getJSPMappings(ServletContext servletContext, String dir) { if(dir.endsWith(SEPARATOR)){ Collection resourcePaths = servletContext.getResourcePaths(dir); for (String path : resourcePaths) { + String entry = StringUtils.removeStart(StringUtils.removeEnd(path, SEPARATOR), StringUtils.SEPARATOR); + if ( StringUtils.equalsAny(entry, "META-INF", "WEB-INF")) { + continue; + } if(path.endsWith(SEPARATOR)) { getJSPMappings(servletContext, path); } diff --git a/instrumentation-security/servlet-3.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet30/HttpServletHelper.java b/instrumentation-security/servlet-3.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet30/HttpServletHelper.java index 5084a7634..69fce5348 100644 --- a/instrumentation-security/servlet-3.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet30/HttpServletHelper.java +++ b/instrumentation-security/servlet-3.0/src/main/java/com/newrelic/agent/security/instrumentation/servlet30/HttpServletHelper.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; import com.newrelic.api.agent.security.instrumentation.helpers.URLMappingsHelper; import com.newrelic.api.agent.security.schema.ApplicationURLMapping; +import com.newrelic.api.agent.security.schema.StringUtils; import com.newrelic.api.agent.security.utils.logging.LogLevel; import javax.servlet.ServletContext; @@ -36,6 +37,10 @@ public static void getJSPMappings(ServletContext servletContext, String dir) { if(dir.endsWith(SEPARATOR)){ Collection resourcePaths = servletContext.getResourcePaths(dir); for (String path : resourcePaths) { + String entry = StringUtils.removeStart(StringUtils.removeEnd(path, SEPARATOR), StringUtils.SEPARATOR); + if ( StringUtils.equalsAny(entry, "META-INF", "WEB-INF")) { + continue; + } if(path.endsWith(SEPARATOR)) { getJSPMappings(servletContext, path); } 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 24c53074c..b87171180 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 @@ -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.StringUtils; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; import com.newrelic.api.agent.security.utils.logging.LogLevel; import jakarta.servlet.ServletContext; @@ -142,6 +143,10 @@ public static void getJSPMappings(ServletContext servletContext, String dir) { if(dir.endsWith(SEPARATOR)){ Collection resourcePaths = servletContext.getResourcePaths(dir); for (String path : resourcePaths) { + String entry = StringUtils.removeStart(StringUtils.removeEnd(path, SEPARATOR), StringUtils.SEPARATOR); + if ( StringUtils.equalsAny(entry, "META-INF", "WEB-INF")) { + continue; + } if(path.endsWith(SEPARATOR)) { getJSPMappings(servletContext, path); } 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..9f198294e 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 @@ -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.StringUtils; import com.newrelic.api.agent.security.schema.policy.AgentPolicy; import com.newrelic.api.agent.security.utils.logging.LogLevel; import jakarta.servlet.ServletContext; @@ -142,6 +143,10 @@ public static void getJSPMappings(ServletContext servletContext, String dir) { if(dir.endsWith(SEPARATOR)){ Collection resourcePaths = servletContext.getResourcePaths(dir); for (String path : resourcePaths) { + String entry = StringUtils.removeStart(StringUtils.removeEnd(path, SEPARATOR), StringUtils.SEPARATOR); + if ( StringUtils.equalsAny(entry, "META-INF", "WEB-INF")) { + continue; + } if(path.endsWith(SEPARATOR)) { getJSPMappings(servletContext, path); } From 1851f7046a8df4d24ae2badb4466a8659f11a970 Mon Sep 17 00:00:00 2001 From: idawda Date: Wed, 28 Aug 2024 16:37:30 +0530 Subject: [PATCH 27/44] add removeStart in StringUtils --- .../agent/security/schema/StringUtils.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/StringUtils.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/StringUtils.java index e9f8e89b3..cd35ce8d9 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/StringUtils.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/StringUtils.java @@ -1381,5 +1381,68 @@ public static boolean endsWithAny(final CharSequence sequence, final CharSequenc return false; } + /** + * Removes a char only if it is at the beginning of a source string, + * otherwise returns the source string. + * + *

A {@code null} source string will return {@code null}. + * An empty ("") source string will return the empty string. + * A {@code null} search char will return the source string.

+ * + *
+     * StringUtils.removeStart(null, *)      = null
+     * StringUtils.removeStart("", *)        = ""
+     * StringUtils.removeStart(*, null)      = *
+     * StringUtils.removeStart("/path", '/') = "path"
+     * StringUtils.removeStart("path", '/')  = "path"
+     * StringUtils.removeStart("path", 0)    = "path"
+     * 
+ * + * @param str the source String to search, may be null. + * @param remove the char to search for and remove. + * @return the substring with the char removed if found, + * {@code null} if null String input. + * @since 3.13.0 + */ + public static String removeStart(final String str, final char remove) { + if (isEmpty(str)) { + return str; + } + return str.charAt(0) == remove ? str.substring(1) : str; + } + + /** + * Removes a substring only if it is at the beginning of a source string, + * otherwise returns the source string. + * + *

A {@code null} source string will return {@code null}. + * An empty ("") source string will return the empty string. + * A {@code null} search string will return the source string.

+ * + *
+     * StringUtils.removeStart(null, *)      = null
+     * StringUtils.removeStart("", *)        = ""
+     * StringUtils.removeStart(*, null)      = *
+     * StringUtils.removeStart("www.domain.com", "www.")   = "domain.com"
+     * StringUtils.removeStart("domain.com", "www.")       = "domain.com"
+     * StringUtils.removeStart("www.domain.com", "domain") = "www.domain.com"
+     * StringUtils.removeStart("abc", "")    = "abc"
+     * 
+ * + * @param str the source String to search, may be null + * @param remove the String to search for and remove, may be null + * @return the substring with the string removed if found, + * {@code null} if null String input + * @since 2.1 + */ + public static String removeStart(final String str, final String remove) { + if (isEmpty(str) || isEmpty(remove)) { + return str; + } + if (str.startsWith(remove)) { + return str.substring(remove.length()); + } + return str; + } } From cfd9a05968d7bc3345135f08649a47e19a6797a7 Mon Sep 17 00:00:00 2001 From: idawda Date: Wed, 28 Aug 2024 19:20:16 +0530 Subject: [PATCH 28/44] NR-306872: Add test-identifier, process start time to websocket headers for CI/CD Support --- .../java/com/newrelic/agent/security/AgentConfig.java | 8 ++++++++ .../agent/security/intcodeagent/websocket/WSClient.java | 5 +++++ .../com/newrelic/agent/security/util/IUtilConstants.java | 1 + 3 files changed, 14 insertions(+) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index 84bda35e3..3625f5861 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -50,6 +50,8 @@ public class AgentConfig { private Map noticeErrorCustomParams = new HashMap<>(); + private String iastTestIdentifier; + private AgentConfig(){ } @@ -68,6 +70,8 @@ public void instantiate(){ logger = FileLoggerThreadPool.getInstance(); // Set required LogLevel logLevel = applyRequiredLogLevel(); + + iastTestIdentifier = NewRelic.getAgent().getConfig().getValue(IUtilConstants.IAST_TEST_IDENTIFIER); } private static final class InstanceHolder { @@ -224,4 +228,8 @@ public void setNRSecurityEnabled(boolean NRSecurityEnabled) { public String getSecurityHome() { return NR_CSEC_HOME; } + + public String getIastTestIdentifier() { + return iastTestIdentifier; + } } 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 338fb464d..bdf9e8b22 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 @@ -30,6 +30,7 @@ import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.management.ManagementFactory; import java.net.*; import java.nio.file.Files; import java.nio.file.Paths; @@ -152,6 +153,10 @@ private WSClient() throws URISyntaxException { this.addHeader("NR-CSEC-JSON-VERSION", AgentInfo.getInstance().getBuildInfo().getJsonVersion()); this.addHeader("NR-ACCOUNT-ID", AgentConfig.getInstance().getConfig().getCustomerInfo().getAccountId()); this.addHeader("NR-CSEC-IAST-DATA-TRANSFER-MODE", "PULL"); + if (AgentConfig.getInstance().getIastTestIdentifier() != null) { + this.addHeader("NR-CSEC-IAST-TEST-IDENTIFIER", AgentConfig.getInstance().getIastTestIdentifier()); + this.addHeader("NR-CSEC-PROCESS-START-TIME", String.valueOf(ManagementFactory.getRuntimeMXBean().getStartTime())); + } Proxy proxy = proxyManager(); if(proxy != null) { this.setProxy(proxy); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java index ebe2c6f28..0045c853d 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java @@ -24,6 +24,7 @@ public interface IUtilConstants { String NR_SECURITY_ENABLED = "security.enabled"; String NR_SECURITY_HOME_APP = "security.is_home_app"; + String IAST_TEST_IDENTIFIER = "security.iast_test_identifier"; String NR_SECURITY_CA_BUNDLE_PATH = "ca_bundle_path"; String NR_CSEC_DEBUG_LOGFILE_SIZE = "NR_CSEC_DEBUG_LOGFILE_SIZE"; From 1a98cb0dd151cab0b5362f35f7cc7fe820b038bb Mon Sep 17 00:00:00 2001 From: idawda Date: Thu, 29 Aug 2024 10:18:05 +0530 Subject: [PATCH 29/44] roundup the value for currentFetchThreshold --- .../httpclient/IASTDataTransferRequestProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 511ca2282..a1641ac4b 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 @@ -77,7 +77,7 @@ private void task() { return; } - int currentFetchThreshold = currentFetchThresholdPerMin/12; + int currentFetchThreshold = Math.round((float) currentFetchThresholdPerMin/12); if (currentFetchThreshold <= 0){ return; } From 794311744c98853695919f0e02048c11c4e48a66 Mon Sep 17 00:00:00 2001 From: idawda Date: Fri, 30 Aug 2024 10:36:02 +0530 Subject: [PATCH 30/44] remove dependency of start-time header on test-identifier header --- .../agent/security/intcodeagent/websocket/WSClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 bdf9e8b22..da32c5c62 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 @@ -155,8 +155,8 @@ private WSClient() throws URISyntaxException { this.addHeader("NR-CSEC-IAST-DATA-TRANSFER-MODE", "PULL"); if (AgentConfig.getInstance().getIastTestIdentifier() != null) { this.addHeader("NR-CSEC-IAST-TEST-IDENTIFIER", AgentConfig.getInstance().getIastTestIdentifier()); - this.addHeader("NR-CSEC-PROCESS-START-TIME", String.valueOf(ManagementFactory.getRuntimeMXBean().getStartTime())); } + this.addHeader("NR-CSEC-PROCESS-START-TIME", String.valueOf(ManagementFactory.getRuntimeMXBean().getStartTime())); Proxy proxy = proxyManager(); if(proxy != null) { this.setProxy(proxy); From 3ba7bdc5d14a0ddeb09cd4534b4b22cc49281629 Mon Sep 17 00:00:00 2001 From: idawda Date: Fri, 30 Aug 2024 12:51:22 +0530 Subject: [PATCH 31/44] Correct User Entity detection for gRPC --- .../main/java/io/grpc/ServerCallListener_Instrumentation.java | 3 +++ .../main/java/io/grpc/ServerCallListener_Instrumentation.java | 3 +++ .../main/java/io/grpc/ServerCallListener_Instrumentation.java | 3 +++ .../src/main/java/com/newrelic/api/agent/security/Agent.java | 1 + 4 files changed, 10 insertions(+) diff --git a/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java b/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java index 299f2885e..677671b37 100644 --- a/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java +++ b/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java @@ -7,6 +7,8 @@ import com.newrelic.api.agent.Token; import com.newrelic.api.agent.Trace; import com.newrelic.api.agent.security.NewRelicSecurity; +import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; +import com.newrelic.api.agent.security.schema.Framework; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.NewField; @@ -32,6 +34,7 @@ public void onMessage(ReqT message) { if (isLockAcquired) { GrpcUtils.preProcessSecurityHook(message, GrpcUtils.Type.REQUEST, descriptorForType.getFullName()); } + ServletHelper.registerUserLevelCode(Framework.GRPC.name()); try { Weaver.callOriginal(); } finally { diff --git a/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java b/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java index 5347df9c1..b1b4b49b0 100644 --- a/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java +++ b/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java @@ -7,6 +7,8 @@ import com.newrelic.api.agent.Token; import com.newrelic.api.agent.Trace; import com.newrelic.api.agent.security.NewRelicSecurity; +import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; +import com.newrelic.api.agent.security.schema.Framework; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.NewField; @@ -32,6 +34,7 @@ public void onMessage(ReqT message) { if (isLockAcquired) { GrpcUtils.preProcessSecurityHook(message, GrpcUtils.Type.REQUEST, descriptorForType.getFullName()); } + ServletHelper.registerUserLevelCode(Framework.GRPC.name()); try { Weaver.callOriginal(); } finally { diff --git a/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java b/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java index a26fb4170..406e6cca8 100644 --- a/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java +++ b/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/ServerCallListener_Instrumentation.java @@ -7,6 +7,8 @@ import com.newrelic.api.agent.Token; import com.newrelic.api.agent.Trace; import com.newrelic.api.agent.security.NewRelicSecurity; +import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; +import com.newrelic.api.agent.security.schema.Framework; import com.newrelic.api.agent.security.schema.SecurityMetaData; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.NewField; @@ -32,6 +34,7 @@ public void onMessage(ReqT message) { if (isLockAcquired) { GrpcUtils.preProcessSecurityHook(message, GrpcUtils.Type.REQUEST, descriptorForType.getFullName()); } + ServletHelper.registerUserLevelCode(Framework.GRPC.name()); try { Weaver.callOriginal(); } finally { 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 f0241ac02..dc65e8bd6 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 @@ -519,6 +519,7 @@ private UserClassEntity setUserClassEntity(AbstractOperation operation, Security } switch (framework){ case "vertx-web": + case "GRPC": if(i-1 >= 0) { userClassEntity = setUserClassEntityForVertx(operation, userStackTraceElement, userClassEntity, securityMetaData.getMetaData().isUserLevelServiceMethodEncountered(), i); if(userClassEntity.getUserClassElement() != null){ From 721ed8e12c5777f3ddb8792e6619dc9cf8516acf Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Mon, 2 Sep 2024 13:32:46 +0530 Subject: [PATCH 32/44] agent version bump 1.4.2 json version bump to 1.2.7 add procStartTime & scanStartTime to HealthCheck --- gradle.properties | 4 ++-- .../IASTDataTransferRequestProcessor.java | 10 ++++++++ .../models/javaagent/JAHealthCheck.java | 24 +++++++++++++++++++ .../agent/security/util/IUtilConstants.java | 2 +- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 9cf70671d..79ca433d4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # The agent version. -agentVersion=1.4.1 -jsonVersion=1.2.6 +agentVersion=1.4.2 +jsonVersion=1.2.7 # Updated exposed NR APM API version. nrAPIVersion=8.12.0 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 a1641ac4b..5c253beec 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 @@ -49,6 +49,8 @@ public class IASTDataTransferRequestProcessor { private int currentFetchThresholdPerMin = 3600; + private long scanStartEpochMilli = 0; + private void task() { IASTDataTransferRequest request = null; try { @@ -67,6 +69,10 @@ private void task() { } } long currentTimestamp = Instant.now().toEpochMilli(); + if(scanStartEpochMilli <= 0){ + AgentInfo.getInstance().getJaHealthCheck().setScanStartTime(currentTimestamp); + scanStartEpochMilli = currentTimestamp; + } // Sleep if under cooldown long cooldownSleepTime = cooldownTillTimestamp.get() - currentTimestamp; if(cooldownSleepTime > 0) { @@ -197,4 +203,8 @@ public void setCooldownTillTimestamp(long timestamp) { public void setLastFuzzCCTimestamp(long timestamp) { lastFuzzCCTimestamp.set(timestamp); } + + public long getScanStartEpochMilli() { + return scanStartEpochMilli; + } } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java index 7eb7f024b..57fb764ae 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java @@ -5,6 +5,7 @@ import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.agent.security.intcodeagent.websocket.JsonConverter; +import java.lang.management.ManagementFactory; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -18,6 +19,10 @@ public class JAHealthCheck extends AgentBasicInfo { // private Set protectedDB; + private long procStartTime; + + private long scanStartTime; + private AtomicInteger invokedHookCount; private IdentifierEnvs kind; @@ -45,6 +50,7 @@ public JAHealthCheck(String applicationUUID) { this.serviceStatus = new HashMap<>(); this.eventStats = new EventStats(); this.setKind(AgentInfo.getInstance().getApplicationInfo().getIdentifier().getKind()); + this.procStartTime = ManagementFactory.getRuntimeMXBean().getStartTime(); logger.log(LogLevel.INFO, String.format(HC_CREATED, JsonConverter.toJSON(this)), JAHealthCheck.class.getName()); } @@ -59,6 +65,8 @@ public JAHealthCheck(JAHealthCheck jaHealthCheck) { this.schedulerRuns = new SchedulerRuns(jaHealthCheck.schedulerRuns); this.invokedHookCount = new AtomicInteger(jaHealthCheck.invokedHookCount.get()); this.webSocketConnectionStats = new WebSocketConnectionStats(jaHealthCheck.webSocketConnectionStats); + this.procStartTime = jaHealthCheck.getProcStartTime(); + this.scanStartTime = jaHealthCheck.getScanStartTime(); logger.log(LogLevel.INFO, String.format(HC_CREATED, JsonConverter.toJSON(this)), JAHealthCheck.class.getName()); } @@ -133,6 +141,22 @@ public void setSchedulerRuns(SchedulerRuns schedulerRuns) { this.schedulerRuns = schedulerRuns; } + public long getProcStartTime() { + return procStartTime; + } + + public void setProcStartTime(long procStartTime) { + this.procStartTime = procStartTime; + } + + public long getScanStartTime() { + return scanStartTime; + } + + public void setScanStartTime(long scanStartTime) { + this.scanStartTime = scanStartTime; + } + public void reset(){ this.setInvokedHookCount(0); this.stats.clear(); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java index 0589266cd..d04d53cc7 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java @@ -12,7 +12,7 @@ public interface IUtilConstants { String SCAN_TIME_SCHEDULE = "security.scan_schedule.schedule"; String SCAN_TIME_DURATION = "security.scan_schedule.duration"; String SCAN_TIME_COLLECT_SAMPLES = "security.scan_schedule.always_sample_traces"; - String SCAN_REQUEST_RATE_LIMIT = "security.scan_request_rate_limit"; + String SCAN_REQUEST_RATE_LIMIT = "security.scan_controllers.iast_scan_request_rate_limit"; String SKIP_IAST_SCAN = "security.exclude_from_iast_scan"; String SKIP_IAST_SCAN_API = SKIP_IAST_SCAN + ".api"; From 339ee15eac844e88521005ed7d45078f804ed9cf Mon Sep 17 00:00:00 2001 From: idawda Date: Mon, 2 Sep 2024 16:42:27 +0530 Subject: [PATCH 33/44] Route detection support for gRPC --- .../grpc/internal/ServerImpl_Instrumentation.java | 13 +++++++++++++ .../grpc/internal/ServerImpl_Instrumentation.java | 13 +++++++++++++ .../grpc/internal/ServerImpl_Instrumentation.java | 13 +++++++++++++ 3 files changed, 39 insertions(+) diff --git a/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java b/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java index e1bc40df9..5b543db04 100644 --- a/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java +++ b/instrumentation-security/grpc-1.22.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java @@ -8,8 +8,13 @@ package io.grpc.internal; import com.newrelic.agent.security.instrumentation.grpc1220.GrpcServerUtils; +import com.newrelic.agent.security.instrumentation.grpc1220.GrpcUtils; import com.newrelic.agent.security.instrumentation.grpc1220.processor.MonitorGrpcRequestQueueThread; import com.newrelic.api.agent.NewRelic; +import com.newrelic.api.agent.security.NewRelicSecurity; +import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.schema.Framework; +import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; import io.grpc.Context; @@ -29,6 +34,14 @@ private ServerStreamListener startCall(ServerStream_Instrumentatio stream.tokenForCsec = NewRelic.getAgent().getTransaction().getToken(); MonitorGrpcRequestQueueThread.submitNewTask(); boolean isLockAcquired = GrpcServerUtils.acquireLockIfPossible(); + try { + if (NewRelicSecurity.isHookProcessingActive()){ + NewRelicSecurity.getAgent().getSecurityMetaData().getRequest().setRoute(methodDef.getMethodDescriptor().getFullMethodName()); + NewRelicSecurity.getAgent().getSecurityMetaData().getMetaData().setFramework(Framework.GRPC); + } + } catch (Exception e) { + NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_GETTING_ROUTE_FOR_INCOMING_REQUEST, GrpcUtils.GRPC_1_22_0, e.getMessage()), e, this.getClass().getName()); + } if (isLockAcquired) { GrpcServerUtils.preprocessSecurityHook(stream, methodDef, headers, this.getClass().getName()); } diff --git a/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java b/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java index b4228c8d3..a65812d3a 100644 --- a/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java +++ b/instrumentation-security/grpc-1.4.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java @@ -8,8 +8,13 @@ package io.grpc.internal; import com.newrelic.agent.security.instrumentation.grpc140.GrpcServerUtils; +import com.newrelic.agent.security.instrumentation.grpc140.GrpcUtils; import com.newrelic.agent.security.instrumentation.grpc140.processor.MonitorGrpcRequestQueueThread; import com.newrelic.api.agent.NewRelic; +import com.newrelic.api.agent.security.NewRelicSecurity; +import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.schema.Framework; +import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; import io.grpc.Context; @@ -28,6 +33,14 @@ private ServerStreamListener startCall(ServerStream_Instrumentatio stream.tokenForCsec = NewRelic.getAgent().getTransaction().getToken(); MonitorGrpcRequestQueueThread.submitNewTask(); boolean isLockAcquired = GrpcServerUtils.acquireLockIfPossible(); + try { + if (NewRelicSecurity.isHookProcessingActive()){ + NewRelicSecurity.getAgent().getSecurityMetaData().getRequest().setRoute(methodDef.getMethodDescriptor().getFullMethodName()); + NewRelicSecurity.getAgent().getSecurityMetaData().getMetaData().setFramework(Framework.GRPC); + } + } catch (Exception e){ + NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_GETTING_ROUTE_FOR_INCOMING_REQUEST, GrpcUtils.GRPC_1_4_0, e.getMessage()), e, this.getClass().getName()); + } if (isLockAcquired) { GrpcServerUtils.preprocessSecurityHook(stream, methodDef, headers, this.getClass().getName()); } diff --git a/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java b/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java index f3e5ffaf1..a3d94e077 100644 --- a/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java +++ b/instrumentation-security/grpc-1.40.0/src/main/java/io/grpc/internal/ServerImpl_Instrumentation.java @@ -1,8 +1,13 @@ package io.grpc.internal; import com.newrelic.agent.security.instrumentation.grpc1400.GrpcServerUtils; +import com.newrelic.agent.security.instrumentation.grpc1400.GrpcUtils; import com.newrelic.agent.security.instrumentation.grpc1400.processor.MonitorGrpcRequestQueueThread; import com.newrelic.api.agent.NewRelic; +import com.newrelic.api.agent.security.NewRelicSecurity; +import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.schema.Framework; +import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.api.agent.weaver.NewField; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; @@ -28,6 +33,14 @@ private void streamCreatedInternal(final ServerStream stream, final String metho private ServerMethodDefinition wrapMethod(ServerStream_Instrumentation stream, ServerMethodDefinition methodDef, StatsTraceContext statsTraceCtx) { stream.tokenForCsec = NewRelic.getAgent().getTransaction().getToken(); boolean isLockAcquired = GrpcServerUtils.acquireLockIfPossible(); + try { + if (NewRelicSecurity.isHookProcessingActive()){ + NewRelicSecurity.getAgent().getSecurityMetaData().getRequest().setRoute(methodDef.getMethodDescriptor().getFullMethodName()); + NewRelicSecurity.getAgent().getSecurityMetaData().getMetaData().setFramework(Framework.GRPC); + } + } catch (Exception e) { + NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_GETTING_ROUTE_FOR_INCOMING_REQUEST, GrpcUtils.GRPC_1_40_0, e.getMessage()), e, this.getClass().getName()); + } if (isLockAcquired) { GrpcServerUtils.preprocessSecurityHook(stream, methodDef, headers, this.getClass().getName()); } From 5ffd62ded99a3dac571f3c47b185bfb32c02c5ae Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Mon, 2 Sep 2024 18:15:04 +0530 Subject: [PATCH 34/44] set scan start time on every NR IAST trigger --- .../src/main/java/com/newrelic/api/agent/security/Agent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3aa31e43d..444b9bb0b 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 @@ -279,7 +279,7 @@ private void startSecurityServices() { } else { IASTDataTransferRequestProcessor.getInstance().stopDataRequestSchedule(true); } - + AgentInfo.getInstance().getJaHealthCheck().setScanStartTime(IASTDataTransferRequestProcessor.getInstance().getScanStartEpochMilli()); } @Override From 57be1b64184ab2c34a2280867820100492a0d123 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Tue, 3 Sep 2024 12:47:52 +0530 Subject: [PATCH 35/44] New Requirements Enhancing Health Checks with State Information --- .../IASTDataTransferRequestProcessor.java | 14 ++--- .../ControlCommandProcessor.java | 4 ++ .../ControlCommandProcessorThreadPool.java | 9 +++ .../models/javaagent/JAHealthCheck.java | 63 +++++++++++++++++-- .../newrelic/api/agent/security/Agent.java | 9 ++- 5 files changed, 86 insertions(+), 13 deletions(-) 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 5c253beec..b6ae89e8d 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 @@ -3,7 +3,6 @@ import com.newrelic.agent.security.AgentConfig; import com.newrelic.agent.security.AgentInfo; import com.newrelic.agent.security.instrumentator.utils.INRSettingsKey; -import com.newrelic.agent.security.intcodeagent.exceptions.RestrictionModeException; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.agent.security.util.IUtilConstants; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -49,7 +48,7 @@ public class IASTDataTransferRequestProcessor { private int currentFetchThresholdPerMin = 3600; - private long scanStartEpochMilli = 0; + private long controlCommandRequestedAtEpochMilli = 0; private void task() { IASTDataTransferRequest request = null; @@ -69,9 +68,10 @@ private void task() { } } long currentTimestamp = Instant.now().toEpochMilli(); - if(scanStartEpochMilli <= 0){ - AgentInfo.getInstance().getJaHealthCheck().setScanStartTime(currentTimestamp); - scanStartEpochMilli = currentTimestamp; + if(controlCommandRequestedAtEpochMilli <= 0){ + AgentInfo.getInstance().getJaHealthCheck().setControlCommandRequestedAt(currentTimestamp); + controlCommandRequestedAtEpochMilli = currentTimestamp; + AgentInfo.getInstance().getJaHealthCheck().setScanActive(true); } // Sleep if under cooldown long cooldownSleepTime = cooldownTillTimestamp.get() - currentTimestamp; @@ -204,7 +204,7 @@ public void setLastFuzzCCTimestamp(long timestamp) { lastFuzzCCTimestamp.set(timestamp); } - public long getScanStartEpochMilli() { - return scanStartEpochMilli; + public long getControlCommandRequestedAtEpochMilli() { + return controlCommandRequestedAtEpochMilli; } } 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 6679724f0..033913645 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 @@ -177,6 +177,10 @@ public void run() { iastReplayRequestMsgReceiveTime = Instant.now(); IASTDataTransferRequestProcessor.getInstance().setLastFuzzCCTimestamp(Instant.now().toEpochMilli()); RestRequestProcessor.processControlCommand(controlCommand); + if(ControlCommandProcessorThreadPool.getInstance().getScanStartTime() <= 0) { + ControlCommandProcessorThreadPool.getInstance().setScanStartTime(Instant.now().toEpochMilli()); + AgentInfo.getInstance().getJaHealthCheck().setScanStartTime(ControlCommandProcessorThreadPool.getInstance().getScanStartTime()); + } break; case IntCodeControlCommand.STARTUP_WELCOME_MSG: diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessorThreadPool.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessorThreadPool.java index badd1c22a..0b432f3d9 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessorThreadPool.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/controlcommand/ControlCommandProcessorThreadPool.java @@ -27,6 +27,8 @@ public class ControlCommandProcessorThreadPool { private final boolean allowCoreThreadTimeOut = false; private static Object mutex = new Object(); + private long scanStartTime = 0; + public ThreadPoolExecutor getExecutor() { return executor; } @@ -157,4 +159,11 @@ public void shutDownThreadPoolExecutor() { } } + public long getScanStartTime() { + return scanStartTime; + } + + public void setScanStartTime(long scanStartTime) { + this.scanStartTime = scanStartTime; + } } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java index 57fb764ae..235b63e6a 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java @@ -1,11 +1,13 @@ package com.newrelic.agent.security.intcodeagent.models.javaagent; +import com.newrelic.agent.security.AgentConfig; import com.newrelic.agent.security.AgentInfo; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.agent.security.intcodeagent.websocket.JsonConverter; import java.lang.management.ManagementFactory; +import java.time.Instant; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -15,14 +17,20 @@ public class JAHealthCheck extends AgentBasicInfo { private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); private static final String HC_CREATED = "Created Health Check: %s"; -// private String protectedServer; - -// private Set protectedDB; - private long procStartTime; + private long controlCommandRequestedAt; + private long scanStartTime; + private long trafficStartedAt; + + private final long csecActivationTime; + + private final long iastActivationTime; + + private Boolean scanActive = false; + private AtomicInteger invokedHookCount; private IdentifierEnvs kind; @@ -51,6 +59,16 @@ public JAHealthCheck(String applicationUUID) { this.eventStats = new EventStats(); this.setKind(AgentInfo.getInstance().getApplicationInfo().getIdentifier().getKind()); this.procStartTime = ManagementFactory.getRuntimeMXBean().getStartTime(); + if(AgentConfig.getInstance().getAgentMode().getScanSchedule().getNextScanTime() != null) { + this.csecActivationTime = AgentConfig.getInstance().getAgentMode().getScanSchedule().getNextScanTime().getTime(); + } else { + this.csecActivationTime = Instant.now().toEpochMilli(); + } + if(AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime() != null) { + this.iastActivationTime = AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime().getTime(); + } else { + this.iastActivationTime = Instant.now().toEpochMilli(); + } logger.log(LogLevel.INFO, String.format(HC_CREATED, JsonConverter.toJSON(this)), JAHealthCheck.class.getName()); } @@ -66,7 +84,12 @@ public JAHealthCheck(JAHealthCheck jaHealthCheck) { this.invokedHookCount = new AtomicInteger(jaHealthCheck.invokedHookCount.get()); this.webSocketConnectionStats = new WebSocketConnectionStats(jaHealthCheck.webSocketConnectionStats); this.procStartTime = jaHealthCheck.getProcStartTime(); + this.controlCommandRequestedAt = jaHealthCheck.getControlCommandRequestedAt(); this.scanStartTime = jaHealthCheck.getScanStartTime(); + this.trafficStartedAt = jaHealthCheck.getTrafficStartedAt(); + this.csecActivationTime = jaHealthCheck.getCsecActivationTime(); + this.iastActivationTime = jaHealthCheck.getIastActivationTime(); + this.scanActive = jaHealthCheck.getScanActive(); logger.log(LogLevel.INFO, String.format(HC_CREATED, JsonConverter.toJSON(this)), JAHealthCheck.class.getName()); } @@ -149,6 +172,14 @@ public void setProcStartTime(long procStartTime) { this.procStartTime = procStartTime; } + public long getControlCommandRequestedAt() { + return controlCommandRequestedAt; + } + + public void setControlCommandRequestedAt(long controlCommandRequestedAt) { + this.controlCommandRequestedAt = controlCommandRequestedAt; + } + public long getScanStartTime() { return scanStartTime; } @@ -157,6 +188,30 @@ public void setScanStartTime(long scanStartTime) { this.scanStartTime = scanStartTime; } + public long getTrafficStartedAt() { + return trafficStartedAt; + } + + public void setTrafficStartedAt(long trafficStartedAt) { + this.trafficStartedAt = trafficStartedAt; + } + + public long getCsecActivationTime() { + return csecActivationTime; + } + + public Boolean getScanActive() { + return scanActive; + } + + public void setScanActive(Boolean scanActive) { + this.scanActive = scanActive; + } + + public long getIastActivationTime() { + return iastActivationTime; + } + public void reset(){ this.setInvokedHookCount(0); this.stats.clear(); 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 444b9bb0b..9ce8a5f02 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 @@ -15,7 +15,6 @@ import com.newrelic.agent.security.intcodeagent.exceptions.RestrictionModeException; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.agent.security.intcodeagent.filelogging.LogFileHelper; -import com.newrelic.agent.security.intcodeagent.models.collectorconfig.AgentMode; import com.newrelic.agent.security.intcodeagent.models.javaagent.*; import com.newrelic.agent.security.intcodeagent.utils.*; import com.newrelic.api.agent.security.instrumentation.helpers.*; @@ -62,6 +61,7 @@ public class Agent implements SecurityAgent { public static final String DROPPING_EVENT_AS_IT_WAS_GENERATED_BY_K_2_INTERNAL_API_CALL = "Dropping event as it was generated by agent internal API call : "; private static final AtomicBoolean firstEventProcessed = new AtomicBoolean(false); + private long trafficStartedAt = 0; public static final String ERROR_WHILE_GENERATING_TRACE_ID_FOR_CATEGORY_S = "Error while generating trace id for category : %s"; public static final String SKIPPING_THE_API_S_AS_IT_IS_PART_OF_THE_SKIP_SCAN_LIST = "Skipping the API %s as it is part of the skip scan list"; public static final String INVALID_CRON_EXPRESSION_PROVIDED_FOR_IAST_RESTRICTED_MODE = "Invalid cron expression provided for IAST Mode"; @@ -261,6 +261,7 @@ private void startSecurityServices() { ); WSReconnectionST.getInstance().submitNewTaskSchedule(0); EventSendPool.getInstance(); + ControlCommandProcessorThreadPool.getInstance(); logger.logInit( LogLevel.INFO, String.format(STARTED_MODULE_LOG, AgentServices.EventWritePool.name()), @@ -279,7 +280,8 @@ private void startSecurityServices() { } else { IASTDataTransferRequestProcessor.getInstance().stopDataRequestSchedule(true); } - AgentInfo.getInstance().getJaHealthCheck().setScanStartTime(IASTDataTransferRequestProcessor.getInstance().getScanStartEpochMilli()); + AgentInfo.getInstance().getJaHealthCheck().setControlCommandRequestedAt(IASTDataTransferRequestProcessor.getInstance().getControlCommandRequestedAtEpochMilli()); + AgentInfo.getInstance().getJaHealthCheck().setScanStartTime(ControlCommandProcessorThreadPool.getInstance().getScanStartTime()); } @Override @@ -344,6 +346,7 @@ private void deactivateSecurityServices(){ */ // InstrumentationUtils.shutdownLogic(); IASTDataTransferRequestProcessor.getInstance().stopDataRequestSchedule(true); + info.getJaHealthCheck().setScanActive(false); if(!config.getAgentMode().getScanSchedule().isCollectSamples()) { AgentInfo.getInstance().setAgentActive(false); HealthCheckScheduleThread.getInstance().cancelTask(true); @@ -468,6 +471,8 @@ public void registerOperation(AbstractOperation operation) { String.format(EVENT_ZERO_PROCESSED, securityMetaData.getRequest()), this.getClass().getName()); firstEventProcessed.set(true); + trafficStartedAt = Instant.now().toEpochMilli(); + AgentInfo.getInstance().getJaHealthCheck().setTrafficStartedAt(trafficStartedAt); } } } From 30801b7bf3a4370fed04c0774d27ea6f8c6dbede Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Tue, 3 Sep 2024 17:55:30 +0530 Subject: [PATCH 36/44] rename fields according to NR-308822 --- .../IASTDataTransferRequestProcessor.java | 2 +- .../models/javaagent/JAHealthCheck.java | 36 +++++++++---------- .../newrelic/api/agent/security/Agent.java | 4 +-- 3 files changed, 21 insertions(+), 21 deletions(-) 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 b6ae89e8d..d2221a522 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 @@ -69,7 +69,7 @@ private void task() { } long currentTimestamp = Instant.now().toEpochMilli(); if(controlCommandRequestedAtEpochMilli <= 0){ - AgentInfo.getInstance().getJaHealthCheck().setControlCommandRequestedAt(currentTimestamp); + AgentInfo.getInstance().getJaHealthCheck().setControlCommandRequestedTime(currentTimestamp); controlCommandRequestedAtEpochMilli = currentTimestamp; AgentInfo.getInstance().getJaHealthCheck().setScanActive(true); } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java index 235b63e6a..cd926be52 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/models/javaagent/JAHealthCheck.java @@ -19,15 +19,15 @@ public class JAHealthCheck extends AgentBasicInfo { private long procStartTime; - private long controlCommandRequestedAt; + private long controlCommandRequestedTime; private long scanStartTime; - private long trafficStartedAt; + private long trafficStartedTime; private final long csecActivationTime; - private final long iastActivationTime; + private final long iastDataRequestTime; private Boolean scanActive = false; @@ -65,9 +65,9 @@ public JAHealthCheck(String applicationUUID) { this.csecActivationTime = Instant.now().toEpochMilli(); } if(AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime() != null) { - this.iastActivationTime = AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime().getTime(); + this.iastDataRequestTime = AgentConfig.getInstance().getAgentMode().getScanSchedule().getDataCollectionTime().getTime(); } else { - this.iastActivationTime = Instant.now().toEpochMilli(); + this.iastDataRequestTime = Instant.now().toEpochMilli(); } logger.log(LogLevel.INFO, String.format(HC_CREATED, JsonConverter.toJSON(this)), JAHealthCheck.class.getName()); } @@ -84,11 +84,11 @@ public JAHealthCheck(JAHealthCheck jaHealthCheck) { this.invokedHookCount = new AtomicInteger(jaHealthCheck.invokedHookCount.get()); this.webSocketConnectionStats = new WebSocketConnectionStats(jaHealthCheck.webSocketConnectionStats); this.procStartTime = jaHealthCheck.getProcStartTime(); - this.controlCommandRequestedAt = jaHealthCheck.getControlCommandRequestedAt(); + this.controlCommandRequestedTime = jaHealthCheck.getControlCommandRequestedTime(); this.scanStartTime = jaHealthCheck.getScanStartTime(); - this.trafficStartedAt = jaHealthCheck.getTrafficStartedAt(); + this.trafficStartedTime = jaHealthCheck.getTrafficStartedTime(); this.csecActivationTime = jaHealthCheck.getCsecActivationTime(); - this.iastActivationTime = jaHealthCheck.getIastActivationTime(); + this.iastDataRequestTime = jaHealthCheck.getIastDataRequestTime(); this.scanActive = jaHealthCheck.getScanActive(); logger.log(LogLevel.INFO, String.format(HC_CREATED, JsonConverter.toJSON(this)), JAHealthCheck.class.getName()); } @@ -172,12 +172,12 @@ public void setProcStartTime(long procStartTime) { this.procStartTime = procStartTime; } - public long getControlCommandRequestedAt() { - return controlCommandRequestedAt; + public long getControlCommandRequestedTime() { + return controlCommandRequestedTime; } - public void setControlCommandRequestedAt(long controlCommandRequestedAt) { - this.controlCommandRequestedAt = controlCommandRequestedAt; + public void setControlCommandRequestedTime(long controlCommandRequestedTime) { + this.controlCommandRequestedTime = controlCommandRequestedTime; } public long getScanStartTime() { @@ -188,12 +188,12 @@ public void setScanStartTime(long scanStartTime) { this.scanStartTime = scanStartTime; } - public long getTrafficStartedAt() { - return trafficStartedAt; + public long getTrafficStartedTime() { + return trafficStartedTime; } - public void setTrafficStartedAt(long trafficStartedAt) { - this.trafficStartedAt = trafficStartedAt; + public void setTrafficStartedTime(long trafficStartedTime) { + this.trafficStartedTime = trafficStartedTime; } public long getCsecActivationTime() { @@ -208,8 +208,8 @@ public void setScanActive(Boolean scanActive) { this.scanActive = scanActive; } - public long getIastActivationTime() { - return iastActivationTime; + public long getIastDataRequestTime() { + return iastDataRequestTime; } public void reset(){ 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 9ce8a5f02..398e61f30 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 @@ -280,7 +280,7 @@ private void startSecurityServices() { } else { IASTDataTransferRequestProcessor.getInstance().stopDataRequestSchedule(true); } - AgentInfo.getInstance().getJaHealthCheck().setControlCommandRequestedAt(IASTDataTransferRequestProcessor.getInstance().getControlCommandRequestedAtEpochMilli()); + AgentInfo.getInstance().getJaHealthCheck().setControlCommandRequestedTime(IASTDataTransferRequestProcessor.getInstance().getControlCommandRequestedAtEpochMilli()); AgentInfo.getInstance().getJaHealthCheck().setScanStartTime(ControlCommandProcessorThreadPool.getInstance().getScanStartTime()); } @@ -472,7 +472,7 @@ public void registerOperation(AbstractOperation operation) { this.getClass().getName()); firstEventProcessed.set(true); trafficStartedAt = Instant.now().toEpochMilli(); - AgentInfo.getInstance().getJaHealthCheck().setTrafficStartedAt(trafficStartedAt); + AgentInfo.getInstance().getJaHealthCheck().setTrafficStartedTime(trafficStartedAt); } } } From d1f12e530fcfa50323a994dfd688a8fbbeec7f20 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Fri, 6 Sep 2024 17:38:02 +0530 Subject: [PATCH 37/44] Cleanup IAST data collection locks --- .../processor/GrpcRequestThreadPool.java | 6 ------ .../processor/GrpcRequestThreadPool.java | 6 ------ .../processor/GrpcRequestThreadPool.java | 6 ------ .../IASTDataTransferRequestProcessor.java | 19 +++++++++-------- .../httpclient/RestRequestProcessor.java | 14 ++++++------- .../httpclient/RestRequestThreadPool.java | 6 ------ .../ControlCommandProcessor.java | 21 +------------------ .../intcodeagent/logging/IAgentConstants.java | 1 + .../intcodeagent/websocket/EventSendPool.java | 6 ------ .../intcodeagent/websocket/EventSender.java | 7 ------- .../GrpcClientRequestReplayHelper.java | 5 ----- 11 files changed, 19 insertions(+), 78 deletions(-) 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..b20081e13 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 @@ -35,8 +35,6 @@ public class GrpcRequestThreadPool { private final boolean allowCoreThreadTimeOut = false; private static final Object mutex = new Object(); - private static final AtomicBoolean isWaiting = new AtomicBoolean(false); - private GrpcRequestThreadPool() { LinkedBlockingQueue processQueue; // load the settings @@ -136,10 +134,6 @@ public BlockingQueue getQueue() { return this.executor.getQueue(); } - public AtomicBoolean isWaiting() { - return isWaiting; - } - public ThreadPoolExecutor getExecutor() { return executor; } 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..32e8eec98 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 @@ -35,8 +35,6 @@ public class GrpcRequestThreadPool { private final boolean allowCoreThreadTimeOut = false; private static final Object mutex = new Object(); - private static final AtomicBoolean isWaiting = new AtomicBoolean(false); - private GrpcRequestThreadPool() { LinkedBlockingQueue processQueue; // load the settings @@ -136,10 +134,6 @@ public BlockingQueue getQueue() { return this.executor.getQueue(); } - public AtomicBoolean isWaiting() { - return isWaiting; - } - public ThreadPoolExecutor getExecutor() { return executor; } 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..de3b95a28 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 @@ -33,8 +33,6 @@ public class GrpcRequestThreadPool { private final boolean allowCoreThreadTimeOut = false; private static final Object mutex = new Object(); - private static final AtomicBoolean isWaiting = new AtomicBoolean(false); - private GrpcRequestThreadPool() { LinkedBlockingQueue processQueue; // load the settings @@ -134,10 +132,6 @@ public BlockingQueue getQueue() { return this.executor.getQueue(); } - public AtomicBoolean isWaiting() { - return isWaiting; - } - public ThreadPoolExecutor getExecutor() { return executor; } 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 d2221a522..4832c2412 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 @@ -54,19 +54,20 @@ private void task() { IASTDataTransferRequest request = null; try { if(!AgentUsageMetric.isIASTRequestProcessingActive()){ + logger.log(LogLevel.FINER, "IAST request processing deactivated for the moment.", IASTDataTransferRequestProcessor.class.getName()); return; } - if (WSUtils.getInstance().isReconnecting() || - !WSClient.getInstance().isOpen()) { - synchronized (WSUtils.getInstance()) { - RestRequestThreadPool.getInstance().isWaiting().set(true); - GrpcClientRequestReplayHelper.getInstance().isWaiting().set(true); - WSUtils.getInstance().wait(); - RestRequestThreadPool.getInstance().isWaiting().set(false); - GrpcClientRequestReplayHelper.getInstance().isWaiting().set(false); - } + if (!WSClient.getInstance().isOpen()) { + logger.log(LogLevel.FINER, "IAST request processing deactivated due to websocket connection status.", IASTDataTransferRequestProcessor.class.getName()); + return; + } + + if(WSUtils.getInstance().isReconnecting()) { + logger.log(LogLevel.FINER, "IAST request processing deactivated due to SE requested for reconnection..", IASTDataTransferRequestProcessor.class.getName()); + return; } + long currentTimestamp = Instant.now().toEpochMilli(); if(controlCommandRequestedAtEpochMilli <= 0){ AgentInfo.getInstance().getJaHealthCheck().setControlCommandRequestedTime(currentTimestamp); 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 1baa1d69a..618d33a0f 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 @@ -41,6 +41,9 @@ public class RestRequestProcessor implements Callable { public static final String JSON_PARSING_ERROR_WHILE_PROCESSING_FUZZING_REQUEST_S = "JSON parsing error while processing fuzzing request : %s"; private static final int MAX_REPETITION = 3; public static final String ENDPOINT_LOCALHOST_S = "%s://localhost:%s"; + private static final String IAST_REQUEST_HAS_NO_ARGUMENTS = "IAST request has no arguments : %s"; + public static final String AGENT_IS_NOT_ACTIVE = "Agent is not active"; + public static final String WS_RECONNECTING = "Websocket reconnecting failing for control command id: %s"; private IntCodeControlCommand controlCommand; private int repeatCount; @@ -61,22 +64,19 @@ public RestRequestProcessor(IntCodeControlCommand controlCommand, int repeatCoun @Override public Boolean call() throws InterruptedException { if (controlCommand.getArguments().size() < 2 ) { + logger.log(LogLevel.FINER, String.format(IAST_REQUEST_HAS_NO_ARGUMENTS, controlCommand.getId()), RestRequestProcessor.class.getSimpleName()); return true; } if( !AgentInfo.getInstance().isAgentActive()) { + logger.log(LogLevel.FINER, AGENT_IS_NOT_ACTIVE, RestRequestProcessor.class.getSimpleName()); return false; } FuzzRequestBean httpRequest = null; try { if (WSUtils.getInstance().isReconnecting()) { - synchronized (WSUtils.getInstance()) { - RestRequestThreadPool.getInstance().isWaiting().set(true); - GrpcClientRequestReplayHelper.getInstance().isWaiting().set(true); - WSUtils.getInstance().wait(); - RestRequestThreadPool.getInstance().isWaiting().set(false); - GrpcClientRequestReplayHelper.getInstance().isWaiting().set(false); - } + logger.log(LogLevel.FINER, String.format(WS_RECONNECTING, controlCommand.getId()), RestRequestProcessor.class.getSimpleName()); + return false; } String req = StringUtils.replace(controlCommand.getArguments().get(0), NR_CSEC_VALIDATOR_HOME_TMP, OsVariablesInstance.getInstance().getOsVariables().getTmpDirectory()); req = StringUtils.replace(req, NR_CSEC_VALIDATOR_HOME_TMP_URL_ENCODED, CallbackUtils.urlEncode(OsVariablesInstance.getInstance().getOsVariables().getTmpDirectory())); 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..e57670be6 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 @@ -29,8 +29,6 @@ public class RestRequestThreadPool { private final TimeUnit timeUnit = TimeUnit.SECONDS; private final boolean allowCoreThreadTimeOut = false; - private static final AtomicBoolean isWaiting = new AtomicBoolean(false); - private final Map> processedIds = new ConcurrentHashMap(); private final Set pendingIds = ConcurrentHashMap.newKeySet(); @@ -128,10 +126,6 @@ public BlockingQueue getQueue() { return this.executor.getQueue(); } - public AtomicBoolean isWaiting() { - return isWaiting; - } - public ThreadPoolExecutor getExecutor() { return executor; } 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 033913645..e18da9551 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 @@ -226,28 +226,9 @@ public void run() { */ try { AgentInfo.getInstance().getJaHealthCheck().getWebSocketConnectionStats().incrementReceivedReconnectAtWill(); + WSUtils.getInstance().setReconnecting(true); //TODO no need for draining IAST since last leg has complete ledger. logger.log(LogLevel.INFO, RECEIVED_WS_RECONNECT_COMMAND_FROM_SERVER_INITIATING_SEQUENCE, this.getClass().getName()); - if (NewRelicSecurity.getAgent().getCurrentPolicy().getVulnerabilityScan().getEnabled() && - NewRelicSecurity.getAgent().getCurrentPolicy().getVulnerabilityScan().getIastScan().getEnabled() - ) { - WSUtils.getInstance().setReconnecting(true); - while (EventSendPool.getInstance().getExecutor().getActiveCount() > 0 && !EventSendPool.getInstance().isWaiting().get()) { - Thread.sleep(100); - } - logger.log(LogLevel.FINER, WS_RECONNECT_EVENT_SEND_POOL_DRAINED, this.getClass().getName()); - - while (RestRequestThreadPool.getInstance().getExecutor().getActiveCount() > 0 && !RestRequestThreadPool.getInstance().isWaiting().get()) { - Thread.sleep(100); - } - logger.log(LogLevel.FINER, String.format("Request = %s, in process = %s", GrpcClientRequestReplayHelper.getInstance().getRequestQueue().size(), GrpcClientRequestReplayHelper.getInstance().getInProcessRequestQueue().size()), this.getClass().getName()); - while (GrpcClientRequestReplayHelper.getInstance().getRequestQueue().size() > 0 && GrpcClientRequestReplayHelper.getInstance().getInProcessRequestQueue().size() > 0 && !GrpcClientRequestReplayHelper.getInstance().isWaiting().get()) { - Thread.sleep(100); - } - logger.log(LogLevel.FINER, WS_RECONNECT_IAST_REQUEST_REPLAY_POOL_DRAINED, this.getClass().getName()); - } -// RestRequestThreadPool.getInstance().resetIASTProcessing(); -// GrpcClientRequestReplayHelper.getInstance().resetIASTProcessing(); WSClient.getInstance().close(CloseFrame.SERVICE_RESTART, "Reconnecting to service"); } catch (Throwable e) { logger.log(LogLevel.SEVERE, String.format(ERROR_WHILE_PROCESSING_RECONNECTION_CC_S_S, e.getMessage(), e.getCause()), this.getClass().getName()); diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/logging/IAgentConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/logging/IAgentConstants.java index ac86fcf2e..5a11e43d3 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/logging/IAgentConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/logging/IAgentConstants.java @@ -579,4 +579,5 @@ public interface IAgentConstants { String REQUEST_FAILURE_DUE_TO_IOEXCEPTION = "Request failure could be due to cancellation, a connectivity problem or timeout."; String FAILURE_WHILE_GRPC_REQUEST_BODY_CONVERSION = "Failure while processing gRPC Request body, body : %s "; String REQUEST_FAILURE_FOR_S_WITH_RESPONSE_CODE = "Request failure for : %s, with response : %s and response body : %s"; + } \ No newline at end of file diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java index f517a9ad1..3da76083b 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSendPool.java @@ -27,8 +27,6 @@ public class EventSendPool { private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); - private AtomicBoolean isWaiting = new AtomicBoolean(false); - private EventSendPool() { // load the settings int queueSize = QUEUE_SIZE; @@ -167,10 +165,6 @@ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { } } - public AtomicBoolean isWaiting() { - return isWaiting; - } - public ThreadPoolExecutor getExecutor() { return executor; } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSender.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSender.java index 893f5687a..889bd35e0 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSender.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/websocket/EventSender.java @@ -35,13 +35,6 @@ public EventSender(Object event) { */ @Override public Boolean call() throws Exception { - if (WSUtils.getInstance().isReconnecting()) { - synchronized (WSUtils.getInstance()) { - EventSendPool.getInstance().isWaiting().set(true); - WSUtils.getInstance().wait(); - EventSendPool.getInstance().isWaiting().set(false); - } - } if (event instanceof JavaAgentEventBean) { ((JavaAgentEventBean) event).setEventGenerationTime(System.currentTimeMillis()); } 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..9009d5bef 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 @@ -20,7 +20,6 @@ public class GrpcClientRequestReplayHelper { private final Map> processedIds = new ConcurrentHashMap(); private final Set pendingIds = ConcurrentHashMap.newKeySet(); private final Set rejectedIds = ConcurrentHashMap.newKeySet(); - private static final AtomicBoolean isWaiting = new AtomicBoolean(false); public static GrpcClientRequestReplayHelper getInstance(){ return InstanceHolder.instance; @@ -69,10 +68,6 @@ public void setGrpcRequestExecutorStarted(boolean grpcRequestExecutorStarted) { isGrpcRequestExecutorStarted = grpcRequestExecutorStarted; } - public AtomicBoolean isWaiting() { - return isWaiting; - } - public void addFuzzFailEventToQueue(FuzzRequestBean requestBean, Throwable e){ fuzzFailRequestQueue.add(Collections.singletonMap(requestBean, e)); } From 77e5ff500d0d77f540a836380ec6695671461027 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Wed, 11 Sep 2024 12:16:11 +0530 Subject: [PATCH 38/44] improve json array representation for restrict --- .../agent/security/intcodeagent/utils/RestrictionUtility.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java index 07b3a9609..c895f1457 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java @@ -270,9 +270,9 @@ private static Map> parseJsonNode(JsonNode node, String bas private static @NotNull String getBase(String baseKey, int index) { if(StringUtils.isBlank(baseKey)){ - return String.format("[%s]", index); + return "[]"; } - return String.format("%s[%s]", baseKey, index); + return String.format("%s[]", baseKey); } private static Map> parseRequestHeaders(Map headers) { From 3c679c5d41247133a1ad943b191d86b5e05dca93 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 12 Sep 2024 12:07:56 +0530 Subject: [PATCH 39/44] Use case type SQL for postgresSQL --- .../AbstractJdbc2Statement_Instrumentation.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/instrumentation-security/jdbc-postgresql-8.0-312.jdbc3/src/main/java/org/postgresql/jdbc2/AbstractJdbc2Statement_Instrumentation.java b/instrumentation-security/jdbc-postgresql-8.0-312.jdbc3/src/main/java/org/postgresql/jdbc2/AbstractJdbc2Statement_Instrumentation.java index ba493bac3..3fb4d314f 100644 --- a/instrumentation-security/jdbc-postgresql-8.0-312.jdbc3/src/main/java/org/postgresql/jdbc2/AbstractJdbc2Statement_Instrumentation.java +++ b/instrumentation-security/jdbc-postgresql-8.0-312.jdbc3/src/main/java/org/postgresql/jdbc2/AbstractJdbc2Statement_Instrumentation.java @@ -77,8 +77,8 @@ private void releaseLock() { GenericHelper.releaseLock(JdbcHelper.getNrSecCustomAttribName()); } - private boolean acquireLockIfPossible(VulnerabilityCaseType httpRequest) { - return GenericHelper.acquireLockIfPossible(httpRequest, JdbcHelper.getNrSecCustomAttribName()); + private boolean acquireLockIfPossible() { + return GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.SQL_DB_COMMAND, JdbcHelper.getNrSecCustomAttribName()); } public AbstractJdbc2Statement_Instrumentation(AbstractJdbc2Connection connection, String sql, boolean isCallable, int rsType, int rsConcurrency) throws SQLException { @@ -86,7 +86,7 @@ public AbstractJdbc2Statement_Instrumentation(AbstractJdbc2Connection connection } public ResultSet executeQuery() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -107,7 +107,7 @@ public ResultSet executeQuery() throws SQLException { } public ResultSet executeQuery(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_QUERY); @@ -125,7 +125,7 @@ public ResultSet executeQuery(String sql) throws SQLException { } public int executeUpdate() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -146,7 +146,7 @@ public int executeUpdate() throws SQLException { } public int executeUpdate(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE_UPDATE); @@ -164,7 +164,7 @@ public int executeUpdate(String sql) throws SQLException { } public boolean execute() throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { if(sqlQuery == null){ @@ -185,7 +185,7 @@ public boolean execute() throws SQLException { } public boolean execute(String sql) throws SQLException { - boolean isLockAcquired = acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST); + boolean isLockAcquired = acquireLockIfPossible(); AbstractOperation operation = null; if(isLockAcquired) { operation = preprocessSecurityHook(sql, JdbcHelper.METHOD_EXECUTE); From b2ee82820355b955a25823c2818a1ba8576d151e Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Fri, 13 Sep 2024 10:43:11 +0530 Subject: [PATCH 40/44] Updated config changes regarding mapping parameters. --- .../NullPointerException_Instrumentation.java | 17 ---- .../newrelic/agent/security/AgentConfig.java | 83 +++++++++++-------- .../newrelic/agent/security/AgentInfo.java | 6 +- .../filelogging/FileLoggerThreadPool.java | 13 ++- .../intcodeagent/utils/CommonUtils.java | 22 +---- .../intcodeagent/utils/ResourceUtils.java | 23 +++++ .../utils/RestrictionUtility.java | 38 ++++----- .../intcodeagent/websocket/WSClient.java | 3 +- .../agent/security/util/IUtilConstants.java | 11 +++ .../newrelic/api/agent/security/Agent.java | 3 +- .../security/schema/policy/IASTScan.java | 2 - .../schema/policy/MappingParameter.java | 34 ++++++++ .../schema/policy/MappingParameters.java | 54 ++++++++---- .../schema/policy/RestrictionCriteria.java | 26 +----- 14 files changed, 197 insertions(+), 138 deletions(-) delete mode 100644 instrumentation-security/exception-handler/src/main/java/java/lang/NullPointerException_Instrumentation.java create mode 100644 newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/ResourceUtils.java create mode 100644 newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameter.java diff --git a/instrumentation-security/exception-handler/src/main/java/java/lang/NullPointerException_Instrumentation.java b/instrumentation-security/exception-handler/src/main/java/java/lang/NullPointerException_Instrumentation.java deleted file mode 100644 index ab476454a..000000000 --- a/instrumentation-security/exception-handler/src/main/java/java/lang/NullPointerException_Instrumentation.java +++ /dev/null @@ -1,17 +0,0 @@ -package java.lang; - -import com.newrelic.api.agent.security.NewRelicSecurity; -import com.newrelic.api.agent.weaver.MatchType; -import com.newrelic.api.agent.weaver.Weave; -import com.newrelic.api.agent.weaver.WeaveAllConstructors; - -@Weave(type = MatchType.ExactClass, originalName = "java.lang.NullPointerException") -public class NullPointerException_Instrumentation extends RuntimeException { - - @WeaveAllConstructors - public NullPointerException_Instrumentation() { - if (NewRelicSecurity.isHookProcessingActive()) { - NewRelicSecurity.getAgent().reportApplicationRuntimeError(NewRelicSecurity.getAgent().getSecurityMetaData(), this); - } - } -} diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java index c10990844..a3fed3d43 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentConfig.java @@ -23,6 +23,8 @@ import org.apache.commons.io.comparator.LastModifiedFileComparator; import org.apache.commons.io.filefilter.FileFilterUtils; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -51,6 +53,9 @@ public class AgentConfig { public static final String ROUTE = "route"; public static final String MAPPING_PARAMETERS_ARE_REQUIRED_FOR_IAST_RESTRICTED_MODE = "Mapping Parameters are required for IAST Restricted Mode"; public static final String DEFAULT_SCAN_SCHEDULE_EXPRESSION = "0 0 0 * * ?"; + public static final String INVALID_SECURITY_CONFIGURATION_FOR_MODE_IAST_RESTRICTED = "Invalid Security Configuration for mode IAST_RESTRICTED "; + public static final String INVALID_SECURITY_CONFIGURATION = "Invalid Security Configuration "; + private static final Logger log = LoggerFactory.getLogger(AgentConfig.class); private String NR_CSEC_HOME; private String logLevel; @@ -92,6 +97,8 @@ public long instantiate() throws RestrictionModeException { osVariables = OsVariablesInstance.instantiate().getOsVariables(); logger = FileLoggerThreadPool.getInstance(); + //Do not repeat this task + logger.initialiseLogger(); iastTestIdentifier = NewRelic.getAgent().getConfig().getValue(IUtilConstants.IAST_TEST_IDENTIFIER); @@ -129,7 +136,6 @@ private void instantiateAgentMode(String groupName) throws RestrictionModeExcept case IAST_RESTRICTED: try { readIastRestrictedConfig(); - updateSkipScanParameters(); } catch (RestrictionModeException e) { System.err.println("[NR-CSEC-JA] Error while reading IAST Restricted Mode Configuration. IAST Restricted Mode will be disabled."); NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Restricted Mode Configuration. IAST Restricted Mode will be disabled."); @@ -146,6 +152,7 @@ private void instantiateAgentMode(String groupName) throws RestrictionModeExcept try { readScanSchedule(); readSkipScan(); + updateSkipScanParameters(); } catch (RestrictionModeException e){ System.err.println("[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled."); NewRelic.getAgent().getLogger().log(Level.WARNING, "[NR-CSEC-JA] Error while reading IAST Scan Configuration. Security will be disabled. Message : {0}", e.getMessage()); @@ -180,7 +187,7 @@ private void readSkipScan() throws RestrictionModeException { agentMode.getSkipScan().getIastDetectionCategory().setRxssEnabled(NewRelic.getAgent().getConfig().getValue(SKIP_RXSS, false)); agentMode.getSkipScan().getIastDetectionCategory().generateDisabledCategoriesCSV(); } catch (ClassCastException | NumberFormatException e){ - throw new RestrictionModeException("Invalid Security Configuration " + e.getMessage(), e); + throw new RestrictionModeException(INVALID_SECURITY_CONFIGURATION + e.getMessage(), e); } } @@ -209,19 +216,20 @@ private void readScanSchedule() throws RestrictionModeException { agentMode.getScanSchedule().setNextScanTime(new Date(Instant.now().toEpochMilli())); } } catch (ClassCastException | NumberFormatException e){ - throw new RestrictionModeException("Invalid Security Configuration " + e.getMessage(), e); + throw new RestrictionModeException(INVALID_SECURITY_CONFIGURATION + e.getMessage(), e); } } private void updateSkipScanParameters() { - for (MappingParameters mappingParameter : this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters()) { - if(mappingParameter.getAccountIdLocation().equals(HttpParameterLocation.HEADER)){ - this.agentMode.getSkipScan().getParameters().getHeader().add(mappingParameter.getAccountIdKey()); - } else if(mappingParameter.getAccountIdLocation().equals(HttpParameterLocation.QUERY)){ - this.agentMode.getSkipScan().getParameters().getQuery().add(mappingParameter.getAccountIdKey()); - } else if(mappingParameter.getAccountIdLocation().equals(HttpParameterLocation.BODY)){ - this.agentMode.getSkipScan().getParameters().getBody().add(mappingParameter.getAccountIdKey()); - } + + if(this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getBody().isEnabled()){ + this.agentMode.getSkipScan().getParameters().getBody().addAll(this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getBody().getLocations()); + } + if(this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getQuery().isEnabled()){ + this.agentMode.getSkipScan().getParameters().getQuery().addAll(this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getQuery().getLocations()); + } + if(this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getHeader().isEnabled()){ + this.agentMode.getSkipScan().getParameters().getHeader().addAll(this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getHeader().getLocations()); } } @@ -232,32 +240,39 @@ private void readIastConfig() { } private void readIastRestrictedConfig() throws RestrictionModeException { - this.agentMode.getIastScan().setRestricted(true); - Agent.getCustomNoticeErrorParameters().put(IAST_RESTRICTED, String.valueOf(true)); - RestrictionCriteria restrictionCriteria = this.agentMode.getIastScan().getRestrictionCriteria(); - restrictionCriteria.setAccountInfo(new AccountInfo(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_ACCOUNT_INFO_ACCOUNT_ID))); - if(restrictionCriteria.getAccountInfo().isEmpty()) { - throw new RestrictionModeException(ACCOUNT_ID_IS_REQUIRED_FOR_IAST_RESTRICTED_MODE); - } + try { + this.agentMode.getIastScan().setRestricted(true); + Agent.getCustomNoticeErrorParameters().put(IAST_RESTRICTED, String.valueOf(true)); + RestrictionCriteria restrictionCriteria = this.agentMode.getIastScan().getRestrictionCriteria(); + restrictionCriteria.setAccountInfo(new AccountInfo(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_ACCOUNT_INFO_ACCOUNT_ID))); + if(restrictionCriteria.getAccountInfo().isEmpty()) { + throw new RestrictionModeException(ACCOUNT_ID_IS_REQUIRED_FOR_IAST_RESTRICTED_MODE); + } - //Mapping parameters - List> mappingParameters = NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS, Collections.emptyList()); - if(mappingParameters.isEmpty()) { - throw new RestrictionModeException(MAPPING_PARAMETERS_ARE_REQUIRED_FOR_IAST_RESTRICTED_MODE); - } - for (Map mappingParameter : mappingParameters) { - MappingParameters matchingCriteria = new MappingParameters(HttpParameterLocation.valueOf(mappingParameter.get(ACCOUNT_ID_LOCATION)), mappingParameter.get(ACCOUNT_ID_KEY)); -// MappingParameters matchingCriteria = mapper.convertValue(mappingParameter, MappingParameters.class); - restrictionCriteria.getMappingParameters().add(matchingCriteria); - } + //Mapping parameters + this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getBody().setEnabled(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS_BODY_ENABLED, false)); + this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getQuery().setEnabled(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS_QUERY_ENABLED, false)); + this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getHeader().setEnabled(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS_HEADER_ENABLED, false)); + this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getPath().setEnabled(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS_PATH_ENABLED, false)); + this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getBody().setLocations(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS_BODY_LOCATION, Collections.emptyList()).stream() + .map(Object::toString) + .collect(Collectors.toList())); + this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getQuery().setLocations(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS_QUERY_LOCATION, Collections.emptyList()).stream() + .map(Object::toString) + .collect(Collectors.toList())); + this.agentMode.getIastScan().getRestrictionCriteria().getMappingParameters().getHeader().setLocations(NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_MAPPING_PARAMETERS_HEADER_LOCATION, Collections.emptyList()).stream() + .map(Object::toString) + .collect(Collectors.toList())); - //Strict Criteria - List> strictCriteria = NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_STRICT, Collections.emptyList()); - for (Map strictCriterion : strictCriteria) { - StrictMappings matchingCriteria = new StrictMappings(strictCriterion.get(ROUTE), HttpParameterLocation.valueOf(strictCriterion.get(ACCOUNT_ID_LOCATION)), strictCriterion.get(ACCOUNT_ID_KEY)); - restrictionCriteria.getStrictMappings().add(matchingCriteria); + //Strict Criteria + List> strictCriteria = NewRelic.getAgent().getConfig().getValue(RESTRICTION_CRITERIA_STRICT, Collections.emptyList()); + for (Map strictCriterion : strictCriteria) { + StrictMappings matchingCriteria = new StrictMappings(strictCriterion.get(ROUTE), HttpParameterLocation.valueOf(strictCriterion.get(ACCOUNT_ID_LOCATION)), strictCriterion.get(ACCOUNT_ID_KEY)); + restrictionCriteria.getStrictMappings().add(matchingCriteria); + } + } catch (ClassCastException | NumberFormatException e){ + throw new RestrictionModeException(INVALID_SECURITY_CONFIGURATION_FOR_MODE_IAST_RESTRICTED + e.getMessage(), e); } - } private void readRaspConfig() { diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentInfo.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentInfo.java index b69db9675..596ce452f 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentInfo.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/AgentInfo.java @@ -48,7 +48,7 @@ public class AgentInfo { private BuildInfo buildInfo = new BuildInfo(); - private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); + private static FileLoggerThreadPool logger; private boolean processProtected = false; private AgentInfo() { @@ -119,6 +119,10 @@ public void setBuildInfo(BuildInfo buildInfo) { this.buildInfo = buildInfo; } + public static void initialiseLogger() { + logger = FileLoggerThreadPool.getInstance(); + } + public ApplicationInfoBean generateAppInfo(CollectorConfig config) { applicationInfo = ApplicationInfoUtils.createApplicationInfoBean(identifier, getVMPID(), applicationUUID, config); if (applicationInfo == null) { diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/filelogging/FileLoggerThreadPool.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/filelogging/FileLoggerThreadPool.java index 6dcb7f362..46db8e43d 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/filelogging/FileLoggerThreadPool.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/filelogging/FileLoggerThreadPool.java @@ -32,13 +32,19 @@ public class FileLoggerThreadPool { private static OSVariables osVariables = OsVariablesInstance.getInstance().getOsVariables(); private FileLoggerThreadPool() throws IOException { + maxfiles = LogFileHelper.logFileCount(); + maxfilesize = LogFileHelper.logFileLimit()* 1024L; + } + + /** + * Initialise the logger, call this method only once + */ + public void initialiseLogger() { // load the settings int queueSize = 15000; int maxPoolSize = 1; int corePoolSize = 1; long keepAliveTime = 600; - maxfiles = LogFileHelper.logFileCount(); - maxfilesize = LogFileHelper.logFileLimit()* 1024L; TimeUnit timeUnit = TimeUnit.SECONDS; try { @@ -47,7 +53,7 @@ private FileLoggerThreadPool() throws IOException { } } catch (NumberFormatException e){} - if(!isLoggingToStdOut && StringUtils.isNotBlank(osVariables.getLogDirectory())) { + if(!isLoggingToStdOut && StringUtils.isBlank(osVariables.getLogDirectory())) { isLoggingActive = false; isInitLoggingActive = false; return; @@ -80,7 +86,6 @@ public Thread newThread(Runnable r) { return t; } }); - } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/CommonUtils.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/CommonUtils.java index 4bc17ee4b..2def061f0 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/CommonUtils.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/CommonUtils.java @@ -1,14 +1,9 @@ package com.newrelic.agent.security.intcodeagent.utils; -import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; -import com.newrelic.api.agent.security.utils.logging.LogLevel; -import com.newrelic.api.agent.security.Agent; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -17,10 +12,9 @@ import java.util.Stack; public class CommonUtils { - - private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); - public static final String POLICY_WRITE_FAILED = "policy write failed : "; - public static final String POLICY_WRITTEN_TO_FILE = "policy written to file : "; + /** + * This class can't have a logger + */ public static SecureRandom secureRandom = new SecureRandom(); @@ -49,16 +43,6 @@ public static Boolean forceMkdirs(Path directory, String permissions) throws IOE return true; } - public static InputStream getResourceStreamFromAgentJar(String resourceName) { - try { - return new URL("jar:" + Agent.getAgentJarURL().toExternalForm() + "!/" + resourceName).openStream(); - } catch (Exception e) { - logger.log(LogLevel.SEVERE, String.format("Unable to locate resource from agent jar : %s", e.getMessage()), CommonUtils.class.getName()); - logger.log(LogLevel.FINER, "Unable to locate resource from agent jar : ", e, CommonUtils.class.getName()); - } - return null; - } - /** * Generate random int between range start to end. Both inclusive. diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/ResourceUtils.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/ResourceUtils.java new file mode 100644 index 000000000..faa2d3f1c --- /dev/null +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/ResourceUtils.java @@ -0,0 +1,23 @@ +package com.newrelic.agent.security.intcodeagent.utils; + +import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; +import com.newrelic.api.agent.security.Agent; +import com.newrelic.api.agent.security.utils.logging.LogLevel; + +import java.io.InputStream; +import java.net.URL; + +public class ResourceUtils { + + private static final FileLoggerThreadPool logger = FileLoggerThreadPool.getInstance(); + + public static InputStream getResourceStreamFromAgentJar(String resourceName) { + try { + return new URL("jar:" + Agent.getAgentJarURL().toExternalForm() + "!/" + resourceName).openStream(); + } catch (Exception e) { + logger.log(LogLevel.SEVERE, String.format("Unable to locate resource from agent jar : %s", e.getMessage()), CommonUtils.class.getName()); + logger.log(LogLevel.FINER, "Unable to locate resource from agent jar : ", e, CommonUtils.class.getName()); + } + return null; + } +} diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java index b26f0015b..0128a219d 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java @@ -71,29 +71,29 @@ public static boolean hasValidAccountId(RestrictionCriteria restrictionCriteria, if(!request.isRequestParametersParsed()){ parseHttpRequestParameters(request); } - for (MappingParameters mappingParameter : restrictionCriteria.getMappingParameters()) { - boolean match = false; - switch (mappingParameter.getAccountIdLocation()) { - case QUERY: - List queryParameters = getQueryString(mappingParameter.getAccountIdKey(), request.getQueryParameters()); - match = matcher(accountIds, queryParameters); - break; - case PATH: - match = matcher(accountIds, request.getPathParameters()); - break; - case HEADER: - List headerValues = getHeaderParameters(mappingParameter.getAccountIdKey(), request.getRequestHeaderParameters()); - match = matcher(accountIds, headerValues); - break; - case BODY: - List bodyValues = getBodyParameters(mappingParameter.getAccountIdKey(), request.getRequestBodyParameters()); - match = matcher(accountIds, bodyValues); - break; + + if(restrictionCriteria.getMappingParameters().getHeader().isEnabled()) { + List headerValues = restrictionCriteria.getMappingParameters().getHeader().getLocations(); + if(matcher(accountIds, headerValues)){ + return true; + } + } + if(restrictionCriteria.getMappingParameters().getQuery().isEnabled()) { + List queryValues = restrictionCriteria.getMappingParameters().getQuery().getLocations(); + if(matcher(accountIds, queryValues)){ + return true; } - if(match){ + } + if(restrictionCriteria.getMappingParameters().getPath().isEnabled()) { + if(matcher(accountIds, request.getPathParameters())){ return true; } } + if(restrictionCriteria.getMappingParameters().getBody().isEnabled()) { + List bodyValues = restrictionCriteria.getMappingParameters().getBody().getLocations(); + return matcher(accountIds, bodyValues); + } + return false; } 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 e1240b2d2..e156df9db 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 @@ -10,6 +10,7 @@ import com.newrelic.agent.security.intcodeagent.controlcommand.ControlCommandProcessorThreadPool; import com.newrelic.agent.security.intcodeagent.exceptions.SecurityNoticeError; import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; +import com.newrelic.agent.security.intcodeagent.utils.ResourceUtils; import com.newrelic.api.agent.security.utils.logging.LogLevel; import com.newrelic.agent.security.intcodeagent.logging.IAgentConstants; import com.newrelic.agent.security.intcodeagent.utils.CommonUtils; @@ -130,7 +131,7 @@ private InputStream getCaBundleStream() throws IOException { inputStream = Files.newInputStream(Paths.get(caBundlePath)); } else { noticeErrorCustomParameters.put("ca_bundle_path", "internal-pem"); - inputStream = CommonUtils.getResourceStreamFromAgentJar("nr-custom-ca.pem"); + inputStream = ResourceUtils.getResourceStreamFromAgentJar("nr-custom-ca.pem"); } return inputStream; } diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java index d04d53cc7..d40df7dba 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/util/IUtilConstants.java @@ -37,6 +37,17 @@ public interface IUtilConstants { String RESTRICTION_CRITERIA = "security.restriction_criteria"; String RESTRICTION_CRITERIA_ACCOUNT_INFO_ACCOUNT_ID = "security.restriction_criteria.account_info.account_id_value"; String RESTRICTION_CRITERIA_MAPPING_PARAMETERS = "security.restriction_criteria.mapping_parameters"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS_HEADER = RESTRICTION_CRITERIA_MAPPING_PARAMETERS + ".header"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS_QUERY = RESTRICTION_CRITERIA_MAPPING_PARAMETERS + ".query"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS_BODY = RESTRICTION_CRITERIA_MAPPING_PARAMETERS + ".body"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS_PATH = RESTRICTION_CRITERIA_MAPPING_PARAMETERS + ".path"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS_HEADER_ENABLED = RESTRICTION_CRITERIA_MAPPING_PARAMETERS_HEADER + ".enabled"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS_QUERY_ENABLED = RESTRICTION_CRITERIA_MAPPING_PARAMETERS_QUERY + ".enabled"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS_BODY_ENABLED = RESTRICTION_CRITERIA_MAPPING_PARAMETERS_BODY + ".enabled"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS_PATH_ENABLED = RESTRICTION_CRITERIA_MAPPING_PARAMETERS_PATH + ".enabled"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS_HEADER_LOCATION = RESTRICTION_CRITERIA_MAPPING_PARAMETERS_HEADER + ".location"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS_QUERY_LOCATION = RESTRICTION_CRITERIA_MAPPING_PARAMETERS_QUERY + ".location"; + String RESTRICTION_CRITERIA_MAPPING_PARAMETERS_BODY_LOCATION = RESTRICTION_CRITERIA_MAPPING_PARAMETERS_BODY + ".location"; String RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS = "security.restriction_criteria.skip_scan_parameters"; String RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_HEADER = "security.restriction_criteria.skip_scan_parameters.header"; String RESTRICTION_CRITERIA_SKIP_SCAN_PARAMETERS_QUERY = "security.restriction_criteria.skip_scan_parameters.query"; 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 398e61f30..8cc1dd6b0 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 @@ -110,6 +110,7 @@ private void initialise() throws RestrictionModeException { info = AgentInfo.getInstance(); } long delay = config.instantiate(); + AgentInfo.initialiseLogger(); SchedulerHelper.getInstance().scheduleIastTrigger(this::triggerNrSecurity, delay, TimeUnit.MILLISECONDS); } @@ -228,7 +229,7 @@ private BuildInfo readCollectorBuildInfo() { BuildInfo buildInfo = new BuildInfo(); try { Properties properties = new Properties(); - properties.load(CommonUtils.getResourceStreamFromAgentJar("Agent.properties")); + properties.load(ResourceUtils.getResourceStreamFromAgentJar("Agent.properties")); buildInfo = new ObjectMapper().convertValue(properties, BuildInfo.class); } catch (Throwable e) { logger.log(LogLevel.SEVERE, String.format(CRITICAL_ERROR_UNABLE_TO_READ_BUILD_INFO_AND_VERSION_S_S, e.getMessage(), e.getCause()), this.getClass().getName()); diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java index cadba8ae5..c18a9be27 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/IASTScan.java @@ -7,9 +7,7 @@ public class IASTScan { private Boolean enabled = true; private Probing probing = new Probing(); - @JsonIgnore private Boolean restricted = false; - @JsonIgnore private RestrictionCriteria restrictionCriteria = new RestrictionCriteria(); /** diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameter.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameter.java new file mode 100644 index 000000000..f4ee7b353 --- /dev/null +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameter.java @@ -0,0 +1,34 @@ +package com.newrelic.api.agent.security.schema.policy; + +import java.util.List; + +public class MappingParameter { + + private boolean enabled; + + private List locations; + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public List getLocations() { + return locations; + } + + public void setLocations(List locations) { + this.locations = locations; + } + + public MappingParameter() { + } + + public MappingParameter(boolean enabled, List locations) { + this.enabled = enabled; + this.locations = locations; + } +} diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameters.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameters.java index 2294265ba..aa34cbd90 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameters.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/MappingParameters.java @@ -4,37 +4,57 @@ public class MappingParameters { - @JsonProperty("account_id_location") - private HttpParameterLocation accountIdLocation; + private MappingParameter header; - @JsonProperty("account_id_key") - private String accountIdKey; + private MappingParameter body; + + private MappingParameter query; + + private MappingParameter path; public MappingParameters() { + this.header = new MappingParameter(); + this.body = new MappingParameter(); + this.query = new MappingParameter(); + this.path = new MappingParameter(); + } + + public MappingParameters(MappingParameter header, MappingParameter body, MappingParameter query, MappingParameter path) { + this.header = header; + this.body = body; + this.query = query; + this.path = path; + } + + public MappingParameter getHeader() { + return header; + } + + public void setHeader(MappingParameter header) { + this.header = header; } - public MappingParameters(HttpParameterLocation accountIdLocation) { - this.accountIdLocation = accountIdLocation; + public MappingParameter getBody() { + return body; } - public MappingParameters(HttpParameterLocation accountIdLocation, String accountIdKey) { - this.accountIdLocation = accountIdLocation; - this.accountIdKey = accountIdKey; + public void setBody(MappingParameter body) { + this.body = body; } - public HttpParameterLocation getAccountIdLocation() { - return accountIdLocation; + public MappingParameter getQuery() { + return query; } - public void setAccountIdLocation(HttpParameterLocation accountIdLocation) { - this.accountIdLocation = accountIdLocation; + public void setQuery(MappingParameter query) { + this.query = query; } - public String getAccountIdKey() { - return accountIdKey; + public MappingParameter getPath() { + return path; } - public void setAccountIdKey(String accountIdKey) { - this.accountIdKey = accountIdKey; + public void setPath(MappingParameter path) { + this.path = path; } } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java index 8d87ce1c6..395011a23 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/policy/RestrictionCriteria.java @@ -5,27 +5,15 @@ public class RestrictionCriteria { - private ScanSchedule scanSchedule = new ScanSchedule(); - private AccountInfo accountInfo = new AccountInfo(); - private List mappingParameters = new ArrayList<>(); - - private SkipScanParameters skipScanParameters = new SkipScanParameters(); + private MappingParameters mappingParameters = new MappingParameters(); private List strictMappings = new ArrayList<>(); public RestrictionCriteria() { } - public ScanSchedule getScanTime() { - return scanSchedule; - } - - public void setScanTime(ScanSchedule scanSchedule) { - this.scanSchedule = scanSchedule; - } - public AccountInfo getAccountInfo() { return accountInfo; } @@ -34,22 +22,14 @@ public void setAccountInfo(AccountInfo accountInfo) { this.accountInfo = accountInfo; } - public List getMappingParameters() { + public MappingParameters getMappingParameters() { return mappingParameters; } - public void setMappingParameters(List mappingParameters) { + public void setMappingParameters(MappingParameters mappingParameters) { this.mappingParameters = mappingParameters; } - public SkipScanParameters getSkipScanParameters() { - return skipScanParameters; - } - - public void setSkipScanParameters(SkipScanParameters skipScanParameters) { - this.skipScanParameters = skipScanParameters; - } - public List getStrictMappings() { return strictMappings; } From fed109e5af915b41eec4c95a7d315f04a430df10 Mon Sep 17 00:00:00 2001 From: idawda Date: Tue, 17 Sep 2024 12:19:49 +0530 Subject: [PATCH 41/44] NR-272899: Fix for user class detection grpc --- .../newrelic/api/agent/security/Agent.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) 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 dc65e8bd6..f5dcdf8b3 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 @@ -496,6 +496,7 @@ private UserClassEntity setUserClassEntityByAnnotation(StackTraceElement[] servi } private UserClassEntity setUserClassEntity(AbstractOperation operation, SecurityMetaData securityMetaData) { + boolean frameworkSpecificEntityFound = false; UserClassEntity userClassEntity = new UserClassEntity(); StackTraceElement userStackTraceElement = securityMetaData.getCustomAttribute(GenericHelper.USER_CLASS_ENTITY, StackTraceElement.class); if(userStackTraceElement == null && securityMetaData.getMetaData().getServiceTrace() != null && securityMetaData.getMetaData().getServiceTrace().length > 0){ @@ -520,21 +521,18 @@ private UserClassEntity setUserClassEntity(AbstractOperation operation, Security switch (framework){ case "vertx-web": case "GRPC": - if(i-1 >= 0) { + if(!frameworkSpecificEntityFound && i-1 >= 0) { userClassEntity = setUserClassEntityForVertx(operation, userStackTraceElement, userClassEntity, securityMetaData.getMetaData().isUserLevelServiceMethodEncountered(), i); if(userClassEntity.getUserClassElement() != null){ - return userClassEntity; + frameworkSpecificEntityFound = true; } } break; default: - if(userStackTraceElement != null){ - if(StringUtils.equals(stackTraceElement.getClassName(), userStackTraceElement.getClassName()) - && StringUtils.equals(stackTraceElement.getMethodName(), userStackTraceElement.getMethodName())){ - userClassEntity.setUserClassElement(stackTraceElement); - userClassEntity.setCalledByUserCode(securityMetaData.getMetaData().isUserLevelServiceMethodEncountered()); - return userClassEntity; - } + if(userStackTraceElement != null && StringUtils.equals(stackTraceElement.getClassName(), userStackTraceElement.getClassName()) + && StringUtils.equals(stackTraceElement.getMethodName(), userStackTraceElement.getMethodName())){ + userClassEntity.setUserClassElement(stackTraceElement); + userClassEntity.setCalledByUserCode(securityMetaData.getMetaData().isUserLevelServiceMethodEncountered()); } } } @@ -544,8 +542,16 @@ private UserClassEntity setUserClassEntity(AbstractOperation operation, Security return userClassEntity; } + if (frameworkSpecificEntityFound && userClassEntity.getUserClassElement() != null && !securityMetaData.getMetaData().isFoundAnnotedUserLevelServiceMethod()){ + return userClassEntity; + } + + if (userClassEntity.getUserClassElement() != null){ + return userClassEntity; + } + // user class identification using annotations - if (userClassEntity.getUserClassElement() == null && securityMetaData.getMetaData().isFoundAnnotedUserLevelServiceMethod()) { + if (securityMetaData.getMetaData().isFoundAnnotedUserLevelServiceMethod()) { return setUserClassEntityByAnnotation(securityMetaData.getMetaData().getServiceTrace()); } From f4b2de4eaf424298cbf9a8bd6e0456b587700977 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 19 Sep 2024 12:03:01 +0530 Subject: [PATCH 42/44] update restriction check for query param, body and headers --- .../utils/RestrictionUtility.java | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java index 0128a219d..a099c18fb 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java @@ -8,7 +8,6 @@ import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; import com.newrelic.api.agent.security.schema.HttpRequest; -import com.newrelic.api.agent.security.schema.policy.MappingParameters; import com.newrelic.api.agent.security.schema.policy.RestrictionCriteria; import com.newrelic.api.agent.security.schema.policy.SkipScan; import com.newrelic.api.agent.security.utils.logging.LogLevel; @@ -73,13 +72,13 @@ public static boolean hasValidAccountId(RestrictionCriteria restrictionCriteria, } if(restrictionCriteria.getMappingParameters().getHeader().isEnabled()) { - List headerValues = restrictionCriteria.getMappingParameters().getHeader().getLocations(); + List headerValues = getHeaderParameters(restrictionCriteria.getMappingParameters().getHeader().getLocations(), request.getQueryParameters()); if(matcher(accountIds, headerValues)){ return true; } } if(restrictionCriteria.getMappingParameters().getQuery().isEnabled()) { - List queryValues = restrictionCriteria.getMappingParameters().getQuery().getLocations(); + List queryValues = getQueryString(restrictionCriteria.getMappingParameters().getHeader().getLocations(), request.getQueryParameters()); if(matcher(accountIds, queryValues)){ return true; } @@ -90,35 +89,49 @@ public static boolean hasValidAccountId(RestrictionCriteria restrictionCriteria, } } if(restrictionCriteria.getMappingParameters().getBody().isEnabled()) { - List bodyValues = restrictionCriteria.getMappingParameters().getBody().getLocations(); + List bodyValues = getBodyParameters(restrictionCriteria.getMappingParameters().getBody().getLocations(), request.getRequestBodyParameters()); return matcher(accountIds, bodyValues); } return false; } - private static List getBodyParameters(String accountId, Map> requestBodyParameters) { + private static List getBodyParameters(List accountIds, Map> requestBodyParameters) { if (requestBodyParameters == null || requestBodyParameters.isEmpty()) { return Collections.emptyList(); } - String lowerCaseAccountId = accountId.toLowerCase(); - return requestBodyParameters.get(lowerCaseAccountId); + + List values = new ArrayList<>(); + for (String accountId : accountIds) { + String lowerCaseAccountId = accountId.toLowerCase(); + values.addAll(requestBodyParameters.get(lowerCaseAccountId)); + } + + return values; } - private static List getHeaderParameters(String accountId, Map> requestHeaderParameters) { + private static List getHeaderParameters(List accountIds, Map> requestHeaderParameters) { if (requestHeaderParameters == null || requestHeaderParameters.isEmpty()) { return Collections.emptyList(); } - String lowerCaseAccountId = accountId.toLowerCase(); - return requestHeaderParameters.get(lowerCaseAccountId); + List values = new ArrayList<>(); + for (String accountId : accountIds) { + String lowerCaseAccountId = accountId.toLowerCase(); + values.addAll(requestHeaderParameters.get(lowerCaseAccountId)); + } + return values; } - private static List getQueryString(String accountId, Map> queryParameters) { + private static List getQueryString(List accountIds, Map> queryParameters) { if(queryParameters == null || queryParameters.isEmpty()) { return Collections.emptyList(); } - String lowerCaseAccountId = accountId.toLowerCase(); - return queryParameters.get(lowerCaseAccountId); + List values = new ArrayList<>(); + for (String accountId : accountIds) { + String lowerCaseAccountId = accountId.toLowerCase(); + values.addAll(queryParameters.get(lowerCaseAccountId)); + } + return values; } private static boolean matcher(List accountIds, List values) { From 6e01a95b89c9c405a2b626434ba4a84a7e16d138 Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 19 Sep 2024 15:44:01 +0530 Subject: [PATCH 43/44] Fix for restriction via header --- .../agent/security/intcodeagent/utils/RestrictionUtility.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java index a099c18fb..c262af40e 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java @@ -72,7 +72,7 @@ public static boolean hasValidAccountId(RestrictionCriteria restrictionCriteria, } if(restrictionCriteria.getMappingParameters().getHeader().isEnabled()) { - List headerValues = getHeaderParameters(restrictionCriteria.getMappingParameters().getHeader().getLocations(), request.getQueryParameters()); + List headerValues = getHeaderParameters(restrictionCriteria.getMappingParameters().getHeader().getLocations(), request.getRequestHeaderParameters()); if(matcher(accountIds, headerValues)){ return true; } From 0edcf36ed45ea89ce855d7e9b6a0d3be9554b69b Mon Sep 17 00:00:00 2001 From: lovesh-ap Date: Thu, 19 Sep 2024 16:16:54 +0530 Subject: [PATCH 44/44] use lower case elements --- .../intcodeagent/utils/RestrictionUtility.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java index c262af40e..b53d39ced 100644 --- a/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java +++ b/newrelic-security-agent/src/main/java/com/newrelic/agent/security/intcodeagent/utils/RestrictionUtility.java @@ -104,7 +104,9 @@ private static List getBodyParameters(List accountIds, Map values = new ArrayList<>(); for (String accountId : accountIds) { String lowerCaseAccountId = accountId.toLowerCase(); - values.addAll(requestBodyParameters.get(lowerCaseAccountId)); + if(requestBodyParameters.containsKey(lowerCaseAccountId)) { + values.addAll(requestBodyParameters.get(lowerCaseAccountId)); + } } return values; @@ -117,7 +119,9 @@ private static List getHeaderParameters(List accountIds, Map values = new ArrayList<>(); for (String accountId : accountIds) { String lowerCaseAccountId = accountId.toLowerCase(); - values.addAll(requestHeaderParameters.get(lowerCaseAccountId)); + if(requestHeaderParameters.containsKey(lowerCaseAccountId)) { + values.addAll(requestHeaderParameters.get(lowerCaseAccountId)); + } } return values; } @@ -129,7 +133,9 @@ private static List getQueryString(List accountIds, Map values = new ArrayList<>(); for (String accountId : accountIds) { String lowerCaseAccountId = accountId.toLowerCase(); - values.addAll(queryParameters.get(lowerCaseAccountId)); + if(queryParameters.containsKey(lowerCaseAccountId)) { + values.addAll(queryParameters.get(lowerCaseAccountId)); + } } return values; } @@ -341,7 +347,7 @@ private static void putHeaderParameter(String key, String value, Map> parseQueryParameters(String url) { @@ -367,7 +373,7 @@ private static Map> queryParamKeyValueGenerator(String quer List values = new ArrayList<>(); values.add(StringUtils.lowerCase(value)); values.add(StringUtils.lowerCase(ServletHelper.urlDecode(value))); - queryParameters.put(key, values); + queryParameters.put(StringUtils.lowerCase(key), values); } return queryParameters; }