Skip to content

Commit c233763

Browse files
committed
Rework metric appsec.waf.requests
1 parent 5f4cc62 commit c233763

File tree

6 files changed

+229
-285
lines changed

6 files changed

+229
-285
lines changed

dd-java-agent/appsec/src/main/java/com/datadog/appsec/ddwaf/WAFModule.java

+29-26
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import datadog.trace.api.gateway.Flow;
4141
import datadog.trace.api.telemetry.LogCollector;
4242
import datadog.trace.api.telemetry.WafMetricCollector;
43-
import datadog.trace.api.telemetry.WafTruncatedType;
4443
import datadog.trace.api.time.SystemTimeSource;
4544
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
4645
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
@@ -440,20 +439,17 @@ public void onDataAvailable(
440439
WafMetricCollector.get().raspTimeout(gwCtx.raspRuleType);
441440
} else {
442441
reqCtx.increaseWafTimeouts();
443-
WafMetricCollector.get().wafRequestTimeout();
444442
log.debug(LogCollector.EXCLUDE_TELEMETRY, "Timeout calling the WAF", tpe);
445443
}
446444
return;
447445
} catch (UnclassifiedWafException e) {
448446
if (!reqCtx.isWafContextClosed()) {
449447
log.error("Error calling WAF", e);
450448
}
451-
// TODO this is wrong and will be fixed in another PR
452-
WafMetricCollector.get().wafRequestError();
453449
incrementErrorCodeMetric(gwCtx, e.code);
454450
return;
455451
} catch (AbstractWafException e) {
456-
incrementErrorCodeMetric(gwCtx, e.code);
452+
incrementErrorCodeMetric(reqCtx, gwCtx, e.code);
457453
return;
458454
} finally {
459455
if (log.isDebugEnabled()) {
@@ -467,17 +463,8 @@ public void onDataAvailable(
467463
final long listMapTooLarge = wafMetrics.getTruncatedListMapTooLargeCount();
468464
final long objectTooDeep = wafMetrics.getTruncatedObjectTooDeepCount();
469465

470-
if (stringTooLong > 0) {
471-
WafMetricCollector.get()
472-
.wafInputTruncated(WafTruncatedType.STRING_TOO_LONG, stringTooLong);
473-
}
474-
if (listMapTooLarge > 0) {
475-
WafMetricCollector.get()
476-
.wafInputTruncated(WafTruncatedType.LIST_MAP_TOO_LARGE, listMapTooLarge);
477-
}
478-
if (objectTooDeep > 0) {
479-
WafMetricCollector.get()
480-
.wafInputTruncated(WafTruncatedType.OBJECT_TOO_DEEP, objectTooDeep);
466+
if (stringTooLong > 0 || listMapTooLarge > 0 || objectTooDeep > 0) {
467+
reqCtx.setWafTruncated();
481468
}
482469
}
483470
}
@@ -501,10 +488,12 @@ public void onDataAvailable(
501488
ActionInfo actionInfo = new ActionInfo(actionType, actionParams);
502489

503490
if ("block_request".equals(actionInfo.type)) {
504-
Flow.Action.RequestBlockingAction rba = createBlockRequestAction(actionInfo);
491+
Flow.Action.RequestBlockingAction rba =
492+
createBlockRequestAction(actionInfo, reqCtx, gwCtx.isRasp);
505493
flow.setAction(rba);
506494
} else if ("redirect_request".equals(actionInfo.type)) {
507-
Flow.Action.RequestBlockingAction rba = createRedirectRequestAction(actionInfo);
495+
Flow.Action.RequestBlockingAction rba =
496+
createRedirectRequestAction(actionInfo, reqCtx, gwCtx.isRasp);
508497
flow.setAction(rba);
509498
} else if ("generate_stack".equals(actionInfo.type)) {
510499
if (Config.get().isAppSecStackTraceEnabled()) {
@@ -516,7 +505,9 @@ public void onDataAvailable(
516505
}
517506
} else {
518507
log.info("Ignoring action with type {}", actionInfo.type);
519-
WafMetricCollector.get().wafRequestBlockFailure();
508+
if (!gwCtx.isRasp) {
509+
reqCtx.setWafRequestBlockFailure();
510+
}
520511
}
521512
}
522513
Collection<AppSecEvent> events = buildEvents(resultWithData);
@@ -543,12 +534,16 @@ public void onDataAvailable(
543534
reqCtx.reportEvents(events);
544535
} else {
545536
log.debug("Rate limited WAF events");
546-
WafMetricCollector.get().wafRequestRateLimited();
537+
if (!gwCtx.isRasp) {
538+
reqCtx.setWafRateLimited();
539+
}
547540
}
548541
}
549542

550543
if (flow.isBlocking()) {
551-
reqCtx.setBlocked();
544+
if (!gwCtx.isRasp) {
545+
reqCtx.setWafBlocked();
546+
}
552547
}
553548
}
554549

@@ -557,7 +552,8 @@ public void onDataAvailable(
557552
}
558553
}
559554

