Skip to content

Commit 8666fda

Browse files
committed
Add new features for trace tagging rules
Signed-off-by: sezen.leblay <sezen.leblay@datadoghq.com>
1 parent ad6d6b9 commit 8666fda

File tree

9 files changed

+703
-25
lines changed

9 files changed

+703
-25
lines changed

dd-java-agent/appsec/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ dependencies {
1515
implementation project(':internal-api')
1616
implementation project(':communication')
1717
implementation project(':telemetry')
18-
implementation group: 'io.sqreen', name: 'libsqreen', version: '15.0.0'
18+
implementation group: 'io.sqreen', name: 'libsqreen', version: '15.0.2'
1919
implementation libs.moshi
2020

2121
testImplementation libs.bytebuddy

dd-java-agent/appsec/src/main/java/com/datadog/appsec/config/AppSecConfigServiceImpl.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_AUTO_USER_INSTRUM_MODE;
66
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_CUSTOM_BLOCKING_RESPONSE;
77
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_CUSTOM_RULES;
8+
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_DD_MULTICONFIG;
89
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_DD_RULES;
910
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_EXCLUSIONS;
1011
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_EXCLUSION_DATA;
@@ -18,6 +19,7 @@
1819
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_RASP_SSRF;
1920
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_REQUEST_BLOCKING;
2021
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_SESSION_FINGERPRINT;
22+
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_TRACE_TAGGING_RULES;
2123
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_TRUSTED_IPS;
2224
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_USER_BLOCKING;
2325
import static datadog.remoteconfig.Capabilities.CAPABILITY_ENDPOINT_FINGERPRINT;
@@ -98,7 +100,7 @@ public class AppSecConfigServiceImpl implements AppSecConfigService {
98100
private boolean hasUserWafConfig;
99101
private boolean defaultConfigActivated;
100102
private final Set<String> usedDDWafConfigKeys = new HashSet<>();
101-
private final String DEFAULT_WAF_CONFIG_RULE = "DEFAULT_WAF_CONFIG";
103+
private final String DEFAULT_WAF_CONFIG_RULE = "ASM_DD/default";
102104
private String currentRuleVersion;
103105
private List<AppSecModule> modulesToUpdateVersionIn;
104106

@@ -129,6 +131,7 @@ private void subscribeConfigurationPoller() {
129131

130132
long capabilities =
131133
CAPABILITY_ASM_DD_RULES
134+
| CAPABILITY_ASM_DD_MULTICONFIG
132135
| CAPABILITY_ASM_IP_BLOCKING
133136
| CAPABILITY_ASM_EXCLUSIONS
134137
| CAPABILITY_ASM_EXCLUSION_DATA
@@ -140,7 +143,8 @@ private void subscribeConfigurationPoller() {
140143
| CAPABILITY_ENDPOINT_FINGERPRINT
141144
| CAPABILITY_ASM_SESSION_FINGERPRINT
142145
| CAPABILITY_ASM_NETWORK_FINGERPRINT
143-
| CAPABILITY_ASM_HEADER_FINGERPRINT;
146+
| CAPABILITY_ASM_HEADER_FINGERPRINT
147+
| CAPABILITY_ASM_TRACE_TAGGING_RULES;
144148
if (tracerConfig.isAppSecRaspEnabled()) {
145149
capabilities |= CAPABILITY_ASM_RASP_SQLI;
146150
capabilities |= CAPABILITY_ASM_RASP_SSRF;
@@ -211,7 +215,7 @@ private class AppSecConfigChangesDDListener extends AppSecConfigChangesListener
211215
public void accept(ConfigKey configKey, byte[] content, PollingRateHinter pollingRateHinter)
212216
throws IOException {
213217
if (defaultConfigActivated) { // if we get any config, remove the default one
214-
log.debug("Removing default config");
218+
log.debug("Removing default config ASM_DD/default");
215219
try {
216220
wafBuilder.removeConfig(DEFAULT_WAF_CONFIG_RULE);
217221
} catch (UnclassifiedWafException e) {
@@ -306,7 +310,10 @@ private void subscribeAsmFeatures() {
306310
private void distributeSubConfigurations(
307311
String key, AppSecModuleConfigurer.Reconfiguration reconfiguration) {
308312
if (usedDDWafConfigKeys.isEmpty() && !defaultConfigActivated && !hasUserWafConfig) {
309-
// no config left in the WAF builder, add the default config
313+
// ASM_DD Failure Fallback: If none of the configurations obtained through ASM_DD were loaded
314+
// successfully,
315+
// libraries must revert back to the default configuration
316+
log.debug("No ASM_DD configurations loaded, falling back to default configuration");
310317
init();
311318
}
312319
for (Map.Entry<String, SubconfigListener> entry : subconfigListeners.entrySet()) {
@@ -473,6 +480,7 @@ public void close() {
473480
this.configurationPoller.removeCapabilities(
474481
CAPABILITY_ASM_ACTIVATION
475482
| CAPABILITY_ASM_DD_RULES
483+
| CAPABILITY_ASM_DD_MULTICONFIG
476484
| CAPABILITY_ASM_IP_BLOCKING
477485
| CAPABILITY_ASM_EXCLUSIONS
478486
| CAPABILITY_ASM_EXCLUSION_DATA
@@ -490,7 +498,8 @@ public void close() {
490498
| CAPABILITY_ENDPOINT_FINGERPRINT
491499
| CAPABILITY_ASM_SESSION_FINGERPRINT
492500
| CAPABILITY_ASM_NETWORK_FINGERPRINT
493-
| CAPABILITY_ASM_HEADER_FINGERPRINT);
501+
| CAPABILITY_ASM_HEADER_FINGERPRINT
502+
| CAPABILITY_ASM_TRACE_TAGGING_RULES);
494503
this.configurationPoller.removeListeners(Product.ASM_DD);
495504
this.configurationPoller.removeListeners(Product.ASM_DATA);
496505
this.configurationPoller.removeListeners(Product.ASM);

dd-java-agent/appsec/src/main/java/com/datadog/appsec/ddwaf/WAFModule.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import datadog.communication.monitor.Counter;
3131
import datadog.communication.monitor.Monitoring;
3232
import datadog.trace.api.Config;
33+
import datadog.trace.api.DDTags;
3334
import datadog.trace.api.ProductActivation;
3435
import datadog.trace.api.ProductTraceSource;
3536
import datadog.trace.api.gateway.Flow;
@@ -223,6 +224,11 @@ private void initOrUpdateWafHandle(AppSecModuleConfigurer.Reconfiguration reconf
223224
reconf.reloadSubscriptions();
224225
}
225226

227+
/**
228+
* Creates a rate limiter for AppSec events. The rate limiter accounts for when libddwaf returns
229+
* keep with a value of true, rather than when events are present, as specified in the technical
230+
* specification.
231+
*/
226232
private static RateLimiter getRateLimiter(Monitoring monitoring) {
227233
if (monitoring == null) {
228234
return null;
@@ -402,14 +408,16 @@ public void onDataAvailable(
402408
}
403409
Collection<AppSecEvent> events = buildEvents(resultWithData);
404410

405-
if (!events.isEmpty()) {
411+
if (resultWithData.keep) {
406412
if (!reqCtx.isThrottled(rateLimiter)) {
407413
AgentSpan activeSpan = AgentTracer.get().activeSpan();
408414
if (activeSpan != null) {
409-
log.debug("Setting force-keep tag on the current span");
415+
log.debug("Setting force-keep tag and manual keep tag on the current span");
410416
// Keep event related span, because it could be ignored in case of
411417
// reduced datadog sampling rate.
412418
activeSpan.getLocalRootSpan().setTag(Tags.ASM_KEEP, true);
419+
// Set manual keep tag as required by the technical spec
420+
activeSpan.getLocalRootSpan().setTag(DDTags.MANUAL_KEEP, true);
413421
// If APM is disabled, inform downstream services that the current
414422
// distributed trace contains at least one ASM event and must inherit
415423
// the given force-keep priority
@@ -437,8 +445,8 @@ public void onDataAvailable(
437445
}
438446
}
439447

440-
if (resultWithData.derivatives != null) {
441-
reqCtx.reportDerivatives(resultWithData.derivatives);
448+
if (resultWithData.attributes != null && !resultWithData.attributes.isEmpty()) {
449+
reqCtx.reportDerivatives(resultWithData.attributes);
442450
}
443451
}
444452

@@ -559,6 +567,10 @@ private Waf.ResultWithData runWafTransient(
559567
private Collection<AppSecEvent> buildEvents(Waf.ResultWithData actionWithData) {
560568
Collection<WAFResultData> listResults;
561569
try {
570+
if (actionWithData.data == null || actionWithData.data.isEmpty()) {
571+
log.debug("WAF returned no data");
572+
return emptyList();
573+
}
562574
listResults = RES_JSON_ADAPTER.fromJson(actionWithData.data);
563575
} catch (IOException e) {
564576
throw new UndeclaredThrowableException(e);

0 commit comments

Comments
 (0)