Skip to content

Commit 80eed8e

Browse files
authored
Adapt standalone ASM to support API Security (#8804)
What Does This Do Fix conflict between ASM standalone and API Security sampling (traces were discarded as they don't have the ASM KEEP) Remove redundant ctx.setKeepOpenForApiSecurityPostProcessing call (it's already set to true in the APISecuritySampler)
1 parent be63fb9 commit 80eed8e

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.datadog.appsec.event.data.SingletonDataBundle;
2121
import com.datadog.appsec.report.AppSecEvent;
2222
import com.datadog.appsec.report.AppSecEventWrapper;
23+
import datadog.trace.api.Config;
2324
import datadog.trace.api.ProductTraceSource;
2425
import datadog.trace.api.gateway.Events;
2526
import datadog.trace.api.gateway.Flow;
@@ -668,7 +669,10 @@ private NoopFlow onRequestEnded(RequestContext ctx_, IGSpanInfo spanInfo) {
668669
Map<String, Object> tags = spanInfo.getTags();
669670

670671
if (maybeSampleForApiSecurity(ctx, spanInfo, tags)) {
671-
ctx.setKeepOpenForApiSecurityPostProcessing(true);
672+
if (!Config.get().isApmTracingEnabled()) {
673+
traceSeg.setTagTop(Tags.ASM_KEEP, true);
674+
traceSeg.setTagTop(Tags.PROPAGATED_TRACE_SOURCE, ProductTraceSource.ASM);
675+
}
672676
} else {
673677
ctx.closeWafContext();
674678
}

dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/gateway/GatewayBridgeSpecification.groovy

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import com.datadog.appsec.event.data.DataBundle
99
import com.datadog.appsec.event.data.KnownAddresses
1010
import com.datadog.appsec.report.AppSecEvent
1111
import com.datadog.appsec.report.AppSecEventWrapper
12+
import datadog.trace.api.ProductTraceSource
13+
import datadog.trace.api.config.GeneralConfig
14+
import static datadog.trace.api.config.IastConfig.IAST_DEDUPLICATION_ENABLED
1215
import datadog.trace.api.function.TriConsumer
1316
import datadog.trace.api.function.TriFunction
1417
import datadog.trace.api.gateway.BlockResponseFunction
@@ -22,6 +25,7 @@ import datadog.trace.api.internal.TraceSegment
2225
import datadog.trace.api.telemetry.LoginEvent
2326
import datadog.trace.api.telemetry.WafMetricCollector
2427
import datadog.trace.bootstrap.instrumentation.api.AgentSpan
28+
import datadog.trace.bootstrap.instrumentation.api.Tags
2529
import datadog.trace.bootstrap.instrumentation.api.URIDataAdapter
2630
import datadog.trace.bootstrap.instrumentation.api.URIDataAdapterBase
2731
import datadog.trace.test.util.DDSpecification
@@ -1162,4 +1166,60 @@ class GatewayBridgeSpecification extends DDSpecification {
11621166
1 * eventDispatcher.getDataSubscribers(KnownAddresses.SESSION_ID) >> nonEmptyDsInfo
11631167
1 * eventDispatcher.publishDataEvent(_, _, _, _)
11641168
}
1169+
1170+
void 'test api security sampling'() {
1171+
given:
1172+
AppSecRequestContext mockAppSecCtx = Mock(AppSecRequestContext)
1173+
RequestContext mockCtx = Stub(RequestContext) {
1174+
getData(RequestContextSlot.APPSEC) >> mockAppSecCtx
1175+
getTraceSegment() >> traceSegment
1176+
}
1177+
IGSpanInfo spanInfo = Mock(AgentSpan)
1178+
when:
1179+
def flow = requestEndedCB.apply(mockCtx, spanInfo)
1180+
then:
1181+
1 * mockAppSecCtx.transferCollectedEvents() >> []
1182+
1 * spanInfo.getTags() >> ['http.route': 'route']
1183+
1 * requestSampler.preSampleRequest(_) >> true
1184+
0 * traceSegment.setTagTop(Tags.ASM_KEEP, true)
1185+
0 * traceSegment.setTagTop(Tags.PROPAGATED_TRACE_SOURCE, ProductTraceSource.ASM)
1186+
}
1187+
1188+
void 'test api security sampling - trace excluded'() {
1189+
given:
1190+
AppSecRequestContext mockAppSecCtx = Mock(AppSecRequestContext)
1191+
RequestContext mockCtx = Stub(RequestContext) {
1192+
getData(RequestContextSlot.APPSEC) >> mockAppSecCtx
1193+
getTraceSegment() >> traceSegment
1194+
}
1195+
IGSpanInfo spanInfo = Mock(AgentSpan)
1196+
when:
1197+
def flow = requestEndedCB.apply(mockCtx, spanInfo)
1198+
then:
1199+
1 * mockAppSecCtx.transferCollectedEvents() >> []
1200+
1 * spanInfo.getTags() >> ['http.route': 'route']
1201+
1 * requestSampler.preSampleRequest(_) >> false
1202+
0 * traceSegment.setTagTop(Tags.ASM_KEEP, true)
1203+
0 * traceSegment.setTagTop(Tags.PROPAGATED_TRACE_SOURCE, ProductTraceSource.ASM)
1204+
}
1205+
1206+
void 'test api security sampling with tracing disabled'() {
1207+
given:
1208+
injectSysConfig(GeneralConfig.APM_TRACING_ENABLED, "false")
1209+
AppSecRequestContext mockAppSecCtx = Mock(AppSecRequestContext)
1210+
RequestContext mockCtx = Stub(RequestContext) {
1211+
getData(RequestContextSlot.APPSEC) >> mockAppSecCtx
1212+
getTraceSegment() >> traceSegment
1213+
}
1214+
IGSpanInfo spanInfo = Mock(AgentSpan)
1215+
when:
1216+
def flow = requestEndedCB.apply(mockCtx, spanInfo)
1217+
then:
1218+
1 * mockAppSecCtx.transferCollectedEvents() >> []
1219+
1 * spanInfo.getTags() >> ['http.route': 'route']
1220+
1 * requestSampler.preSampleRequest(_) >> true
1221+
1 * traceSegment.setTagTop(Tags.ASM_KEEP, true)
1222+
1 * traceSegment.setTagTop(Tags.PROPAGATED_TRACE_SOURCE, ProductTraceSource.ASM)
1223+
}
1224+
11651225
}

0 commit comments

Comments
 (0)