Skip to content

Commit eb328ea

Browse files
committed
addition for standalone mode
Signed-off-by: sezen.leblay <sezen.leblay@datadoghq.com>
1 parent 935b340 commit eb328ea

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

dd-smoke-tests/apm-tracing-disabled/src/test/groovy/datadog/smoketest/apmtracingdisabled/ApmTracingDisabledSamplingSmokeTest.groovy

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff 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
}

dd-trace-core/src/main/java/datadog/trace/common/sampling/AsmStandaloneSampler.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static datadog.trace.api.sampling.PrioritySampling.SAMPLER_DROP;
44
import static datadog.trace.api.sampling.PrioritySampling.SAMPLER_KEEP;
55

6+
import datadog.trace.api.sampling.PrioritySampling;
67
import datadog.trace.api.sampling.SamplingMechanism;
78
import datadog.trace.core.CoreSpan;
89
import 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());

dd-trace-core/src/test/groovy/datadog/trace/common/sampling/AsmStandaloneSamplerTest.groovy

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff 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
}

0 commit comments

Comments
 (0)