55import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_AUTO_USER_INSTRUM_MODE ;
66import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_CUSTOM_BLOCKING_RESPONSE ;
77import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_CUSTOM_RULES ;
8+ import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_DD_MULTICONFIG ;
89import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_DD_RULES ;
910import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_EXCLUSIONS ;
1011import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_EXCLUSION_DATA ;
1819import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_RASP_SSRF ;
1920import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_REQUEST_BLOCKING ;
2021import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_SESSION_FINGERPRINT ;
22+ import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_TRACE_TAGGING_RULES ;
2123import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_TRUSTED_IPS ;
2224import static datadog .remoteconfig .Capabilities .CAPABILITY_ASM_USER_BLOCKING ;
2325import static datadog .remoteconfig .Capabilities .CAPABILITY_ENDPOINT_FINGERPRINT ;
3638import com .datadog .ddwaf .exception .InvalidRuleSetException ;
3739import com .datadog .ddwaf .exception .UnclassifiedWafException ;
3840import com .squareup .moshi .JsonAdapter ;
39- import com .squareup .moshi .Moshi ;
40- import com .squareup .moshi .Types ;
41+ import com .squareup .moshi .JsonReader ;
42+ import com .squareup .moshi .JsonWriter ;
4143import datadog .remoteconfig .ConfigurationEndListener ;
4244import datadog .remoteconfig .ConfigurationPoller ;
4345import datadog .remoteconfig .PollingRateHinter ;
5860import java .util .Collections ;
5961import java .util .HashMap ;
6062import java .util .HashSet ;
63+ import java .util .LinkedHashMap ;
6164import java .util .List ;
6265import java .util .Map ;
6366import java .util .Set ;
@@ -89,15 +92,12 @@ public class AppSecConfigServiceImpl implements AppSecConfigService {
8992 new WAFInitializationResultReporter ();
9093 private final WAFStatsReporter statsReporter = new WAFStatsReporter ();
9194
92- private static final JsonAdapter <Map <String , Object >> ADAPTER =
93- new Moshi .Builder ()
94- .build ()
95- .adapter (Types .newParameterizedType (Map .class , String .class , Object .class ));
95+ private static final JsonAdapter <Object > ADAPTER = new SafeMapAdapter ();
9696
9797 private boolean hasUserWafConfig ;
9898 private boolean defaultConfigActivated ;
9999 private final Set <String > usedDDWafConfigKeys = new HashSet <>();
100- private final String DEFAULT_WAF_CONFIG_RULE = "DEFAULT_WAF_CONFIG " ;
100+ private final String DEFAULT_WAF_CONFIG_RULE = "ASM_DD/default " ;
101101 private String currentRuleVersion ;
102102 private List <AppSecModule > modulesToUpdateVersionIn ;
103103
@@ -128,6 +128,7 @@ private void subscribeConfigurationPoller() {
128128
129129 long capabilities =
130130 CAPABILITY_ASM_DD_RULES
131+ | CAPABILITY_ASM_DD_MULTICONFIG
131132 | CAPABILITY_ASM_IP_BLOCKING
132133 | CAPABILITY_ASM_EXCLUSIONS
133134 | CAPABILITY_ASM_EXCLUSION_DATA
@@ -139,7 +140,8 @@ private void subscribeConfigurationPoller() {
139140 | CAPABILITY_ENDPOINT_FINGERPRINT
140141 | CAPABILITY_ASM_SESSION_FINGERPRINT
141142 | CAPABILITY_ASM_NETWORK_FINGERPRINT
142- | CAPABILITY_ASM_HEADER_FINGERPRINT ;
143+ | CAPABILITY_ASM_HEADER_FINGERPRINT
144+ | CAPABILITY_ASM_TRACE_TAGGING_RULES ;
143145 if (tracerConfig .isAppSecRaspEnabled ()) {
144146 capabilities |= CAPABILITY_ASM_RASP_SQLI ;
145147 capabilities |= CAPABILITY_ASM_RASP_SSRF ;
@@ -182,7 +184,8 @@ public void accept(ConfigKey configKey, byte[] content, PollingRateHinter pollin
182184 }
183185 } else {
184186 Map <String , Object > contentMap =
185- ADAPTER .fromJson (Okio .buffer (Okio .source (new ByteArrayInputStream (content ))));
187+ (Map <String , Object >)
188+ ADAPTER .fromJson (Okio .buffer (Okio .source (new ByteArrayInputStream (content ))));
186189 try {
187190 handleWafUpdateResultReport (configKey .toString (), contentMap );
188191 } catch (AppSecModule .AppSecModuleActivationException e ) {
@@ -208,7 +211,7 @@ private class AppSecConfigChangesDDListener extends AppSecConfigChangesListener
208211 public void accept (ConfigKey configKey , byte [] content , PollingRateHinter pollingRateHinter )
209212 throws IOException {
210213 if (defaultConfigActivated ) { // if we get any config, remove the default one
211- log .debug ("Removing default config" );
214+ log .debug ("Removing default config ASM_DD/default " );
212215 try {
213216 wafBuilder .removeConfig (DEFAULT_WAF_CONFIG_RULE );
214217 } catch (UnclassifiedWafException e ) {
@@ -422,7 +425,8 @@ private static Map<String, Object> loadDefaultWafConfig() throws IOException {
422425 throw new IOException ("Resource " + DEFAULT_CONFIG_LOCATION + " not found" );
423426 }
424427
425- Map <String , Object > ret = ADAPTER .fromJson (Okio .buffer (Okio .source (is )));
428+ Map <String , Object > ret =
429+ (Map <String , Object >) ADAPTER .fromJson (Okio .buffer (Okio .source (is )));
426430
427431 StandardizedLogging ._initialConfigSourceAndLibddwafVersion (log , "<bundled config>" );
428432 if (log .isInfoEnabled ()) {
@@ -439,7 +443,8 @@ private static Map<String, Object> loadUserWafConfig(Config tracerConfig) throws
439443 return null ;
440444 }
441445 try (InputStream is = new FileInputStream (filename )) {
442- Map <String , Object > ret = ADAPTER .fromJson (Okio .buffer (Okio .source (is )));
446+ Map <String , Object > ret =
447+ (Map <String , Object >) ADAPTER .fromJson (Okio .buffer (Okio .source (is )));
443448
444449 StandardizedLogging ._initialConfigSourceAndLibddwafVersion (log , filename );
445450 if (log .isInfoEnabled ()) {
@@ -468,6 +473,7 @@ public void close() {
468473 this .configurationPoller .removeCapabilities (
469474 CAPABILITY_ASM_ACTIVATION
470475 | CAPABILITY_ASM_DD_RULES
476+ | CAPABILITY_ASM_DD_MULTICONFIG
471477 | CAPABILITY_ASM_IP_BLOCKING
472478 | CAPABILITY_ASM_EXCLUSIONS
473479 | CAPABILITY_ASM_EXCLUSION_DATA
@@ -485,7 +491,8 @@ public void close() {
485491 | CAPABILITY_ENDPOINT_FINGERPRINT
486492 | CAPABILITY_ASM_SESSION_FINGERPRINT
487493 | CAPABILITY_ASM_NETWORK_FINGERPRINT
488- | CAPABILITY_ASM_HEADER_FINGERPRINT );
494+ | CAPABILITY_ASM_HEADER_FINGERPRINT
495+ | CAPABILITY_ASM_TRACE_TAGGING_RULES );
489496 this .configurationPoller .removeListeners (Product .ASM_DD );
490497 this .configurationPoller .removeListeners (Product .ASM_DATA );
491498 this .configurationPoller .removeListeners (Product .ASM );
@@ -553,4 +560,59 @@ private static WafConfig createWafConfig(Config config) {
553560 }
554561 return wafConfig ;
555562 }
563+
564+ private static class SafeMapAdapter extends JsonAdapter <Object > {
565+ @ Override
566+ public Object fromJson (JsonReader reader ) throws IOException {
567+ switch (reader .peek ()) {
568+ case BEGIN_OBJECT :
569+ Map <String , Object > map = new LinkedHashMap <>();
570+ reader .beginObject ();
571+ while (reader .hasNext ()) {
572+ map .put (reader .nextName (), fromJson (reader ));
573+ }
574+ reader .endObject ();
575+ return map ;
576+
577+ case BEGIN_ARRAY :
578+ List <Object > list = new ArrayList <>();
579+ reader .beginArray ();
580+ while (reader .hasNext ()) {
581+ list .add (fromJson (reader ));
582+ }
583+ reader .endArray ();
584+ return list ;
585+
586+ case STRING :
587+ return reader .nextString ();
588+ case NUMBER :
589+ String numberStr = reader .nextString ();
590+ try {
591+ if (numberStr .contains ("." )) {
592+ return Double .parseDouble (numberStr );
593+ } else {
594+ return Long .parseLong (numberStr );
595+ }
596+ } catch (NumberFormatException e ) {
597+ // Fallback to string if parsing fails
598+ return numberStr ;
599+ }
600+
601+ case BOOLEAN :
602+ return reader .nextBoolean ();
603+
604+ case NULL :
605+ reader .nextNull ();
606+ return null ;
607+
608+ default :
609+ throw new IllegalStateException ("Unexpected token: " + reader .peek ());
610+ }
611+ }
612+
613+ @ Override
614+ public void toJson (JsonWriter writer , Object value ) throws IOException {
615+ throw new UnsupportedOperationException ("Serialization not supported" );
616+ }
617+ }
556618}
0 commit comments