File tree Expand file tree Collapse file tree 3 files changed +65
-0
lines changed
dd-smoke-tests/apm-tracing-disabled/src/test/groovy/datadog/smoketest/apmtracingdisabled
main/java/datadog/trace/common/sampling
test/groovy/datadog/trace/common/sampling Expand file tree Collapse file tree 3 files changed +65
-0
lines changed Original file line number Diff line number Diff line change @@ -134,4 +134,33 @@ class ApmTracingDisabledSamplingSmokeTest extends AbstractApmTracingDisabledSmok
134134 def downstreamHeaders = jsonSlurper. parseText(response. body(). string())
135135 downstreamHeaders[" x-datadog-sampling-priority" ] == " 2"
136136 }
137+
138+ void ' test WAF attack preserves USER_KEEP priority in standalone mode' () {
139+ setup :
140+ // Use Arachni User-Agent to trigger WAF attack (same as system test)
141+ final wafAttackUrl = " http://localhost:${ httpPorts[0]} /rest-api/greetings"
142+ final wafAttackRequest = new Request.Builder ()
143+ .url(wafAttackUrl)
144+ .header(" User-Agent" , " Arachni/v1" )
145+ .get()
146+ .build()
147+
148+ when : " WAF attack is detected"
149+ final wafResponse = client. newCall(wafAttackRequest). execute()
150+
151+ then : " WAF attack should result in USER_KEEP priority (not overridden by AsmStandaloneSampler)"
152+ // Response might be blocked (403) or allowed depending on WAF mode, but span should still be generated
153+ wafResponse. code() in [200 , 403 ]
154+ waitForTraceCount(1 )
155+ assert traces. size() == 1
156+
157+ and : " Root span should have USER_KEEP priority and appsec.event=true"
158+ checkRootSpanPrioritySampling(traces[0 ], PrioritySampling . USER_KEEP )
159+ hasAppsecPropagationTag(traces[0 ])
160+
161+ // Verify appsec.event tag is set to "true"
162+ def rootSpan = traces[0 ]. spans. find { it. parentId == 0 }
163+ assert rootSpan != null
164+ assert rootSpan. meta[" appsec.event" ] == " true"
165+ }
137166}
Original file line number Diff line number Diff line change 33import static datadog .trace .api .sampling .PrioritySampling .SAMPLER_DROP ;
44import static datadog .trace .api .sampling .PrioritySampling .SAMPLER_KEEP ;
55
6+ import datadog .trace .api .sampling .PrioritySampling ;
67import datadog .trace .api .sampling .SamplingMechanism ;
78import datadog .trace .core .CoreSpan ;
89import java .time .Clock ;
@@ -39,6 +40,13 @@ public <T extends CoreSpan<T>> boolean sample(final T span) {
3940
4041 @ Override
4142 public <T extends CoreSpan <T >> void setSamplingPriority (final T span ) {
43+ // Check if the span already has USER_KEEP priority (e.g., from asm.keep tag)
44+ // If so, preserve it instead of overriding with SAMPLER_KEEP/SAMPLER_DROP
45+ int currentPriority = span .samplingPriority ();
46+ if (currentPriority == PrioritySampling .USER_KEEP ) {
47+ log .debug ("Preserving existing USER_KEEP priority for span {}" , span .getSpanId ());
48+ return ;
49+ }
4250
4351 if (shouldSample ()) {
4452 log .debug ("Set SAMPLER_KEEP for span {}" , span .getSpanId ());
Original file line number Diff line number Diff line change @@ -52,4 +52,32 @@ class AsmStandaloneSamplerTest extends DDCoreSpecification{
5252 tracer. close()
5353 }
5454
55+ void " test setSamplingPriority preserves existing USER_KEEP priority" (){
56+ setup :
57+ def current = new AtomicLong (System . currentTimeMillis())
58+ final Clock clock = Mock (Clock ) {
59+ millis() >> {
60+ current. get()
61+ }
62+ }
63+ def sampler = new AsmStandaloneSampler (clock)
64+ def tracer = tracerBuilder(). writer(writer). sampler(sampler). build()
65+
66+ when : " span already has USER_KEEP priority (e.g., from asm.keep tag)"
67+ def span = tracer. buildSpan(" test" ). start()
68+ span. setSamplingPriority(PrioritySampling . USER_KEEP , datadog.trace.api.sampling.SamplingMechanism . APPSEC )
69+
70+ and : " AsmStandaloneSampler tries to set its own priority"
71+ sampler. setSamplingPriority(span)
72+
73+ then : " USER_KEEP priority should be preserved, not overridden"
74+ span. getSamplingPriority() == PrioritySampling . USER_KEEP
75+
76+ and : " clock should not be called since we return early"
77+ 0 * clock. millis()
78+
79+ cleanup :
80+ tracer. close()
81+ }
82+
5583}
You can’t perform that action at this time.
0 commit comments