From 09b77c3f3396eb18f10a7064743afc5f793120cc Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Tue, 22 Apr 2025 12:56:25 +0200 Subject: [PATCH 1/6] WIP --- .../datadog/appsec/gateway/GatewayBridge.java | 90 ++++++++--- .../gateway/GatewayBridgeSpecification.groovy | 92 +++++++++++ .../springboot/controller/WebController.java | 22 +++ .../ExtendedDataCollectionSmokeTest.groovy | 151 ++++++++++++++++++ .../AbstractAppSecServerSmokeTest.groovy | 4 + .../datadog/trace/api/ConfigDefaults.java | 1 + .../trace/api/config/AppSecConfig.java | 4 + .../main/java/datadog/trace/api/Config.java | 21 +++ 8 files changed, 366 insertions(+), 19 deletions(-) create mode 100644 dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy diff --git a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/gateway/GatewayBridge.java b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/gateway/GatewayBridge.java index 9ba2bdb07a3..1f5a2f62164 100644 --- a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/gateway/GatewayBridge.java +++ b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/gateway/GatewayBridge.java @@ -707,8 +707,15 @@ private NoopFlow onRequestEnded(RequestContext ctx_, IGSpanInfo spanInfo) { traceSeg.setDataTop("appsec", wrapper); // Report collected request and response headers based on allow list - writeRequestHeaders(traceSeg, REQUEST_HEADERS_ALLOW_LIST, ctx.getRequestHeaders()); - writeResponseHeaders(traceSeg, RESPONSE_HEADERS_ALLOW_LIST, ctx.getResponseHeaders()); + boolean collectAll = + Config.get().isAppSecCollectAllHeaders() + // Until redaction is defined we don't want to collect all headers due to risk of + // leaking sensitive data + && !Config.get().isAppSecHeaderCollectionRedactionEnabled(); + writeRequestHeaders( + traceSeg, REQUEST_HEADERS_ALLOW_LIST, ctx.getRequestHeaders(), collectAll); + writeResponseHeaders( + traceSeg, RESPONSE_HEADERS_ALLOW_LIST, ctx.getResponseHeaders(), collectAll); // Report collected stack traces List stackTraces = ctx.getStackTraces(); @@ -718,10 +725,11 @@ private NoopFlow onRequestEnded(RequestContext ctx_, IGSpanInfo spanInfo) { } else if (hasUserInfo(traceSeg)) { // Report all collected request headers on user tracking event - writeRequestHeaders(traceSeg, REQUEST_HEADERS_ALLOW_LIST, ctx.getRequestHeaders()); + writeRequestHeaders(traceSeg, REQUEST_HEADERS_ALLOW_LIST, ctx.getRequestHeaders(), false); } else { // Report minimum set of collected request headers - writeRequestHeaders(traceSeg, DEFAULT_REQUEST_HEADERS_ALLOW_LIST, ctx.getRequestHeaders()); + writeRequestHeaders( + traceSeg, DEFAULT_REQUEST_HEADERS_ALLOW_LIST, ctx.getRequestHeaders(), false); } // If extracted any derivatives - commit them if (!ctx.commitDerivatives(traceSeg)) { @@ -835,32 +843,76 @@ private static boolean hasUserCollectionEvent(final TraceSegment traceSeg) { private static void writeRequestHeaders( final TraceSegment traceSeg, final Set allowed, - final Map> headers) { - writeHeaders(traceSeg, "http.request.headers.", allowed, headers); + final Map> headers, + final boolean collectAll) { + writeHeaders( + traceSeg, "http.request.headers.", "_dd.appsec.request.", allowed, headers, collectAll); } private static void writeResponseHeaders( final TraceSegment traceSeg, final Set allowed, - final Map> headers) { - writeHeaders(traceSeg, "http.response.headers.", allowed, headers); + final Map> headers, + final boolean collectAll) { + writeHeaders( + traceSeg, "http.response.headers.", "_dd.appsec.response.", allowed, headers, collectAll); } private static void writeHeaders( final TraceSegment traceSeg, final String prefix, + final String discardedPrefix, final Set allowed, - final Map> headers) { - if (headers != null) { - headers.forEach( - (name, value) -> { - if (allowed.contains(name)) { - String v = String.join(",", value); - if (!v.isEmpty()) { - traceSeg.setTagTop(prefix + name, v); - } - } - }); + final Map> headers, + final boolean collectAll) { + + if (headers == null || headers.isEmpty()) { + return; + } + + final int headerLimit = Config.get().getAppsecMaxCollectedHeaders(); + final Set added = new HashSet<>(); + int excluded = 0; + + // Try to add allowed headers (prioritized) + for (String name : allowed) { + if (added.size() >= headerLimit) { + break; + } + List values = headers.get(name); + if (values != null) { + String joined = String.join(",", values); + if (!joined.isEmpty()) { + traceSeg.setTagTop(prefix + name, joined); + added.add(name); + } + } + } + + if (collectAll) { + // Add other headers (non-allowed) until total reaches the limit + for (Map.Entry> entry : headers.entrySet()) { + String name = entry.getKey(); + if (added.contains(name)) { + continue; + } + + if (added.size() >= headerLimit) { + excluded++; + continue; + } + + List values = entry.getValue(); + String joined = String.join(",", values); + if (!joined.isEmpty()) { + traceSeg.setTagTop(prefix + name, joined); + added.add(name); + } + } + + if (excluded > 0) { + traceSeg.setTagTop(discardedPrefix + "header_collection.discarded", excluded); + } } } diff --git a/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/gateway/GatewayBridgeSpecification.groovy b/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/gateway/GatewayBridgeSpecification.groovy index 4eb14da17dc..6839b7061b9 100644 --- a/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/gateway/GatewayBridgeSpecification.groovy +++ b/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/gateway/GatewayBridgeSpecification.groovy @@ -1222,4 +1222,96 @@ class GatewayBridgeSpecification extends DDSpecification { 1 * traceSegment.setTagTop(Tags.PROPAGATED_TRACE_SOURCE, ProductTraceSource.ASM) } + + void 'test default writeRequestHeaders'(){ + given: + def allowedHeaders = ['x-allowed-header', 'x-multiple-allowed-header', 'x-always-included'] as Set + def headers = [ + 'x-allowed-header' : ['value1'], + 'x-multiple-allowed-header' : ['value1A', 'value1B'], + 'x-other-header-1' : ['value2'], + 'x-other-header-2' : ['value3'], + 'x-other-header-3' : ['value4'] + ] + + when: + GatewayBridge.writeRequestHeaders(traceSegment, allowedHeaders, headers, false) + + then: + 1 * traceSegment.setTagTop('http.request.headers.x-allowed-header', 'value1') + 1 * traceSegment.setTagTop('http.request.headers.x-multiple-allowed-header', 'value1A,value1B') + 0 * traceSegment.setTagTop(_, _) + } + + void 'test default writeResponseHeaders'(){ + given: + def allowedHeaders = ['x-allowed-header', 'x-multiple-allowed-header', 'x-always-included'] as Set + def headers = [ + 'x-allowed-header' : ['value1'], + 'x-multiple-allowed-header' : ['value1A', 'value1B'], + 'x-other-header-1' : ['value2'], + 'x-other-header-2' : ['value3'], + 'x-other-header-3' : ['value4'] + ] + + when: + GatewayBridge.writeResponseHeaders(traceSegment, allowedHeaders, headers, false) + + then: + 1 * traceSegment.setTagTop('http.response.headers.x-allowed-header', 'value1') + 1 * traceSegment.setTagTop('http.response.headers.x-multiple-allowed-header', 'value1A,value1B') + 0 * traceSegment.setTagTop(_, _) + } + + void 'test writeRequestHeaders collecting all headers '(){ + setup: + injectEnvConfig('DD_APPSEC_MAX_COLLECTED_HEADERS', '4') + + def allowedHeaders = ['x-allowed-header', 'x-multiple-allowed-header', 'x-always-included'] as Set + def headers = [ + 'x-allowed-header' : ['value1'], + 'x-multiple-allowed-header' : ['value1A', 'value1B'], + 'x-other-header-1' : ['value2'], + 'x-other-header-2' : ['value3'], + 'x-other-header-3' : ['value4'] + ] + + when: + GatewayBridge.writeRequestHeaders(traceSegment, allowedHeaders, headers, true) + + then: + 1 * traceSegment.setTagTop('http.request.headers.x-allowed-header', 'value1') + 1 * traceSegment.setTagTop('http.request.headers.x-multiple-allowed-header', 'value1A,value1B') + 1 * traceSegment.setTagTop('http.request.headers.x-other-header-1', 'value2') + 1 * traceSegment.setTagTop('http.request.headers.x-other-header-2', 'value3') + 1 * traceSegment.setTagTop('_dd.appsec.request.header_collection.discarded', 1) + 0 * traceSegment.setTagTop(_, _) + } + + void 'test writeResponseHeaders collecting all headers '(){ + setup: + injectEnvConfig('DD_APPSEC_COLLECT_ALL_HEADERS' , 'true') + injectEnvConfig('DD_APPSEC_MAX_COLLECTED_HEADERS', '4') + + def allowedHeaders = ['x-allowed-header', 'x-multiple-allowed-header', 'x-always-included'] as Set + def headers = [ + 'x-allowed-header' : ['value1'], + 'x-multiple-allowed-header' : ['value1A', 'value1B'], + 'x-other-header-1' : ['value2'], + 'x-other-header-2' : ['value3'], + 'x-other-header-3' : ['value4'] + ] + + when: + GatewayBridge.writeResponseHeaders(traceSegment, allowedHeaders, headers, true) + + then: + 1 * traceSegment.setTagTop('http.response.headers.x-allowed-header', 'value1') + 1 * traceSegment.setTagTop('http.response.headers.x-multiple-allowed-header', 'value1A,value1B') + 1 * traceSegment.setTagTop('http.response.headers.x-other-header-1', 'value2') + 1 * traceSegment.setTagTop('http.response.headers.x-other-header-2', 'value3') + 1 * traceSegment.setTagTop('_dd.appsec.response.header_collection.discarded', 1) + 0 * traceSegment.setTagTop(_, _) + } + } diff --git a/dd-smoke-tests/appsec/springboot/src/main/java/datadog/smoketest/appsec/springboot/controller/WebController.java b/dd-smoke-tests/appsec/springboot/src/main/java/datadog/smoketest/appsec/springboot/controller/WebController.java index a71fa52b689..cabefb74e45 100644 --- a/dd-smoke-tests/appsec/springboot/src/main/java/datadog/smoketest/appsec/springboot/controller/WebController.java +++ b/dd-smoke-tests/appsec/springboot/src/main/java/datadog/smoketest/appsec/springboot/controller/WebController.java @@ -16,6 +16,7 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -210,6 +211,27 @@ public ResponseEntity apiSecuritySampling(@PathVariable("status_code") i return ResponseEntity.status(statusCode).body("EXECUTED"); } + @GetMapping("/custom-headers") + public ResponseEntity customHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.add("X-Test-Header-1", "value1"); + headers.add("X-Test-Header-2", "value2"); + headers.add("X-Test-Header-3", "value3"); + headers.add("X-Test-Header-4", "value4"); + headers.add("X-Test-Header-5", "value5"); + return new ResponseEntity<>("Custom headers added", headers, HttpStatus.OK); + } + + @GetMapping("/exceedResponseHeaders") + public ResponseEntity exceedResponseHeaders() { + HttpHeaders headers = new HttpHeaders(); + for (int i = 1; i <= 50; i++) { + headers.add("X-Test-Header-" + i, "value" + i); + } + headers.add("content-language", "en-US"); + return new ResponseEntity<>("Custom headers added", headers, HttpStatus.OK); + } + private void withProcess(final Operation op) { Process process = null; try { diff --git a/dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy b/dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy new file mode 100644 index 00000000000..da2862dce12 --- /dev/null +++ b/dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy @@ -0,0 +1,151 @@ +package datadog.smoketest.appsec + +import datadog.trace.agent.test.utils.OkHttpUtils +import okhttp3.Request + +class ExtendedDataCollectionSmokeTest extends AbstractAppSecServerSmokeTest { + + @Override + ProcessBuilder createProcessBuilder() { + + String springBootShadowJar = System.getProperty("datadog.smoketest.appsec.springboot.shadowJar.path") + + List command = new ArrayList<>() + command.add(javaPath()) + command.addAll(defaultJavaProperties) + command.addAll(defaultAppSecProperties) + command.add('-Ddd.appsec.collect.all.headers=true') + command.add('-Ddd.appsec.header.collection.redaction.enabled=false') + command.addAll((String[]) ["-jar", springBootShadowJar, "--server.port=${httpPort}"]) + + ProcessBuilder processBuilder = new ProcessBuilder(command) + processBuilder.directory(new File(buildDirectory)) + } + + + void 'test all headers'(){ + given: + def url = "http://localhost:${httpPort}/custom-headers" + def client = OkHttpUtils.clientBuilder().build() + def request = new Request.Builder() + .url(url) + .addHeader("User-Agent", "Arachni/v1") + .addHeader('X-My-Header-1', "value1") + .addHeader('X-My-Header-2', "value2") + .addHeader('X-My-Header-3', "value3") + .addHeader('X-My-Header-4', "value4") + .addHeader('Content-Type', "text/html") + .get() + .build() + + when: + def response = client.newCall(request).execute() + + then: + response.code()==200 + + when: + waitForTraceCount(1) + + then: + def rootSpans = this.rootSpans.toList() + rootSpans.size() == 1 + def rootSpan = rootSpans[0] + !rootSpan.metrics.containsKey('_dd.appsec.request.header_collection.discarded') + rootSpan.meta.get('http.request.headers.x-my-header-1') == 'value1' + rootSpan.meta.get('http.request.headers.x-my-header-2') == 'value2' + rootSpan.meta.get('http.request.headers.x-my-header-3') == 'value3' + rootSpan.meta.get('http.request.headers.x-my-header-4') == 'value4' + rootSpan.meta.get('http.request.headers.content-type') == 'text/html' + !rootSpan.metrics.containsKey('_dd.appsec.response.header_collection.discarded') + rootSpan.meta.get('http.response.headers.x-test-header-1') == 'value1' + rootSpan.meta.get('http.response.headers.x-test-header-2') == 'value2' + rootSpan.meta.get('http.response.headers.x-test-header-3') == 'value3' + rootSpan.meta.get('http.response.headers.x-test-header-4') == 'value4' + rootSpan.meta.get('http.response.headers.x-test-header-5') == 'value5' + } + + void 'No extended header collection if no appsec event'(){ + given: + def url = "http://localhost:${httpPort}/custom-headers" + def client = OkHttpUtils.clientBuilder().build() + def request = new Request.Builder() + .url(url) + .addHeader('X-My-Header-1', "value1") + .addHeader('X-My-Header-2', "value2") + .addHeader('X-My-Header-3', "value3") + .addHeader('X-My-Header-4', "value4") + .addHeader('Content-Type', "text/html") + .get() + .build() + + when: + def response = client.newCall(request).execute() + + then: + response.code()==200 + + when: + waitForTraceCount(1) + + then: + def rootSpans = this.rootSpans.toList() + rootSpans.size() == 1 + def rootSpan = rootSpans[0] + !rootSpan.metrics.containsKey('_dd.appsec.request.header_collection.discarded') + !rootSpan.metrics.containsKey('http.request.headers.x-my-header-1') + !rootSpan.metrics.containsKey('http.request.headers.x-my-header-2') + !rootSpan.metrics.containsKey('http.request.headers.x-my-header-3') + !rootSpan.metrics.containsKey('http.request.headers.x-my-header-4') + rootSpan.meta.get('http.request.headers.content-type') == 'text/html' + !rootSpan.metrics.containsKey('_dd.appsec.response.header_collection.discarded') + !rootSpan.metrics.containsKey('http.response.headers.x-test-header-1') + !rootSpan.metrics.containsKey('http.response.headers.x-test-header-2') + !rootSpan.metrics.containsKey('http.response.headers.x-test-header-3') + !rootSpan.metrics.containsKey('http.response.headers.x-test-header-4') + !rootSpan.metrics.containsKey('http.response.headers.x-test-header-5') + } + + void 'test header budget exceeded with 50 headers'() { + given: + def url = "http://localhost:${httpPort}/exceedResponseHeaders" + def client = OkHttpUtils.clientBuilder().build() + // Build request with 50 custom headers + def builder = new Request.Builder().url(url) + builder.addHeader("User-Agent", "Arachni/v1") + (1..50).each { i -> + builder.addHeader("X-My-Header-${i}", "value${i}") + } + // Include content-type to trigger parsing + builder.addHeader('Content-Type', 'text/html') + def request = builder.get().build() + + when: + def response = client.newCall(request).execute() + + then: + response.code() == 200 + + when: + waitForTraceCount(1) + + then: + def rootSpan = this.rootSpans.toList()[0] + // Check that the discarded metrics exists and are greater than 1 + rootSpan.metrics.containsKey('_dd.appsec.request.header_collection.discarded') + rootSpan.metrics['_dd.appsec.request.header_collection.discarded'] > 1 + rootSpan.metrics.containsKey('_dd.appsec.response.header_collection.discarded') + rootSpan.metrics['_dd.appsec.response.header_collection.discarded'] > 1 + // Ensure no more than 50 request headers collected + def headerRequestKeys = rootSpan.meta.keySet().findAll { it.startsWith('http.request.headers.') } + headerRequestKeys.size() <= 50 + def headerResponseKeys = rootSpan.meta.keySet().findAll { it.startsWith('http.response.headers.') } + headerResponseKeys.size() <= 50 + // Ensure allowed headers are collected + rootSpan.meta.get('http.request.headers.content-type') == 'text/html' + rootSpan.meta.get('http.response.headers.content-language') == 'en-US' + } + + + +} diff --git a/dd-smoke-tests/appsec/src/main/groovy/datadog/smoketest/appsec/AbstractAppSecServerSmokeTest.groovy b/dd-smoke-tests/appsec/src/main/groovy/datadog/smoketest/appsec/AbstractAppSecServerSmokeTest.groovy index 0d8eb04f393..7c47625ee8f 100644 --- a/dd-smoke-tests/appsec/src/main/groovy/datadog/smoketest/appsec/AbstractAppSecServerSmokeTest.groovy +++ b/dd-smoke-tests/appsec/src/main/groovy/datadog/smoketest/appsec/AbstractAppSecServerSmokeTest.groovy @@ -23,6 +23,10 @@ abstract class AbstractAppSecServerSmokeTest extends AbstractServerSmokeTest { span.meta } + Map getMetrics() { + span.metrics + } + List> getTriggers() { def appsecJSON = meta.get("_dd.appsec.json") if (appsecJSON) { diff --git a/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java b/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java index 0926941731c..84cc985f4d9 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java @@ -122,6 +122,7 @@ public final class ConfigDefaults { static final boolean DEFAULT_APPSEC_STACK_TRACE_ENABLED = true; static final int DEFAULT_APPSEC_MAX_STACK_TRACES = 2; static final int DEFAULT_APPSEC_MAX_STACK_TRACE_DEPTH = 32; + static final int DEFAULT_APPSEC_MAX_COLLECTED_HEADERS = 50; static final String DEFAULT_IAST_ENABLED = "false"; static final boolean DEFAULT_IAST_DEBUG_ENABLED = false; public static final int DEFAULT_IAST_MAX_CONCURRENT_REQUESTS = 4; diff --git a/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java b/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java index 4feee469e75..c194828038a 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java @@ -43,6 +43,10 @@ public final class AppSecConfig { public static final String APPSEC_MAX_STACK_TRACE_DEPTH = "appsec.max.stack-trace.depth"; public static final String APPSEC_MAX_STACKTRACE_DEPTH_DEPRECATED = "appsec.max.stacktrace.depth"; // old non-standard as a fallback alias + public static final String APPSEC_COLLECT_ALL_HEADERS = "appsec.collect.all.headers"; + public static final String APPSEC_MAX_COLLECTED_HEADERS = "appsec.max.collected.headers"; + public static final String APPSEC_HEADER_COLLECTION_REDACTION_ENABLED = + "appsec.header.collection.redaction.enabled"; private AppSecConfig() {} } diff --git a/internal-api/src/main/java/datadog/trace/api/Config.java b/internal-api/src/main/java/datadog/trace/api/Config.java index 6f3041ca7d8..abc5baf4612 100644 --- a/internal-api/src/main/java/datadog/trace/api/Config.java +++ b/internal-api/src/main/java/datadog/trace/api/Config.java @@ -292,6 +292,9 @@ public static String getHostName() { private final boolean appSecStackTraceEnabled; private final int appSecMaxStackTraces; private final int appSecMaxStackTraceDepth; + private final boolean appSecCollectAllHeaders; + private final boolean appSecHeaderCollectionRedactionEnabled; + private final int appSecMaxCollectedHeaders; private final boolean apiSecurityEnabled; private final float apiSecuritySampleDelay; private final boolean apiSecurityEndpointCollectionEnabled; @@ -1386,6 +1389,12 @@ PROFILING_DATADOG_PROFILER_ENABLED, isDatadogProfilerSafeInCurrentEnvironment()) APPSEC_MAX_STACK_TRACE_DEPTH, DEFAULT_APPSEC_MAX_STACK_TRACE_DEPTH, APPSEC_MAX_STACKTRACE_DEPTH_DEPRECATED); + appSecCollectAllHeaders = configProvider.getBoolean(APPSEC_COLLECT_ALL_HEADERS, false); + appSecHeaderCollectionRedactionEnabled = + configProvider.getBoolean(APPSEC_HEADER_COLLECTION_REDACTION_ENABLED, true); + appSecMaxCollectedHeaders = + configProvider.getInteger( + APPSEC_MAX_COLLECTED_HEADERS, DEFAULT_APPSEC_MAX_COLLECTED_HEADERS); apiSecurityEnabled = configProvider.getBoolean( API_SECURITY_ENABLED, DEFAULT_API_SECURITY_ENABLED, API_SECURITY_ENABLED_EXPERIMENTAL); @@ -4195,6 +4204,18 @@ public int getAppSecMaxStackTraceDepth() { return appSecMaxStackTraceDepth; } + public boolean isAppSecCollectAllHeaders() { + return appSecCollectAllHeaders; + } + + public boolean isAppSecHeaderCollectionRedactionEnabled() { + return appSecHeaderCollectionRedactionEnabled; + } + + public int getAppsecMaxCollectedHeaders() { + return appSecMaxCollectedHeaders; + } + public boolean isCloudPayloadTaggingEnabledFor(String serviceName) { return cloudPayloadTaggingServices.contains(serviceName); } From 97433cde4a2283d0cc1d5f3a6307d203a5e6fcd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Gonz=C3=A1lez=20Garc=C3=ADa?= Date: Tue, 20 May 2025 15:36:14 +0200 Subject: [PATCH 2/6] Update dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java Co-authored-by: Santiago M. Mola --- .../src/main/java/datadog/trace/api/config/AppSecConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java b/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java index c194828038a..c7ab415b464 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java @@ -43,7 +43,7 @@ public final class AppSecConfig { public static final String APPSEC_MAX_STACK_TRACE_DEPTH = "appsec.max.stack-trace.depth"; public static final String APPSEC_MAX_STACKTRACE_DEPTH_DEPRECATED = "appsec.max.stacktrace.depth"; // old non-standard as a fallback alias - public static final String APPSEC_COLLECT_ALL_HEADERS = "appsec.collect.all.headers"; + public static final String APPSEC_COLLECT_ALL_HEADERS = "appsec.collect-all-headers"; public static final String APPSEC_MAX_COLLECTED_HEADERS = "appsec.max.collected.headers"; public static final String APPSEC_HEADER_COLLECTION_REDACTION_ENABLED = "appsec.header.collection.redaction.enabled"; From e6cb2dd5f8e753e183f6a6345948c56af745b30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Gonz=C3=A1lez=20Garc=C3=ADa?= Date: Tue, 20 May 2025 15:36:21 +0200 Subject: [PATCH 3/6] Update dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java Co-authored-by: Santiago M. Mola --- .../src/main/java/datadog/trace/api/config/AppSecConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java b/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java index c7ab415b464..93dd4f3b7e4 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java @@ -44,7 +44,7 @@ public final class AppSecConfig { public static final String APPSEC_MAX_STACKTRACE_DEPTH_DEPRECATED = "appsec.max.stacktrace.depth"; // old non-standard as a fallback alias public static final String APPSEC_COLLECT_ALL_HEADERS = "appsec.collect-all-headers"; - public static final String APPSEC_MAX_COLLECTED_HEADERS = "appsec.max.collected.headers"; + public static final String APPSEC_MAX_COLLECTED_HEADERS = "appsec.max-collected-headers"; public static final String APPSEC_HEADER_COLLECTION_REDACTION_ENABLED = "appsec.header.collection.redaction.enabled"; From 37a5094a03efeac0a86b0ffff9d3fc7efcc08ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Gonz=C3=A1lez=20Garc=C3=ADa?= Date: Tue, 20 May 2025 15:36:32 +0200 Subject: [PATCH 4/6] Update dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java Co-authored-by: Santiago M. Mola --- .../src/main/java/datadog/trace/api/config/AppSecConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java b/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java index 93dd4f3b7e4..6f2b8247de0 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java @@ -46,7 +46,7 @@ public final class AppSecConfig { public static final String APPSEC_COLLECT_ALL_HEADERS = "appsec.collect-all-headers"; public static final String APPSEC_MAX_COLLECTED_HEADERS = "appsec.max-collected-headers"; public static final String APPSEC_HEADER_COLLECTION_REDACTION_ENABLED = - "appsec.header.collection.redaction.enabled"; + "appsec.header-collection-redaction.enabled"; private AppSecConfig() {} } From 4e995e9ba6eb42cdf397ad6739f817a22b377b97 Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Wed, 21 May 2025 10:05:17 +0200 Subject: [PATCH 5/6] fix smoke tests --- .../smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy b/dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy index da2862dce12..33a7a04740d 100644 --- a/dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy +++ b/dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy @@ -14,8 +14,8 @@ class ExtendedDataCollectionSmokeTest extends AbstractAppSecServerSmokeTest { command.add(javaPath()) command.addAll(defaultJavaProperties) command.addAll(defaultAppSecProperties) - command.add('-Ddd.appsec.collect.all.headers=true') - command.add('-Ddd.appsec.header.collection.redaction.enabled=false') + command.add('-Ddd.appsec.collect-all-headers=true') + command.add('-Ddd.appsec.header-collection-redaction.enabled=false') command.addAll((String[]) ["-jar", springBootShadowJar, "--server.port=${httpPort}"]) ProcessBuilder processBuilder = new ProcessBuilder(command) From 1989174a13cf1dc495b806ae4072112923540ba8 Mon Sep 17 00:00:00 2001 From: "alejandro.gonzalez" Date: Wed, 21 May 2025 10:46:04 +0200 Subject: [PATCH 6/6] rollback properties changes --- .../smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy | 4 ++-- .../main/java/datadog/trace/api/config/AppSecConfig.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy b/dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy index 33a7a04740d..da2862dce12 100644 --- a/dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy +++ b/dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy @@ -14,8 +14,8 @@ class ExtendedDataCollectionSmokeTest extends AbstractAppSecServerSmokeTest { command.add(javaPath()) command.addAll(defaultJavaProperties) command.addAll(defaultAppSecProperties) - command.add('-Ddd.appsec.collect-all-headers=true') - command.add('-Ddd.appsec.header-collection-redaction.enabled=false') + command.add('-Ddd.appsec.collect.all.headers=true') + command.add('-Ddd.appsec.header.collection.redaction.enabled=false') command.addAll((String[]) ["-jar", springBootShadowJar, "--server.port=${httpPort}"]) ProcessBuilder processBuilder = new ProcessBuilder(command) diff --git a/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java b/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java index 6f2b8247de0..c194828038a 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/config/AppSecConfig.java @@ -43,10 +43,10 @@ public final class AppSecConfig { public static final String APPSEC_MAX_STACK_TRACE_DEPTH = "appsec.max.stack-trace.depth"; public static final String APPSEC_MAX_STACKTRACE_DEPTH_DEPRECATED = "appsec.max.stacktrace.depth"; // old non-standard as a fallback alias - public static final String APPSEC_COLLECT_ALL_HEADERS = "appsec.collect-all-headers"; - public static final String APPSEC_MAX_COLLECTED_HEADERS = "appsec.max-collected-headers"; + public static final String APPSEC_COLLECT_ALL_HEADERS = "appsec.collect.all.headers"; + public static final String APPSEC_MAX_COLLECTED_HEADERS = "appsec.max.collected.headers"; public static final String APPSEC_HEADER_COLLECTION_REDACTION_ENABLED = - "appsec.header-collection-redaction.enabled"; + "appsec.header.collection.redaction.enabled"; private AppSecConfig() {} }