560-
private Flow.Action.RequestBlockingAction createBlockRequestAction(ActionInfo actionInfo) {
555+
private Flow.Action.RequestBlockingAction createBlockRequestAction(
556+
final ActionInfo actionInfo, final AppSecRequestContext reqCtx, final boolean isRasp) {
561557
try {
562558
int statusCode;
563559
Object statusCodeObj = actionInfo.parameters.get("status_code");
@@ -578,12 +574,15 @@ private Flow.Action.RequestBlockingAction createBlockRequestAction(ActionInfo ac
578574
return new Flow.Action.RequestBlockingAction(statusCode, blockingContentType);
579575
} catch (RuntimeException cce) {
580576
log.warn("Invalid blocking action data", cce);
581-
WafMetricCollector.get().wafRequestBlockFailure();
577+
if (!isRasp) {
578+
reqCtx.setWafRequestBlockFailure();
579+
}
582580
return null;
583581
}
584582
}
585583

586-
private Flow.Action.RequestBlockingAction createRedirectRequestAction(ActionInfo actionInfo) {
584+
private Flow.Action.RequestBlockingAction createRedirectRequestAction(
585+
final ActionInfo actionInfo, final AppSecRequestContext reqCtx, final boolean isRasp) {
587586
try {
588587
int statusCode;
589588
Object statusCodeObj = actionInfo.parameters.get("status_code");
@@ -604,7 +603,9 @@ private Flow.Action.RequestBlockingAction createRedirectRequestAction(ActionInfo
604603
return Flow.Action.RequestBlockingAction.forRedirect(statusCode, location);
605604
} catch (RuntimeException cce) {
606605
log.warn("Invalid blocking action data", cce);
607-
WafMetricCollector.get().wafRequestBlockFailure();
606+
if (!isRasp) {
607+
reqCtx.setWafRequestBlockFailure();
608+
}
608609
return null;
609610
}
610611
}
@@ -649,11 +650,13 @@ private Waf.ResultWithData runWafContext(
649650
}
650651
}
651652

652-
private static void incrementErrorCodeMetric(GatewayContext gwCtx, int code) {
653+
private static void incrementErrorCodeMetric(
654+
AppSecRequestContext reqCtx, GatewayContext gwCtx, int code) {
653655
if (gwCtx.isRasp) {
654656
WafMetricCollector.get().raspErrorCode(gwCtx.raspRuleType, code);
655657
} else {
656658
WafMetricCollector.get().wafErrorCode(code);
659+
reqCtx.setWafErrors();
657660
}
658661
}
659662

dd-java-agent/appsec/src/main/java/com/datadog/appsec/gateway/AppSecRequestContext.java

+43-5
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,13 @@ public class AppSecRequestContext implements DataBundle, Closeable {
119119
private volatile WafMetrics wafMetrics;
120120
private volatile WafMetrics raspMetrics;
121121
private final AtomicInteger raspMetricsCounter = new AtomicInteger(0);
122-
private volatile boolean blocked;
122+
123+
private volatile boolean wafBlocked;
124+
private volatile boolean wafErrors;
125+
private volatile boolean wafTruncated;
126+
private volatile boolean wafRequestBlockFailure;
127+
private volatile boolean wafRateLimited;
128+
123129
private volatile int wafTimeouts;
124130
private volatile int raspTimeouts;
125131

@@ -174,12 +180,44 @@ public AtomicInteger getRaspMetricsCounter() {
174180
return raspMetricsCounter;
175181
}
176182

177-
public void setBlocked() {
178-
this.blocked = true;
183+
public void setWafBlocked() {
184+
this.wafBlocked = true;
185+
}
186+
187+
public boolean isWafBlocked() {
188+
return wafBlocked;
189+
}
190+
191+
public void setWafErrors() {
192+
this.wafErrors = true;
193+
}
194+
195+
public boolean hasWafErrors() {
196+
return wafErrors;
197+
}
198+
199+
public void setWafTruncated() {
200+
this.wafTruncated = true;
201+
}
202+
203+
public boolean isWafTruncated() {
204+
return wafTruncated;
205+
}
206+
207+
public void setWafRequestBlockFailure() {
208+
this.wafRequestBlockFailure = true;
209+
}
210+
211+
public boolean isWafRequestBlockFailure() {
212+
return wafRequestBlockFailure;
213+
}
214+
215+
public void setWafRateLimited() {
216+
this.wafRateLimited = true;
179217
}
180218

181-
public boolean isBlocked() {
182-
return blocked;
219+
public boolean isWafRateLimited() {
220+
return wafRateLimited;
183221
}
184222

185223
public void increaseWafTimeouts() {

dd-java-agent/appsec/src/main/java/com/datadog/appsec/gateway/GatewayBridge.java

+10-7
Original file line numberDiff line numberDiff line change
@@ -724,13 +724,16 @@ private NoopFlow onRequestEnded(RequestContext ctx_, IGSpanInfo spanInfo) {
724724
log.debug("Unable to commit, derivatives will be skipped {}", ctx.getDerivativeKeys());
725725
}
726726

727-
if (ctx.isBlocked()) {
728-
WafMetricCollector.get().wafRequestBlocked();
729-
} else if (!collectedEvents.isEmpty()) {
730-
WafMetricCollector.get().wafRequestTriggered();
731-
} else {
732-
WafMetricCollector.get().wafRequest();
733-
}
727+
WafMetricCollector.get()
728+
.wafRequest(
729+
!collectedEvents.isEmpty(), // ruleTriggered
730+
ctx.isWafBlocked(), // requestBlocked
731+
ctx.hasWafErrors(), // wafError
732+
ctx.getWafTimeouts() > 0, // wafTimeout,
733+
ctx.isWafRequestBlockFailure(), // blockFailure,
734+
ctx.isWafRateLimited(), // rateLimited,
735+
ctx.isWafTruncated() // inputTruncated
736+
);
734737
}
735738

736739
ctx.close();

dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/ddwaf/WAFModuleSpecification.groovy

+6-7
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ class WAFModuleSpecification extends DDSpecification {
475475
2 * ctx.getWafMetrics()
476476
1 * ctx.isWafContextClosed() >> false
477477
1 * ctx.closeWafContext() >> { wafContext.close() }
478-
1 * ctx.setBlocked()
478+
1 * ctx.setWafBlocked()
479479
1 * ctx.isThrottled(null)
480480
0 * _
481481

@@ -560,7 +560,7 @@ class WAFModuleSpecification extends DDSpecification {
560560
2 * ctx.getWafMetrics()
561561
1 * ctx.isWafContextClosed() >> false
562562
1 * ctx.closeWafContext()
563-
1 * ctx.setBlocked()
563+
1 * ctx.setWafBlocked()
564564
1 * ctx.isThrottled(null)
565565
0 * _
566566
}
@@ -665,7 +665,7 @@ class WAFModuleSpecification extends DDSpecification {
665665
1 * ctx.isWafContextClosed() >> false
666666
1 * ctx.closeWafContext()
667667
1 * ctx.reportEvents(_)
668-
1 * ctx.setBlocked()
668+
1 * ctx.setWafBlocked()
669669
1 * ctx.isThrottled(null)
670670
0 * ctx._(*_)
671671
flow.blocking == true
@@ -731,7 +731,7 @@ class WAFModuleSpecification extends DDSpecification {
731731
1 * ctx.isWafContextClosed() >> false
732732
1 * ctx.closeWafContext()
733733
1 * ctx.reportEvents(_)
734-
1 * ctx.setBlocked()
734+
1 * ctx.setWafBlocked()
735735
1 * ctx.isThrottled(null)
736736
0 * ctx._(*_)
737737
flow.blocking == true
@@ -758,7 +758,7 @@ class WAFModuleSpecification extends DDSpecification {
758758
1 * ctx.isWafContextClosed() >> false
759759
1 * ctx.closeWafContext()
760760
1 * ctx.reportEvents(_)
761-
1 * ctx.setBlocked()
761+
1 * ctx.setWafBlocked()
762762
1 * ctx.isThrottled(null)
763763
0 * ctx._(*_)
764764
metrics == null
@@ -817,7 +817,7 @@ class WAFModuleSpecification extends DDSpecification {
817817
}
818818
2 * ctx.getWafMetrics() >> metrics
819819
1 * ctx.reportEvents(*_)
820-
1 * ctx.setBlocked()
820+
1 * ctx.setWafBlocked()
821821
1 * ctx.isThrottled(null)
822822
1 * ctx.isWafContextClosed() >> false
823823
0 * ctx._(*_)
@@ -1016,7 +1016,6 @@ class WAFModuleSpecification extends DDSpecification {
10161016
wafContext = it[0].openContext() }
10171017
2 * ctx.getWafMetrics()
10181018
1 * ctx.increaseWafTimeouts()
1019-
1 * wafMetricCollector.get().wafRequestTimeout()
10201019
0 * _
10211020
10221021
when:

0 commit comments

Comments
 (0)