Skip to content

Commit 019fecb

Browse files
dougqhdevflow.devflow-routing-intake
andauthored
Fix AppSec/IAST context dropped when trace.propagation.behavior.extract=ignore/restart (#11666)
Fix AppSec/IAST context dropped when trace.propagation.behavior.extract=ignore/restart With IGNORE or RESTART, CoreSpanBuilder nulls the remote TagContext parent before buildSpanContext reaches the instanceof TagContext branch that copies requestContextDataAppSec/requestContextDataIast. The AppSec context is lost and GatewayBridge callbacks no-op, silently bypassing WAF/RASP for all inbound requests in AppSec-enabled services configured to ignore distributed tracing extraction. Fix: promote the AppSec/IAST data from the TagContext into the builder fields before nulling the parent. The builder-field path in buildSpanContext applies these after the parent is gone, preserving the request context while still correctly dropping trace identifiers and sampling priority. Fixes: APMSP-3198 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Apply spotless formatting Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Merge branch 'master' into dougqh/fix-appsec-context-extract-ignore Co-authored-by: devflow.devflow-routing-intake <devflow.devflow-routing-intake@kubernetes.us1.ddbuild.io>
1 parent 2489b79 commit 019fecb

2 files changed

Lines changed: 46 additions & 0 deletions

File tree

dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,6 +1790,18 @@ protected static final AgentSpan startSpan(
17901790

17911791
// Handle remote terminated span context as span links
17921792
if (parentSpanContext != null && parentSpanContext.isRemote()) {
1793+
// Preserve AppSec/IAST request context before dropping the remote parent: when
1794+
// extract=IGNORE or RESTART the TagContext parent is nulled before buildSpanContext
1795+
// can copy requestContextDataAppSec/Iast into DDSpanContext.
1796+
if (parentSpanContext instanceof TagContext) {
1797+
TagContext tc = (TagContext) parentSpanContext;
1798+
if (builderRequestContextDataAppSec == null) {
1799+
builderRequestContextDataAppSec = tc.getRequestContextDataAppSec();
1800+
}
1801+
if (builderRequestContextDataIast == null) {
1802+
builderRequestContextDataIast = tc.getRequestContextDataIast();
1803+
}
1804+
}
17931805
switch (Config.get().getTracePropagationBehaviorExtract()) {
17941806
case RESTART:
17951807
links = addParentSpanLink(links, parentSpanContext);

dd-trace-core/src/test/java/datadog/trace/core/CoreSpanBuilderTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,40 @@ void buildContextFromExtractedContextWithIgnoreBehavior() {
422422
assertTrue(span.getLinks().isEmpty());
423423
}
424424

425+
@Test
426+
@WithConfig(key = "trace.propagation.behavior.extract", value = "ignore")
427+
void appSecContextPreservedFromTagContextWithIgnoreBehavior() {
428+
Object appSecData = new Object();
429+
Object iastData = new Object();
430+
TagContext tagContext =
431+
new TagContext()
432+
.withRequestContextDataAppSec(appSecData)
433+
.withRequestContextDataIast(iastData);
434+
435+
DDSpan span = (DDSpan) tracer.buildSpan("test", "op name").asChildOf(tagContext).start();
436+
437+
assertEquals(appSecData, span.getRequestContext().getData(RequestContextSlot.APPSEC));
438+
assertEquals(iastData, span.getRequestContext().getData(RequestContextSlot.IAST));
439+
span.finish();
440+
}
441+
442+
@Test
443+
@WithConfig(key = "trace.propagation.behavior.extract", value = "restart")
444+
void appSecContextPreservedFromTagContextWithRestartBehavior() {
445+
Object appSecData = new Object();
446+
Object iastData = new Object();
447+
TagContext tagContext =
448+
new TagContext()
449+
.withRequestContextDataAppSec(appSecData)
450+
.withRequestContextDataIast(iastData);
451+
452+
DDSpan span = (DDSpan) tracer.buildSpan("test", "op name").asChildOf(tagContext).start();
453+
454+
assertEquals(appSecData, span.getRequestContext().getData(RequestContextSlot.APPSEC));
455+
assertEquals(iastData, span.getRequestContext().getData(RequestContextSlot.IAST));
456+
span.finish();
457+
}
458+
425459
@TableTest({
426460
"scenario | origin | tagMap ",
427461
"empty tag map | | [:] ",

0 commit comments

Comments
 (0)