Skip to content

Commit 6d2c673

Browse files
authored
Update metrics: appsec.waf.requests (#8353)
* Add waf_error tag to appsec.waf.requests metric
1 parent 85ac63b commit 6d2c673

File tree

9 files changed

+325
-84
lines changed

9 files changed

+325
-84
lines changed

.circleci/config.continue.yml.j2

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ instrumentation_modules: &instrumentation_modules "dd-java-agent/instrumentation
3636
debugger_modules: &debugger_modules "dd-java-agent/agent-debugger|dd-java-agent/agent-bootstrap|dd-java-agent/agent-builder|internal-api|communication|dd-trace-core"
3737
profiling_modules: &profiling_modules "dd-java-agent/agent-profiling"
3838

39-
default_system_tests_commit: &default_system_tests_commit 315bc8a32cc888834726397f088336ba8038277f
39+
default_system_tests_commit: &default_system_tests_commit d4974a9d88a10a70a8688afd08697affb5e82261
4040

4141
parameters:
4242
nightly:

dd-java-agent/appsec/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ dependencies {
1515
implementation project(':internal-api')
1616
implementation project(':communication')
1717
implementation project(':telemetry')
18-
implementation group: 'io.sqreen', name: 'libsqreen', version: '11.2.0'
18+
implementation group: 'io.sqreen', name: 'libsqreen', version: '12.0.0'
1919
implementation libs.moshi
2020

2121
testImplementation libs.bytebuddy
@@ -68,6 +68,7 @@ ext {
6868
excludedClassesCoverage = [
6969
'com.datadog.appsec.config.MergedAsmData.InvalidAsmDataException',
7070
'com.datadog.appsec.powerwaf.LibSqreenInitialization',
71+
'com.datadog.appsec.powerwaf.PowerWAFModule.PowerWAFDataCallback',
7172
'com.datadog.appsec.report.*',
7273
'com.datadog.appsec.config.AppSecConfigServiceImpl.SubscribeFleetServiceRunnable.1',
7374
'com.datadog.appsec.util.StandardizedLogging',
@@ -87,7 +88,6 @@ ext {
8788
'com.datadog.appsec.config.CurrentAppSecConfig',
8889
// equals() / hashCode() are not well covered
8990
'com.datadog.appsec.config.AppSecConfig.Helper',
90-
'com.datadog.appsec.powerwaf.PowerWAFModule.PowerWAFDataCallback',
9191
'com.datadog.appsec.powerwaf.PowerWAFModule.PowerWAFEventsCallback',
9292
// assert never fails
9393
'com.datadog.appsec.util.StandardizedLogging',

dd-java-agent/appsec/src/main/java/com/datadog/appsec/powerwaf/PowerWAFModule.java

+48-17
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import datadog.trace.api.gateway.Flow;
3131
import datadog.trace.api.telemetry.LogCollector;
3232
import datadog.trace.api.telemetry.WafMetricCollector;
33+
import datadog.trace.api.telemetry.WafTruncatedType;
3334
import datadog.trace.api.time.SystemTimeSource;
3435
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
3536
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
@@ -445,6 +446,7 @@ public void onDataAvailable(
445446
if (!reqCtx.isAdditiveClosed()) {
446447
log.error("Error calling WAF", e);
447448
}
449+
WafMetricCollector.get().wafRequestError();
448450
return;
449451
} catch (AbstractPowerwafException e) {
450452
if (gwCtx.isRasp) {
@@ -460,6 +462,27 @@ public void onDataAvailable(
460462
long elapsed = System.currentTimeMillis() - start;
461463
StandardizedLogging.finishedExecutionWAF(log, elapsed);
462464
}
465+
if (!gwCtx.isRasp) {
466+
PowerwafMetrics wafMetrics = reqCtx.getWafMetrics();
467+
if (wafMetrics != null) {
468+
final long stringTooLong = wafMetrics.getTruncatedStringTooLongCount();
469+
final long listMapTooLarge = wafMetrics.getTruncatedListMapTooLargeCount();
470+
final long objectTooDeep = wafMetrics.getTruncatedObjectTooDeepCount();
471+
472+
if (stringTooLong > 0) {
473+
WafMetricCollector.get()
474+
.wafInputTruncated(WafTruncatedType.STRING_TOO_LONG, stringTooLong);
475+
}
476+
if (listMapTooLarge > 0) {
477+
WafMetricCollector.get()
478+
.wafInputTruncated(WafTruncatedType.LIST_MAP_TOO_LARGE, listMapTooLarge);
479+
}
480+
if (objectTooDeep > 0) {
481+
WafMetricCollector.get()
482+
.wafInputTruncated(WafTruncatedType.OBJECT_TOO_DEEP, objectTooDeep);
483+
}
484+
}
485+
}
463486
}
464487

465488
StandardizedLogging.inAppWafReturn(log, resultWithData);
@@ -495,29 +518,35 @@ public void onDataAvailable(
495518
}
496519
} else {
497520
log.info("Ignoring action with type {}", actionInfo.type);
521+
WafMetricCollector.get().wafRequestBlockFailure();
498522
}
499523
}
500524
Collection<AppSecEvent> events = buildEvents(resultWithData);
501525

502-
if (!events.isEmpty() && !reqCtx.isThrottled(rateLimiter)) {
503-
AgentSpan activeSpan = AgentTracer.get().activeSpan();
504-
if (activeSpan != null) {
505-
log.debug("Setting force-keep tag on the current span");
506-
// Keep event related span, because it could be ignored in case of
507-
// reduced datadog sampling rate.
508-
activeSpan.getLocalRootSpan().setTag(Tags.ASM_KEEP, true);
509-
// If APM is disabled, inform downstream services that the current
510-
// distributed trace contains at least one ASM event and must inherit
511-
// the given force-keep priority
512-
activeSpan
513-
.getLocalRootSpan()
514-
.setTag(Tags.PROPAGATED_TRACE_SOURCE, ProductTraceSource.ASM);
526+
if (!events.isEmpty()) {
527+
if (!reqCtx.isThrottled(rateLimiter)) {
528+
AgentSpan activeSpan = AgentTracer.get().activeSpan();
529+
if (activeSpan != null) {
530+
log.debug("Setting force-keep tag on the current span");
531+
// Keep event related span, because it could be ignored in case of
532+
// reduced datadog sampling rate.
533+
activeSpan.getLocalRootSpan().setTag(Tags.ASM_KEEP, true);
534+
// If APM is disabled, inform downstream services that the current
535+
// distributed trace contains at least one ASM event and must inherit
536+
// the given force-keep priority
537+
activeSpan
538+
.getLocalRootSpan()
539+
.setTag(Tags.PROPAGATED_TRACE_SOURCE, ProductTraceSource.ASM);
540+
} else {
541+
// If active span is not available the ASM_KEEP tag will be set in the GatewayBridge
542+
// when the request ends
543+
log.debug("There is no active span available");
544+
}
545+
reqCtx.reportEvents(events);
515546
} else {
516-
// If active span is not available the ASK_KEEP tag will be set in the GatewayBridge
517-
// when the request ends
518-
log.debug("There is no active span available");
547+
log.debug("Rate limited WAF events");
548+
WafMetricCollector.get().wafRequestRateLimited();
519549
}
520-
reqCtx.reportEvents(events);
521550
}
522551

523552
if (flow.isBlocking()) {
@@ -551,6 +580,7 @@ private Flow.Action.RequestBlockingAction createBlockRequestAction(ActionInfo ac
551580
return new Flow.Action.RequestBlockingAction(statusCode, blockingContentType);
552581
} catch (RuntimeException cce) {
553582
log.warn("Invalid blocking action data", cce);
583+
WafMetricCollector.get().wafRequestBlockFailure();
554584
return null;
555585
}
556586
}
@@ -576,6 +606,7 @@ private Flow.Action.RequestBlockingAction createRedirectRequestAction(ActionInfo
576606
return Flow.Action.RequestBlockingAction.forRedirect(statusCode, location);
577607
} catch (RuntimeException cce) {
578608
log.warn("Invalid blocking action data", cce);
609+
WafMetricCollector.get().wafRequestBlockFailure();
579610
return null;
580611
}
581612
}

0 commit comments

Comments
 (0)