Skip to content

Commit f9b366c

Browse files
committed
GRD-106525 fix Neo4j outofbounds exception
1 parent dead536 commit f9b366c

3 files changed

Lines changed: 1094 additions & 1065 deletions

File tree

filter-plugin/logstash-filter-neo4j-guardium/src/main/java/com/ibm/guardium/neodb/NeodbGuardiumFilter.java

Lines changed: 140 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.text.ParseException;
1010
import java.util.Collection;
1111
import java.util.Collections;
12+
1213
import com.google.gson.JsonElement;
1314
import org.apache.logging.log4j.LogManager;
1415
import org.apache.logging.log4j.Logger;
@@ -31,140 +32,142 @@
3132
@LogstashPlugin(name = "neodb_guardium_filter")
3233
public class NeodbGuardiumFilter implements Filter {
3334

34-
private static Logger logger = LogManager.getLogger(NeodbGuardiumFilter.class);
35-
36-
37-
public static final String LOG42_CONF = "log4j2uc.properties";
38-
static {
39-
try {
40-
String uc_etc = System.getenv("UC_ETC");
41-
LoggerContext context = (LoggerContext) LogManager.getContext(false);
42-
File file = new File(uc_etc + File.separator + LOG42_CONF);
43-
context.setConfigLocation(file.toURI());
44-
} catch (Exception e) {
45-
e.printStackTrace();
46-
}
47-
}
48-
49-
private String id;
50-
public static final PluginConfigSpec<String> SOURCE_CONFIG = PluginConfigSpec.stringSetting("source", "message");
51-
private static Logger log = LogManager.getLogger(NeodbGuardiumFilter.class);
52-
53-
public NeodbGuardiumFilter(String id, Configuration config, Context context) {
54-
this.id = id;
55-
}
56-
57-
@Override
58-
public Collection<PluginConfigSpec<?>> configSchema() {
59-
// should return a list of all configuration options for this plugin
60-
return Collections.singletonList(SOURCE_CONFIG);
61-
}
62-
63-
@Override
64-
public String getId() {
65-
return this.id;
66-
}
67-
68-
@Override
69-
public Collection<Event> filter(Collection<Event> events, FilterMatchListener matchListener) {
70-
71-
for (Event e : events) {
72-
if(logger.isDebugEnabled()){
73-
logger.debug("Event Now: {}", e.getData());
74-
}
75-
76-
try {
77-
JsonObject inputData = inputData(e);
78-
79-
if (isNotSystemGeneratedEvent(inputData)) {
80-
81-
Record record = Parser.parseRecord(inputData);
82-
83-
final GsonBuilder builder = new GsonBuilder();
84-
builder.serializeNulls();
85-
final Gson gson = builder.create();
86-
e.setField(GuardConstants.GUARDIUM_RECORD_FIELD_NAME, gson.toJson(record));
87-
88-
matchListener.filterMatched(e);
89-
} else {
90-
e.tag(Constants.LOGSTASH_TAG_SKIP_NOT_NEO);
91-
}
92-
93-
} catch (ParseException pe) {
94-
log.error("Neo4j filter: Error parsing neo4j event " + e.getField(Constants.MESSAGE).toString(), pe);
95-
e.tag(Constants.LOGSTASH_TAG_JSON_PARSE_ERROR);
96-
} catch (Exception exception) {
97-
log.error("Neo4j filter: Error parsing neo4j event " + e.getField(Constants.MESSAGE).toString(),
98-
exception);
99-
e.tag(Constants.LOGSTASH_TAG_JSON_PARSE_ERROR);
100-
}
101-
}
102-
return events;
103-
}
104-
105-
private boolean isNotSystemGeneratedEvent(JsonObject inputData) {
106-
if (inputData == null || !inputData.has(Constants.QUERY_STATEMENT)) {
107-
return false; // Treat as system-generated if missing QUERY_STATEMENT or inputData is null
108-
}
109-
110-
JsonElement queryElement = inputData.get(Constants.QUERY_STATEMENT);
111-
if (queryElement == null || queryElement.isJsonNull()) {
112-
return false; // Treat as system-generated if queryElement is null or JsonNull
113-
}
114-
115-
String queryStatement = queryElement.getAsString();
116-
if (queryStatement == null || queryStatement.isEmpty() || queryStatement.startsWith("EXPLAIN")) {
117-
return false; // Treat as system-generated if queryStatement is null, empty, or starts with "EXPLAIN"
118-
}
119-
120-
return true; // Otherwise, it is not a system-generated event
121-
}
122-
123-
private JsonObject inputData(Event e) {
124-
JsonObject data = new JsonObject();
125-
126-
if (e.getField(Constants.CLIENT_IP) != null
127-
&& !e.getField(Constants.CLIENT_IP).toString().isEmpty()) {
128-
data.addProperty(Constants.CLIENT_IP, e.getField(Constants.CLIENT_IP).toString());
129-
}
130-
if (e.getField(Constants.SERVER_IP) != null
131-
&& !e.getField(Constants.SERVER_IP).toString().isEmpty()) {
132-
data.addProperty(Constants.SERVER_IP, e.getField(Constants.SERVER_IP).toString());
133-
}
134-
if (e.getField(Constants.DB_PROTOCOL) != null
135-
&& e.getField(Constants.DB_PROTOCOL).toString().isEmpty()) {
136-
data.addProperty(Constants.DB_PROTOCOL, e.getField(Constants.DB_PROTOCOL).toString());
137-
}
138-
if (e.getField(Constants.TIMESTAMP) != null
139-
&& !e.getField(Constants.TIMESTAMP).toString().isEmpty()) {
140-
data.addProperty(Constants.TIMESTAMP, e.getField(Constants.TIMESTAMP).toString());
141-
}
142-
if (e.getField(Constants.LOG_LEVEL) != null
143-
&& !e.getField(Constants.LOG_LEVEL).toString().isEmpty()) {
144-
data.addProperty(Constants.LOG_LEVEL, e.getField(Constants.LOG_LEVEL).toString());
145-
}
146-
if (e.getField(Constants.DB_USER) != null && !e.getField(Constants.DB_USER).toString().isEmpty()) {
147-
data.addProperty(Constants.DB_USER, e.getField(Constants.DB_USER).toString());
148-
}
149-
if (e.getField(Constants.DB_NAME) != null && !e.getField(Constants.DB_NAME).toString().isEmpty()) {
150-
data.addProperty(Constants.DB_NAME, e.getField(Constants.DB_NAME).toString());
151-
}
152-
if (e.getField(Constants.SOURCE_PROGRAM) != null
153-
&& !e.getField(Constants.SOURCE_PROGRAM).toString().isEmpty()) {
154-
data.addProperty(Constants.SOURCE_PROGRAM, e.getField(Constants.SOURCE_PROGRAM).toString());
155-
}
156-
if (e.getField(Constants.QUERY_STATEMENT) != null
157-
&& !e.getField(Constants.QUERY_STATEMENT).toString().isEmpty()) {
158-
data.addProperty(Constants.QUERY_STATEMENT, e.getField(Constants.QUERY_STATEMENT).toString());
159-
}
160-
if (e.getField(Constants.SERVER_HOSTNAME) != null
161-
&& !e.getField(Constants.SERVER_HOSTNAME).toString().isEmpty()) {
162-
data.addProperty(Constants.SERVER_HOSTNAME, e.getField(Constants.SERVER_HOSTNAME).toString());
163-
}
164-
if (e.getField(Constants.MESSAGE) != null && !e.getField(Constants.MESSAGE).toString().isEmpty()) {
165-
data.addProperty(Constants.MESSAGE, e.getField(Constants.MESSAGE).toString());
166-
}
167-
return data;
168-
}
169-
170-
}
35+
private static Logger logger = LogManager.getLogger(NeodbGuardiumFilter.class);
36+
37+
38+
public static final String LOG42_CONF = "log4j2uc.properties";
39+
40+
static {
41+
try {
42+
String uc_etc = System.getenv("UC_ETC");
43+
LoggerContext context = (LoggerContext) LogManager.getContext(false);
44+
File file = new File(uc_etc + File.separator + LOG42_CONF);
45+
context.setConfigLocation(file.toURI());
46+
} catch (Exception e) {
47+
e.printStackTrace();
48+
}
49+
}
50+
51+
private String id;
52+
public static final PluginConfigSpec<String> SOURCE_CONFIG = PluginConfigSpec.stringSetting("source", "message");
53+
private static Logger log = LogManager.getLogger(NeodbGuardiumFilter.class);
54+
Parser parser = new Parser();
55+
56+
public NeodbGuardiumFilter(String id, Configuration config, Context context) {
57+
this.id = id;
58+
}
59+
60+
@Override
61+
public Collection<PluginConfigSpec<?>> configSchema() {
62+
// should return a list of all configuration options for this plugin
63+
return Collections.singletonList(SOURCE_CONFIG);
64+
}
65+
66+
@Override
67+
public String getId() {
68+
return this.id;
69+
}
70+
71+
@Override
72+
public Collection<Event> filter(Collection<Event> events, FilterMatchListener matchListener) {
73+
74+
for (Event e : events) {
75+
if (logger.isDebugEnabled()) {
76+
logger.debug("Event Now: {}", e.getData());
77+
}
78+
79+
try {
80+
JsonObject inputData = inputData(e);
81+
82+
if (isNotSystemGeneratedEvent(inputData)) {
83+
84+
Record record = parser.parseRecord(inputData);
85+
86+
final GsonBuilder builder = new GsonBuilder();
87+
builder.serializeNulls();
88+
final Gson gson = builder.create();
89+
e.setField(GuardConstants.GUARDIUM_RECORD_FIELD_NAME, gson.toJson(record));
90+
91+
matchListener.filterMatched(e);
92+
} else {
93+
e.tag(Constants.LOGSTASH_TAG_SKIP_NOT_NEO);
94+
}
95+
96+
} catch (ParseException pe) {
97+
log.error("Neo4j filter: Error parsing neo4j event " + e.getField(Constants.MESSAGE).toString(), pe);
98+
e.tag(Constants.LOGSTASH_TAG_JSON_PARSE_ERROR);
99+
} catch (Exception exception) {
100+
log.error("Neo4j filter: Error parsing neo4j event " + e.getField(Constants.MESSAGE).toString(),
101+
exception);
102+
e.tag(Constants.LOGSTASH_TAG_JSON_PARSE_ERROR);
103+
}
104+
}
105+
return events;
106+
}
107+
108+
private boolean isNotSystemGeneratedEvent(JsonObject inputData) {
109+
if (inputData == null || !inputData.has(Constants.QUERY_STATEMENT)) {
110+
return false; // Treat as system-generated if missing QUERY_STATEMENT or inputData is null
111+
}
112+
113+
JsonElement queryElement = inputData.get(Constants.QUERY_STATEMENT);
114+
if (queryElement == null || queryElement.isJsonNull()) {
115+
return false; // Treat as system-generated if queryElement is null or JsonNull
116+
}
117+
118+
String queryStatement = queryElement.getAsString();
119+
if (queryStatement == null || queryStatement.isEmpty() || queryStatement.startsWith("EXPLAIN")) {
120+
return false; // Treat as system-generated if queryStatement is null, empty, or starts with "EXPLAIN"
121+
}
122+
123+
return true; // Otherwise, it is not a system-generated event
124+
}
125+
126+
private JsonObject inputData(Event e) {
127+
JsonObject data = new JsonObject();
128+
129+
if (e.getField(Constants.CLIENT_IP) != null
130+
&& !e.getField(Constants.CLIENT_IP).toString().isEmpty()) {
131+
data.addProperty(Constants.CLIENT_IP, e.getField(Constants.CLIENT_IP).toString());
132+
}
133+
if (e.getField(Constants.SERVER_IP) != null
134+
&& !e.getField(Constants.SERVER_IP).toString().isEmpty()) {
135+
data.addProperty(Constants.SERVER_IP, e.getField(Constants.SERVER_IP).toString());
136+
}
137+
if (e.getField(Constants.DB_PROTOCOL) != null
138+
&& e.getField(Constants.DB_PROTOCOL).toString().isEmpty()) {
139+
data.addProperty(Constants.DB_PROTOCOL, e.getField(Constants.DB_PROTOCOL).toString());
140+
}
141+
if (e.getField(Constants.TIMESTAMP) != null
142+
&& !e.getField(Constants.TIMESTAMP).toString().isEmpty()) {
143+
data.addProperty(Constants.TIMESTAMP, e.getField(Constants.TIMESTAMP).toString());
144+
}
145+
if (e.getField(Constants.LOG_LEVEL) != null
146+
&& !e.getField(Constants.LOG_LEVEL).toString().isEmpty()) {
147+
data.addProperty(Constants.LOG_LEVEL, e.getField(Constants.LOG_LEVEL).toString());
148+
}
149+
if (e.getField(Constants.DB_USER) != null && !e.getField(Constants.DB_USER).toString().isEmpty()) {
150+
data.addProperty(Constants.DB_USER, e.getField(Constants.DB_USER).toString());
151+
}
152+
if (e.getField(Constants.DB_NAME) != null && !e.getField(Constants.DB_NAME).toString().isEmpty()) {
153+
data.addProperty(Constants.DB_NAME, e.getField(Constants.DB_NAME).toString());
154+
}
155+
if (e.getField(Constants.SOURCE_PROGRAM) != null
156+
&& !e.getField(Constants.SOURCE_PROGRAM).toString().isEmpty()) {
157+
data.addProperty(Constants.SOURCE_PROGRAM, e.getField(Constants.SOURCE_PROGRAM).toString());
158+
}
159+
if (e.getField(Constants.QUERY_STATEMENT) != null
160+
&& !e.getField(Constants.QUERY_STATEMENT).toString().isEmpty()) {
161+
data.addProperty(Constants.QUERY_STATEMENT, e.getField(Constants.QUERY_STATEMENT).toString());
162+
}
163+
if (e.getField(Constants.SERVER_HOSTNAME) != null
164+
&& !e.getField(Constants.SERVER_HOSTNAME).toString().isEmpty()) {
165+
data.addProperty(Constants.SERVER_HOSTNAME, e.getField(Constants.SERVER_HOSTNAME).toString());
166+
}
167+
if (e.getField(Constants.MESSAGE) != null && !e.getField(Constants.MESSAGE).toString().isEmpty()) {
168+
data.addProperty(Constants.MESSAGE, e.getField(Constants.MESSAGE).toString());
169+
}
170+
return data;
171+
}
172+
173+
}

0 commit comments

Comments
 (0)