Skip to content

Commit fcaf1fb

Browse files
committed
Avoid log classes
1 parent 9306f2a commit fcaf1fb

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/data/ObjectIntrospection.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,9 @@ private static Object doConversion(Object obj, int depth, State state) {
290290
if (f.getType().getName().equals("groovy.lang.MetaClass")) {
291291
continue;
292292
}
293+
if (isLoggingType(f.getType())) {
294+
continue;
295+
}
293296
String name = f.getName();
294297
if (ignoredFieldName(name)) {
295298
continue;
@@ -315,6 +318,20 @@ private static Object doConversion(Object obj, int depth, State state) {
315318
return newMap;
316319
}
317320

321+
private static boolean isLoggingType(final Class<?> type) {
322+
switch (type.getName()) {
323+
case "org.slf4j.Logger":
324+
case "org.apache.logging.log4j.Logger":
325+
case "org.apache.logging.log4j.core.Logger":
326+
case "java.util.logging.Logger":
327+
case "org.apache.commons.logging.Log":
328+
case "ch.qos.logback.classic.Logger":
329+
return true;
330+
default:
331+
return false;
332+
}
333+
}
334+
318335
private static boolean ignoredFieldName(final String name) {
319336
switch (name) {
320337
case "this$0":

dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/event/data/ObjectIntrospectionSpecification.groovy

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,30 @@ class ObjectIntrospectionSpecification extends DDSpecification {
488488
MAPPER.readTree('"unicode: \\u0041"') || 'unicode: A'
489489
}
490490

491+
void 'logging framework fields are excluded from introspection'() {
492+
given: 'a DTO with a logger instance field alongside regular fields'
493+
// Reproduces the false positive in crs-944-130: an instance logger field on the request
494+
// body DTO causes ObjectIntrospection to traverse logging framework internals (Log4j,
495+
// Jackson TypeCache), eventually hitting java.lang.Class.toString() = "class java.lang.Object"
496+
// which matches the WAF phrase_match rule. Skipping logging-typed fields cuts the traversal
497+
// at the root and eliminates the false positive without discarding other useful fields.
498+
def input = new DtoWithLogger()
499+
500+
when:
501+
def result = convert(input, ctx) as Map
502+
503+
then:
504+
result['userId'] == 'user123'
505+
result['payload'] == 'data'
506+
!result.containsKey('logger')
507+
}
508+
509+
static class DtoWithLogger {
510+
String userId = 'user123'
511+
java.util.logging.Logger logger = java.util.logging.Logger.getLogger('test')
512+
String payload = 'data'
513+
}
514+
491515
void 'objects with inaccessible JDK fields skip those fields rather than expose toString()'() {
492516
given: '''An object with two fields: one normal, one holding a java.lang.ref.SoftReference.
493517
java.lang.ref is NOT opened in the test JVM (only java.lang and java.util are),

0 commit comments

Comments
 (0)