From 1f703688307eb21d663a7d2881f332321a4cec96 Mon Sep 17 00:00:00 2001 From: Monu Lakshkar Date: Mon, 6 Nov 2023 18:16:47 +0530 Subject: [PATCH] Stored procedure query identification (initial poc) Co-authored-by: Ishika Dawda --- .../java/java/sql/PreparedStatement_Instrumentation.java | 4 ++++ .../security/instrumentator/dispatcher/Dispatcher.java | 8 +++++++- .../agent/security/schema/operation/SQLOperation.java | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) 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 475140ddf..069998d3e 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 @@ -53,6 +53,10 @@ private AbstractOperation preprocessSecurityHook (String sql, String methodName) SQLOperation sqlOperation = new SQLOperation(this.getClass().getName(), methodName); sqlOperation.setQuery(sql); sqlOperation.setParams(this.params); + // for now only those db servers are supported that uses `call` + if (sql.toLowerCase().startsWith("call") || sql.toLowerCase().startsWith("{call")) { + sqlOperation.setStoredProcedureCall(true); + } sqlOperation.setDbName(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute(JDBCVendor.META_CONST_JDBC_VENDOR, String.class)); sqlOperation.setPreparedCall(true); NewRelicSecurity.getAgent().registerOperation(sqlOperation); 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 a6deb2a50..80d2874af 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 @@ -55,6 +55,7 @@ public class Dispatcher implements Callable { private Map extraInfo = new HashMap(); private boolean isNRCode = false; private static AtomicBoolean firstEventSent = new AtomicBoolean(false); + private final String SQL_STORED_PROCEDURE ="SQL_STORED_PROCEDURE"; public ExitEventBean getExitEventBean() { return exitEventBean; @@ -438,7 +439,12 @@ private JavaAgentEventBean prepareSQLDbCommandEvent(SQLOperation operation, } params.add(query); eventBean.setParameters(params); - eventBean.setEventCategory(operation.getDbName()); + if (operation.isStoredProcedureCall()) { + eventBean.setEventCategory(SQL_STORED_PROCEDURE); + } else { + eventBean.setEventCategory(operation.getDbName()); + } + return eventBean; } diff --git a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/operation/SQLOperation.java b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/operation/SQLOperation.java index 6e3d5a66e..aab96090d 100644 --- a/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/operation/SQLOperation.java +++ b/newrelic-security-api/src/main/java/com/newrelic/api/agent/security/schema/operation/SQLOperation.java @@ -17,6 +17,7 @@ public class SQLOperation extends AbstractOperation { private String dbName = "UNKNOWN"; private boolean isPreparedCall; + private boolean isStoredProcedureCall; public SQLOperation(String className, String methodName) { super(className, methodName); @@ -91,5 +92,13 @@ public void setDbName(String dbName) { this.dbName = dbName; } } + + public boolean isStoredProcedureCall() { + return isStoredProcedureCall; + } + + public void setStoredProcedureCall(boolean storedProcedureCall) { + isStoredProcedureCall = storedProcedureCall; + } }