5
5
import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_AUTO_USER_INSTRUM_MODE ;
6
6
import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_CUSTOM_BLOCKING_RESPONSE ;
7
7
import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_CUSTOM_RULES ;
8
+ import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_DD_MULTICONFIG ;
8
9
import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_DD_RULES ;
9
10
import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_EXCLUSIONS ;
10
11
import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_EXCLUSION_DATA ;
18
19
import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_RASP_SSRF ;
19
20
import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_REQUEST_BLOCKING ;
20
21
import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_SESSION_FINGERPRINT ;
22
+ import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_TRACE_TAGGING_RULES ;
21
23
import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_TRUSTED_IPS ;
22
24
import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_USER_BLOCKING ;
23
25
import static datadog .remoteconfig .Capabilities .CAPABILITY_ENDPOINT_FINGERPRINT ;
37
39
import com .datadog .ddwaf .exception .InvalidRuleSetException ;
38
40
import com .datadog .ddwaf .exception .UnclassifiedWafException ;
39
41
import com .squareup .moshi .JsonAdapter ;
40
- import com .squareup .moshi .Moshi ;
41
- import com .squareup .moshi .Types ;
42
+ import com .squareup .moshi .JsonReader ;
43
+ import com .squareup .moshi .JsonWriter ;
42
44
import datadog .remoteconfig .ConfigurationEndListener ;
43
45
import datadog .remoteconfig .ConfigurationPoller ;
44
46
import datadog .remoteconfig .PollingRateHinter ;
61
63
import java .util .Collections ;
62
64
import java .util .HashMap ;
63
65
import java .util .HashSet ;
66
+ import java .util .LinkedHashMap ;
64
67
import java .util .List ;
65
68
import java .util .Map ;
66
69
import java .util .Set ;
@@ -92,15 +95,12 @@ public class AppSecConfigServiceImpl implements AppSecConfigService {
92
95
new WAFInitializationResultReporter ();
93
96
private final WAFStatsReporter statsReporter = new WAFStatsReporter ();
94
97
95
- private static final JsonAdapter <Map <String , Object >> ADAPTER =
96
- new Moshi .Builder ()
97
- .build ()
98
- .adapter (Types .newParameterizedType (Map .class , String .class , Object .class ));
98
+ private static final JsonAdapter <Object > ADAPTER = new SafeMapAdapter ();
99
99
100
100
private boolean hasUserWafConfig ;
101
101
private boolean defaultConfigActivated ;
102
102
private final Set <String > usedDDWafConfigKeys = new HashSet <>();
103
- private final String DEFAULT_WAF_CONFIG_RULE = "DEFAULT_WAF_CONFIG " ;
103
+ private final String DEFAULT_WAF_CONFIG_RULE = "ASM_DD/default " ;
104
104
private String currentRuleVersion ;
105
105
private List <AppSecModule > modulesToUpdateVersionIn ;
106
106
@@ -131,6 +131,7 @@ private void subscribeConfigurationPoller() {
131
131
132
132
long capabilities =
133
133
CAPABILITY_ASM_DD_RULES
134
+ | CAPABILITY_ASM_DD_MULTICONFIG
134
135
| CAPABILITY_ASM_IP_BLOCKING
135
136
| CAPABILITY_ASM_EXCLUSIONS
136
137
| CAPABILITY_ASM_EXCLUSION_DATA
@@ -142,7 +143,8 @@ private void subscribeConfigurationPoller() {
142
143
| CAPABILITY_ENDPOINT_FINGERPRINT
143
144
| CAPABILITY_ASM_SESSION_FINGERPRINT
144
145
| CAPABILITY_ASM_NETWORK_FINGERPRINT
145
- | CAPABILITY_ASM_HEADER_FINGERPRINT ;
146
+ | CAPABILITY_ASM_HEADER_FINGERPRINT
147
+ | CAPABILITY_ASM_TRACE_TAGGING_RULES ;
146
148
if (tracerConfig .isAppSecRaspEnabled ()) {
147
149
capabilities |= CAPABILITY_ASM_RASP_SQLI ;
148
150
capabilities |= CAPABILITY_ASM_RASP_SSRF ;
@@ -185,7 +187,8 @@ public void accept(ConfigKey configKey, byte[] content, PollingRateHinter pollin
185
187
}
186
188
} else {
187
189
Map <String , Object > contentMap =
188
- ADAPTER .fromJson (Okio .buffer (Okio .source (new ByteArrayInputStream (content ))));
190
+ (Map <String , Object >)
191
+ ADAPTER .fromJson (Okio .buffer (Okio .source (new ByteArrayInputStream (content ))));
189
192
try {
190
193
handleWafUpdateResultReport (configKey .toString (), contentMap );
191
194
} catch (AppSecModule .AppSecModuleActivationException e ) {
@@ -211,7 +214,7 @@ private class AppSecConfigChangesDDListener extends AppSecConfigChangesListener
211
214
public void accept (ConfigKey configKey , byte [] content , PollingRateHinter pollingRateHinter )
212
215
throws IOException {
213
216
if (defaultConfigActivated ) { // if we get any config, remove the default one
214
- log .debug ("Removing default config" );
217
+ log .debug ("Removing default config ASM_DD/default " );
215
218
try {
216
219
wafBuilder .removeConfig (DEFAULT_WAF_CONFIG_RULE );
217
220
} catch (UnclassifiedWafException e ) {
@@ -425,7 +428,8 @@ private static Map<String, Object> loadDefaultWafConfig() throws IOException {
425
428
throw new IOException ("Resource " + DEFAULT_CONFIG_LOCATION + " not found" );
426
429
}
427
430
428
- Map <String , Object > ret = ADAPTER .fromJson (Okio .buffer (Okio .source (is )));
431
+ Map <String , Object > ret =
432
+ (Map <String , Object >) ADAPTER .fromJson (Okio .buffer (Okio .source (is )));
429
433
430
434
StandardizedLogging ._initialConfigSourceAndLibddwafVersion (log , "<bundled config>" );
431
435
if (log .isInfoEnabled ()) {
@@ -442,7 +446,8 @@ private static Map<String, Object> loadUserWafConfig(Config tracerConfig) throws
442
446
return null ;
443
447
}
444
448
try (InputStream is = new FileInputStream (filename )) {
445
- Map <String , Object > ret = ADAPTER .fromJson (Okio .buffer (Okio .source (is )));
449
+ Map <String , Object > ret =
450
+ (Map <String , Object >) ADAPTER .fromJson (Okio .buffer (Okio .source (is )));
446
451
447
452
StandardizedLogging ._initialConfigSourceAndLibddwafVersion (log , filename );
448
453
if (log .isInfoEnabled ()) {
@@ -471,6 +476,7 @@ public void close() {
471
476
this .configurationPoller .removeCapabilities (
472
477
CAPABILITY_ASM_ACTIVATION
473
478
| CAPABILITY_ASM_DD_RULES
479
+ | CAPABILITY_ASM_DD_MULTICONFIG
474
480
| CAPABILITY_ASM_IP_BLOCKING
475
481
| CAPABILITY_ASM_EXCLUSIONS
476
482
| CAPABILITY_ASM_EXCLUSION_DATA
@@ -488,7 +494,8 @@ public void close() {
488
494
| CAPABILITY_ENDPOINT_FINGERPRINT
489
495
| CAPABILITY_ASM_SESSION_FINGERPRINT
490
496
| CAPABILITY_ASM_NETWORK_FINGERPRINT
491
- | CAPABILITY_ASM_HEADER_FINGERPRINT );
497
+ | CAPABILITY_ASM_HEADER_FINGERPRINT
498
+ | CAPABILITY_ASM_TRACE_TAGGING_RULES );
492
499
this .configurationPoller .removeListeners (Product .ASM_DD );
493
500
this .configurationPoller .removeListeners (Product .ASM_DATA );
494
501
this .configurationPoller .removeListeners (Product .ASM );
@@ -558,4 +565,59 @@ private static WafConfig createWafConfig(Config config) {
558
565
}
559
566
return wafConfig ;
560
567
}
568
+
569
+ private static class SafeMapAdapter extends JsonAdapter <Object > {
570
+ @ Override
571
+ public Object fromJson (JsonReader reader ) throws IOException {
572
+ switch (reader .peek ()) {
573
+ case BEGIN_OBJECT :
574
+ Map <String , Object > map = new LinkedHashMap <>();
575
+ reader .beginObject ();
576
+ while (reader .hasNext ()) {
577
+ map .put (reader .nextName (), fromJson (reader ));
578
+ }
579
+ reader .endObject ();
580
+ return map ;
581
+
582
+ case BEGIN_ARRAY :
583
+ List <Object > list = new ArrayList <>();
584
+ reader .beginArray ();
585
+ while (reader .hasNext ()) {
586
+ list .add (fromJson (reader ));
587
+ }
588
+ reader .endArray ();
589
+ return list ;
590
+
591
+ case STRING :
592
+ return reader .nextString ();
593
+ case NUMBER :
594
+ String numberStr = reader .nextString ();
595
+ try {
596
+ if (numberStr .contains ("." )) {
597
+ return Double .parseDouble (numberStr );
598
+ } else {
599
+ return Long .parseLong (numberStr );
600
+ }
601
+ } catch (NumberFormatException e ) {
602
+ // Fallback to string if parsing fails
603
+ return numberStr ;
604
+ }
605
+
606
+ case BOOLEAN :
607
+ return reader .nextBoolean ();
608
+
609
+ case NULL :
610
+ reader .nextNull ();
611
+ return null ;
612
+
613
+ default :
614
+ throw new IllegalStateException ("Unexpected token: " + reader .peek ());
615
+ }
616
+ }
617
+
618
+ @ Override
619
+ public void toJson (JsonWriter writer , Object value ) throws IOException {
620
+ throw new UnsupportedOperationException ("Serialization not supported" );
621
+ }
622
+ }
561
623
}
0 commit comments