From 8b00e3e1021ed3948b6741cdd0f213fe941557ab Mon Sep 17 00:00:00 2001 From: ValentinZakharov Date: Thu, 11 Jul 2024 11:08:30 +0200 Subject: [PATCH] Introduced GatewayContext (#7304) --- .../benchmark/EventDispatcherBenchmark.java | 4 +- .../appsec/blocking/BlockingServiceImpl.java | 8 +- .../datadog/appsec/event/DataListener.java | 4 +- .../datadog/appsec/event/EventDispatcher.java | 8 +- .../appsec/event/EventProducerService.java | 8 +- .../ReplaceableEventProducerService.java | 8 +- .../datadog/appsec/gateway/GatewayBridge.java | 30 ++++-- .../appsec/gateway/GatewayContext.java | 11 ++ .../appsec/powerwaf/PowerWAFModule.java | 16 +-- .../appsec/AppSecModuleSpecification.groovy | 3 +- .../BlockingServiceImplSpecification.groovy | 3 +- .../event/EventDispatcherSpecification.groovy | 30 +++--- .../gateway/GatewayBridgeSpecification.groovy | 102 ++++++++++++------ .../PowerWAFModuleSpecification.groovy | 74 ++++++------- 14 files changed, 193 insertions(+), 116 deletions(-) create mode 100644 dd-java-agent/appsec/src/main/java/com/datadog/appsec/gateway/GatewayContext.java diff --git a/dd-java-agent/appsec/src/jmh/java/datadog/appsec/benchmark/EventDispatcherBenchmark.java b/dd-java-agent/appsec/src/jmh/java/datadog/appsec/benchmark/EventDispatcherBenchmark.java index 5bbc4f9ef27..2375c3fb1f4 100644 --- a/dd-java-agent/appsec/src/jmh/java/datadog/appsec/benchmark/EventDispatcherBenchmark.java +++ b/dd-java-agent/appsec/src/jmh/java/datadog/appsec/benchmark/EventDispatcherBenchmark.java @@ -11,6 +11,7 @@ import com.datadog.appsec.event.data.DataBundle; import com.datadog.appsec.event.data.KnownAddresses; import com.datadog.appsec.gateway.AppSecRequestContext; +import com.datadog.appsec.gateway.GatewayContext; import java.util.Collections; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; @@ -87,8 +88,7 @@ public void onDataAvailable( ChangeableFlow flow, AppSecRequestContext context, DataBundle dataBundle, - boolean isTransient, - boolean isRasp) {} + GatewayContext gatewayContext) {} @Override public Priority getPriority() { diff --git a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/blocking/BlockingServiceImpl.java b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/blocking/BlockingServiceImpl.java index e87f2c9470a..65757a186b4 100644 --- a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/blocking/BlockingServiceImpl.java +++ b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/blocking/BlockingServiceImpl.java @@ -5,6 +5,7 @@ import com.datadog.appsec.event.data.KnownAddresses; import com.datadog.appsec.event.data.SingletonDataBundle; import com.datadog.appsec.gateway.AppSecRequestContext; +import com.datadog.appsec.gateway.GatewayContext; import datadog.appsec.api.blocking.BlockingContentType; import datadog.appsec.api.blocking.BlockingDetails; import datadog.appsec.api.blocking.BlockingService; @@ -45,7 +46,8 @@ public BlockingDetails shouldBlockUser(@Nonnull String userId) { } SingletonDataBundle db = new SingletonDataBundle<>(KnownAddresses.USER_ID, userId); try { - flow = eventProducer.publishDataEvent(subInfo, reqCtx, db, true, false); + GatewayContext gwCtx = new GatewayContext(true, false); + flow = eventProducer.publishDataEvent(subInfo, reqCtx, db, gwCtx); break; } catch (ExpiredSubscriberInfoException e) { subInfo = null; @@ -65,7 +67,9 @@ public BlockingDetails shouldBlockUser(@Nonnull String userId) { @Override public boolean tryCommitBlockingResponse( - int statusCode, BlockingContentType templateType, Map extraHeaders) { + int statusCode, + @Nonnull BlockingContentType templateType, + @Nonnull Map extraHeaders) { log.info( "Will try to commit blocking response statusCode={} templateType={} extraHeaders={}", statusCode, diff --git a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/DataListener.java b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/DataListener.java index 570989a4d6a..cba2b80044c 100644 --- a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/DataListener.java +++ b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/DataListener.java @@ -2,12 +2,12 @@ import com.datadog.appsec.event.data.DataBundle; import com.datadog.appsec.gateway.AppSecRequestContext; +import com.datadog.appsec.gateway.GatewayContext; public interface DataListener extends OrderedCallback { void onDataAvailable( ChangeableFlow flow, AppSecRequestContext context, DataBundle dataBundle, - boolean isTransient, - boolean isRasp); + GatewayContext gatewayContext); } diff --git a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/EventDispatcher.java b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/EventDispatcher.java index 88636fce86c..de29df3d52b 100644 --- a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/EventDispatcher.java +++ b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/EventDispatcher.java @@ -4,6 +4,7 @@ import com.datadog.appsec.event.data.DataBundle; import com.datadog.appsec.event.data.KnownAddresses; import com.datadog.appsec.gateway.AppSecRequestContext; +import com.datadog.appsec.gateway.GatewayContext; import datadog.trace.api.gateway.Flow; import java.util.ArrayList; import java.util.BitSet; @@ -132,20 +133,19 @@ public Flow publishDataEvent( DataSubscriberInfo subscribers, AppSecRequestContext ctx, DataBundle newData, - boolean isTransient, - boolean isRasp) + GatewayContext gwCtx) throws ExpiredSubscriberInfoException { if (!((DataSubscriberInfoImpl) subscribers).isEventDispatcher(this)) { throw new ExpiredSubscriberInfoException(); } - if (!isTransient) { + if (!gwCtx.isTransient) { ctx.addAll(newData); } ChangeableFlow flow = new ChangeableFlow(); for (int idx : ((DataSubscriberInfoImpl) subscribers).listenerIndices) { try { - dataListenersIdx.get(idx).onDataAvailable(flow, ctx, newData, isTransient, isRasp); + dataListenersIdx.get(idx).onDataAvailable(flow, ctx, newData, gwCtx); } catch (RuntimeException rte) { log.warn("AppSec callback exception", rte); } diff --git a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/EventProducerService.java b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/EventProducerService.java index d8d07ccebab..9b0cd760320 100644 --- a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/EventProducerService.java +++ b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/EventProducerService.java @@ -3,6 +3,7 @@ import com.datadog.appsec.event.data.Address; import com.datadog.appsec.event.data.DataBundle; import com.datadog.appsec.gateway.AppSecRequestContext; +import com.datadog.appsec.gateway.GatewayContext; import datadog.trace.api.gateway.Flow; import java.util.Collection; @@ -14,7 +15,7 @@ public interface EventProducerService { * set of addresses is identical. * *

The return value is to be passed to {@link #publishDataEvent(DataSubscriberInfo, - * AppSecRequestContext, DataBundle, boolean, boolean)}. + * AppSecRequestContext, DataBundle, GatewayContext)}. * * @param newAddresses the addresses contained in the {@link DataBundle} that is to be passed to * publishDataEvent(). @@ -33,10 +34,9 @@ public interface EventProducerService { */ Flow publishDataEvent( DataSubscriberInfo subscribers, - AppSecRequestContext ctx, + AppSecRequestContext appSecRequestContext, DataBundle newData, - boolean isTransient, - boolean isRasp) + GatewayContext gatewayContext) throws ExpiredSubscriberInfoException; interface DataSubscriberInfo { diff --git a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/ReplaceableEventProducerService.java b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/ReplaceableEventProducerService.java index 0b38d1889b0..f0562fb56c2 100644 --- a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/ReplaceableEventProducerService.java +++ b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/event/ReplaceableEventProducerService.java @@ -3,6 +3,7 @@ import com.datadog.appsec.event.data.Address; import com.datadog.appsec.event.data.DataBundle; import com.datadog.appsec.gateway.AppSecRequestContext; +import com.datadog.appsec.gateway.GatewayContext; import datadog.trace.api.gateway.Flow; import java.util.Collection; @@ -21,12 +22,11 @@ public DataSubscriberInfo getDataSubscribers(Address... newAddresses) { @Override public Flow publishDataEvent( DataSubscriberInfo subscribers, - AppSecRequestContext ctx, + AppSecRequestContext reqCtx, DataBundle newData, - boolean isTransient, - boolean isRasp) + GatewayContext gwCtx) throws ExpiredSubscriberInfoException { - return cur.publishDataEvent(subscribers, ctx, newData, isTransient, isRasp); + return cur.publishDataEvent(subscribers, reqCtx, newData, gwCtx); } @Override 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 8b9046bff49..c046b7a93ff 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 @@ -235,7 +235,8 @@ public void init() { DataBundle bundle = new SingletonDataBundle<>(KnownAddresses.REQUEST_PATH_PARAMS, data); try { - return producerService.publishDataEvent(subInfo, ctx, bundle, false, false); + GatewayContext gwCtx = new GatewayContext(false, false); + return producerService.publishDataEvent(subInfo, ctx, bundle, gwCtx); } catch (ExpiredSubscriberInfoException e) { pathParamsSubInfo = null; } @@ -269,7 +270,8 @@ public void init() { DataBundle bundle = new SingletonDataBundle<>(KnownAddresses.REQUEST_BODY_RAW, bodyContent); try { - return producerService.publishDataEvent(subInfo, ctx, bundle, false, false); + GatewayContext gwCtx = new GatewayContext(false, false); + return producerService.publishDataEvent(subInfo, ctx, bundle, gwCtx); } catch (ExpiredSubscriberInfoException e) { rawRequestBodySubInfo = null; } @@ -306,7 +308,8 @@ public void init() { new SingletonDataBundle<>( KnownAddresses.REQUEST_BODY_OBJECT, ObjectIntrospection.convert(obj)); try { - return producerService.publishDataEvent(subInfo, ctx, bundle, false, false); + GatewayContext gwCtx = new GatewayContext(false, false); + return producerService.publishDataEvent(subInfo, ctx, bundle, gwCtx); } catch (ExpiredSubscriberInfoException e) { requestBodySubInfo = null; } @@ -385,7 +388,8 @@ public void init() { DataBundle bundle = new SingletonDataBundle<>(KnownAddresses.GRPC_SERVER_METHOD, method); try { - return producerService.publishDataEvent(subInfo, ctx, bundle, true, false); + GatewayContext gwCtx = new GatewayContext(true, false); + return producerService.publishDataEvent(subInfo, ctx, bundle, gwCtx); } catch (ExpiredSubscriberInfoException e) { grpcServerMethodSubInfo = null; } @@ -413,7 +417,8 @@ public void init() { DataBundle bundle = new SingletonDataBundle<>(KnownAddresses.GRPC_SERVER_REQUEST_MESSAGE, convObj); try { - return producerService.publishDataEvent(subInfo, ctx, bundle, true, false); + GatewayContext gwCtx = new GatewayContext(true, false); + return producerService.publishDataEvent(subInfo, ctx, bundle, gwCtx); } catch (ExpiredSubscriberInfoException e) { grpcServerRequestMsgSubInfo = null; } @@ -440,7 +445,8 @@ public void init() { DataBundle bundle = new SingletonDataBundle<>(KnownAddresses.GRAPHQL_SERVER_ALL_RESOLVERS, data); try { - return producerService.publishDataEvent(subInfo, ctx, bundle, true, false); + GatewayContext gwCtx = new GatewayContext(true, false); + return producerService.publishDataEvent(subInfo, ctx, bundle, gwCtx); } catch (ExpiredSubscriberInfoException e) { graphqlServerRequestMsgSubInfo = null; } @@ -481,7 +487,8 @@ public void init() { .add(KnownAddresses.DB_SQL_QUERY, sql) .build(); try { - return producerService.publishDataEvent(subInfo, ctx, bundle, false, true); + GatewayContext gwCtx = new GatewayContext(false, true); + return producerService.publishDataEvent(subInfo, ctx, bundle, gwCtx); } catch (ExpiredSubscriberInfoException e) { dbSqlQuerySubInfo = null; } @@ -678,7 +685,8 @@ private Flow maybePublishRequestData(AppSecRequestContext ctx) { } try { - return producerService.publishDataEvent(subInfo, ctx, bundle, false, false); + GatewayContext gwCtx = new GatewayContext(false, false); + return producerService.publishDataEvent(subInfo, ctx, bundle, gwCtx); } catch (ExpiredSubscriberInfoException e) { this.initialReqDataSubInfo = null; } @@ -710,7 +718,8 @@ private Flow maybePublishResponseData(AppSecRequestContext ctx) { } try { - return producerService.publishDataEvent(subInfo, ctx, bundle, false, false); + GatewayContext gwCtx = new GatewayContext(false, false); + return producerService.publishDataEvent(subInfo, ctx, bundle, gwCtx); } catch (ExpiredSubscriberInfoException e) { respDataSubInfo = null; } @@ -742,7 +751,8 @@ private void maybeExtractSchemas(AppSecRequestContext ctx) { KnownAddresses.WAF_CONTEXT_PROCESSOR, Collections.singletonMap("extract-schema", true)); try { - producerService.publishDataEvent(subInfo, ctx, bundle, false, false); + GatewayContext gwCtx = new GatewayContext(false, false); + producerService.publishDataEvent(subInfo, ctx, bundle, gwCtx); return; } catch (ExpiredSubscriberInfoException e) { requestEndSubInfo = null; diff --git a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/gateway/GatewayContext.java b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/gateway/GatewayContext.java new file mode 100644 index 00000000000..69b3b248eee --- /dev/null +++ b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/gateway/GatewayContext.java @@ -0,0 +1,11 @@ +package com.datadog.appsec.gateway; + +public class GatewayContext { + public final boolean isTransient; + public final boolean isRasp; + + public GatewayContext(final boolean isTransient, final boolean isRasp) { + this.isTransient = isTransient; + this.isRasp = isRasp; + } +} diff --git a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/powerwaf/PowerWAFModule.java b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/powerwaf/PowerWAFModule.java index c38ef40ff36..fd2efceba6c 100644 --- a/dd-java-agent/appsec/src/main/java/com/datadog/appsec/powerwaf/PowerWAFModule.java +++ b/dd-java-agent/appsec/src/main/java/com/datadog/appsec/powerwaf/PowerWAFModule.java @@ -13,6 +13,7 @@ import com.datadog.appsec.event.data.DataBundle; import com.datadog.appsec.event.data.KnownAddresses; import com.datadog.appsec.gateway.AppSecRequestContext; +import com.datadog.appsec.gateway.GatewayContext; import com.datadog.appsec.gateway.RateLimiter; import com.datadog.appsec.report.AppSecEvent; import com.datadog.appsec.stack_trace.StackTraceEvent; @@ -417,8 +418,7 @@ public void onDataAvailable( ChangeableFlow flow, AppSecRequestContext reqCtx, DataBundle newData, - boolean isTransient, - boolean isRasp) { + GatewayContext gwCtx) { Powerwaf.ResultWithData resultWithData; CtxAndAddresses ctxAndAddr = ctxAndAddresses.get(); if (ctxAndAddr == null) { @@ -433,7 +433,7 @@ public void onDataAvailable( } try { - resultWithData = doRunPowerwaf(reqCtx, newData, ctxAndAddr, isTransient, isRasp); + resultWithData = doRunPowerwaf(reqCtx, newData, ctxAndAddr, gwCtx); } catch (TimeoutPowerwafException tpe) { reqCtx.increaseTimeouts(); log.debug(LogCollector.EXCLUDE_TELEMETRY, "Timeout calling the WAF", tpe); @@ -587,20 +587,20 @@ private Powerwaf.ResultWithData doRunPowerwaf( AppSecRequestContext reqCtx, DataBundle newData, CtxAndAddresses ctxAndAddr, - boolean isTransient, - boolean isRasp) + GatewayContext gwCtx) throws AbstractPowerwafException { - Additive additive = reqCtx.getOrCreateAdditive(ctxAndAddr.ctx, wafMetricsEnabled, isRasp); + Additive additive = + reqCtx.getOrCreateAdditive(ctxAndAddr.ctx, wafMetricsEnabled, gwCtx.isRasp); PowerwafMetrics metrics; - if (isRasp) { + if (gwCtx.isRasp) { metrics = reqCtx.getRaspMetrics(); reqCtx.getRaspMetricsCounter().incrementAndGet(); } else { metrics = reqCtx.getWafMetrics(); } - if (isTransient) { + if (gwCtx.isTransient) { return runPowerwafTransient(additive, metrics, newData, ctxAndAddr); } else { return runPowerwafAdditive(additive, metrics, newData, ctxAndAddr); diff --git a/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/AppSecModuleSpecification.groovy b/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/AppSecModuleSpecification.groovy index 1f81fcf0f7a..fb06d1d33ad 100644 --- a/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/AppSecModuleSpecification.groovy +++ b/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/AppSecModuleSpecification.groovy @@ -5,6 +5,7 @@ import com.datadog.appsec.event.OrderedCallback import com.datadog.appsec.event.data.Address import com.datadog.appsec.event.data.DataBundle import com.datadog.appsec.gateway.AppSecRequestContext +import com.datadog.appsec.gateway.GatewayContext import datadog.trace.test.util.DDSpecification import static com.datadog.appsec.event.OrderedCallback.Priority.DEFAULT @@ -33,7 +34,7 @@ class AppSecModuleSpecification extends DDSpecification { } @Override - void onDataAvailable(ChangeableFlow flow, AppSecRequestContext context, DataBundle dataBundle, boolean isTransient, boolean isRasp) { + void onDataAvailable(ChangeableFlow flow, AppSecRequestContext reqCtx, DataBundle dataBundle, GatewayContext gwCtx) { } @Override diff --git a/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/blocking/BlockingServiceImplSpecification.groovy b/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/blocking/BlockingServiceImplSpecification.groovy index 0438f1c9040..a151f4917ae 100644 --- a/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/blocking/BlockingServiceImplSpecification.groovy +++ b/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/blocking/BlockingServiceImplSpecification.groovy @@ -8,6 +8,7 @@ import com.datadog.appsec.event.OrderedCallback import com.datadog.appsec.event.data.DataBundle import com.datadog.appsec.event.data.KnownAddresses import com.datadog.appsec.gateway.AppSecRequestContext +import com.datadog.appsec.gateway.GatewayContext import datadog.appsec.api.blocking.BlockingContentType import datadog.appsec.api.blocking.BlockingDetails import datadog.trace.api.gateway.BlockResponseFunction @@ -41,7 +42,7 @@ class BlockingServiceImplSpecification extends DDSpecification { final OrderedCallback.Priority priority = OrderedCallback.Priority.DEFAULT @Override - void onDataAvailable(ChangeableFlow flow, AppSecRequestContext context, DataBundle dataBundle, boolean isTransient, boolean isRasp) { + void onDataAvailable(ChangeableFlow flow, AppSecRequestContext reqCtx, DataBundle dataBundle, GatewayContext gwCtx) { if (dataBundle.get(KnownAddresses.USER_ID) == 'blocked.user') { flow.action = new Flow.Action.RequestBlockingAction(405, BlockingContentType.HTML) } diff --git a/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/event/EventDispatcherSpecification.groovy b/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/event/EventDispatcherSpecification.groovy index 184ac56ff00..c4c3cbbc8e9 100644 --- a/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/event/EventDispatcherSpecification.groovy +++ b/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/event/EventDispatcherSpecification.groovy @@ -5,6 +5,7 @@ import com.datadog.appsec.event.data.DataBundle import com.datadog.appsec.event.data.KnownAddresses import com.datadog.appsec.event.data.MapDataBundle import com.datadog.appsec.gateway.AppSecRequestContext +import com.datadog.appsec.gateway.GatewayContext import datadog.appsec.api.blocking.BlockingContentType import datadog.trace.api.gateway.Flow import datadog.trace.test.util.DDSpecification @@ -29,30 +30,31 @@ class EventDispatcherSpecification extends DDSpecification { set.addSubscription([KnownAddresses.REQUEST_CLIENT_IP], dataListener2) set.addSubscription([KnownAddresses.REQUEST_METHOD], dataListener3) dispatcher.subscribeDataAvailable(set) + def gwCtx = new GatewayContext(true, false) when: def subscribers = dispatcher.getDataSubscribers(KnownAddresses.REQUEST_CLIENT_IP, KnownAddresses.REQUEST_METHOD) DataBundle db = MapDataBundle.of( KnownAddresses.REQUEST_CLIENT_IP, '::1', KnownAddresses.REQUEST_METHOD, 'GET') - dispatcher.publishDataEvent(subscribers, ctx, db, true, false) + dispatcher.publishDataEvent(subscribers, ctx, db, gwCtx) then: 1 * dataListener3.onDataAvailable( _ as Flow, ctx, { it.hasAddress(KnownAddresses.REQUEST_CLIENT_IP) }, - true, false) >> { savedFlow3 = it[0] } + gwCtx) >> { savedFlow3 = it[0] } then: 1 * dataListener2.onDataAvailable( _ as Flow, ctx, { it.hasAddress(KnownAddresses.REQUEST_CLIENT_IP) }, - true, false) >> { savedFlow2 = it[0] } + gwCtx) >> { savedFlow2 = it[0] } savedFlow2.is(savedFlow3) then: 1 * dataListener1.onDataAvailable(_ as Flow, ctx, - _ as DataBundle, true, false) >> { savedFlow1 = it[0] } + _ as DataBundle, gwCtx) >> { savedFlow1 = it[0] } savedFlow1.is(savedFlow2) } @@ -70,14 +72,15 @@ class EventDispatcherSpecification extends DDSpecification { [KnownAddresses.REQUEST_CLIENT_IP, KnownAddresses.HEADERS_NO_COOKIES], listener) dispatcher.subscribeDataAvailable(set) + def gwCtx = new GatewayContext(true, false) when: def subscribers = dispatcher.getDataSubscribers(KnownAddresses.REQUEST_CLIENT_IP, KnownAddresses.HEADERS_NO_COOKIES) - dispatcher.publishDataEvent(subscribers, ctx, db, true, false) + dispatcher.publishDataEvent(subscribers, ctx, db, gwCtx) then: assert !subscribers.empty - 1 * listener.onDataAvailable(_ as Flow, ctx, db, true, false) + 1 * listener.onDataAvailable(_ as Flow, ctx, db, gwCtx) } void 'blocking interrupts data listener calls'() { @@ -92,18 +95,19 @@ class EventDispatcherSpecification extends DDSpecification { set.addSubscription([KnownAddresses.REQUEST_CLIENT_IP], dataListener1) set.addSubscription([KnownAddresses.REQUEST_CLIENT_IP], dataListener2) dispatcher.subscribeDataAvailable(set) + def gwCtx = new GatewayContext(true, false) when: def subscribers = dispatcher.getDataSubscribers(KnownAddresses.REQUEST_CLIENT_IP) DataBundle db = MapDataBundle.of(KnownAddresses.REQUEST_CLIENT_IP, '::1') - ChangeableFlow resultFlow = dispatcher.publishDataEvent(subscribers, ctx, db, true, false) + ChangeableFlow resultFlow = dispatcher.publishDataEvent(subscribers, ctx, db, gwCtx) then: - 1 * dataListener1.onDataAvailable(_ as Flow, ctx, _ as DataBundle, true, false) >> { + 1 * dataListener1.onDataAvailable(_ as Flow, ctx, _ as DataBundle, gwCtx) >> { ChangeableFlow flow = it.first() flow.action = new Flow.Action.RequestBlockingAction(404, BlockingContentType.AUTO) } - 0 * dataListener2.onDataAvailable(_ as Flow, ctx, _ as DataBundle, _ as boolean, _ as boolean) + 0 * dataListener2.onDataAvailable(_ as Flow, ctx, _ as DataBundle, _ as GatewayContext) assert resultFlow.blocking assert resultFlow.action.statusCode == 404 assert resultFlow.action.blockingContentType == BlockingContentType.AUTO @@ -119,13 +123,14 @@ class EventDispatcherSpecification extends DDSpecification { def set = new EventDispatcher.DataSubscriptionSet() set.addSubscription([KnownAddresses.REQUEST_CLIENT_IP], listener) dispatcher.subscribeDataAvailable(set) + def gwCtx = new GatewayContext(false, false) when: def subscribers = dispatcher.getDataSubscribers(KnownAddresses.REQUEST_CLIENT_IP) - dispatcher.publishDataEvent(subscribers, ctx, db, false, false) + dispatcher.publishDataEvent(subscribers, ctx, db, gwCtx) then: - 1 * listener.onDataAvailable(_ as Flow, ctx, db, false, false) + 1 * listener.onDataAvailable(_ as Flow, ctx, db, gwCtx) 1 * ctx.addAll(db) } @@ -155,7 +160,8 @@ class EventDispatcherSpecification extends DDSpecification { EventDispatcher anotherDispatcher = new EventDispatcher() EventProducerService.DataSubscriberInfo subInfo = anotherDispatcher.getDataSubscribers(KnownAddresses.REQUEST_CLIENT_IP) - dispatcher.publishDataEvent(subInfo, Stub(AppSecRequestContext), Stub(DataBundle), false, false) + def gwCtx = new GatewayContext(false, false) + dispatcher.publishDataEvent(subInfo, Stub(AppSecRequestContext), Stub(DataBundle), gwCtx) then: thrown ExpiredSubscriberInfoException 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 c72956ae1b1..39c0792160f 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 @@ -57,6 +57,7 @@ class GatewayBridgeSpecification extends DDSpecification { i.empty >> false i }() + GatewayContext gwCtx = new GatewayContext(false, false) TraceSegmentPostProcessor pp = Mock() GatewayBridge bridge = new GatewayBridge(ig, eventDispatcher, null, [pp]) @@ -214,7 +215,7 @@ class GatewayBridgeSpecification extends DDSpecification { ctx.data.rawURI = '/' ctx.data.peerAddress = '0.0.0.0' eventDispatcher.getDataSubscribers(_) >> nonEmptyDsInfo - eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> + eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> { bundle = it[2]; NoopFlow.INSTANCE } and: @@ -229,11 +230,12 @@ class GatewayBridgeSpecification extends DDSpecification { void 'the socket address is distributed'() { DataBundle bundle + GatewayContext gatewayContext when: eventDispatcher.getDataSubscribers(_) >> nonEmptyDsInfo - eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> - { bundle = it[2]; NoopFlow.INSTANCE } + eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { bundle = it[2]; gatewayContext = it[3]; NoopFlow.INSTANCE } and: reqHeadersDoneCB.apply(ctx) @@ -243,15 +245,18 @@ class GatewayBridgeSpecification extends DDSpecification { then: bundle.get(KnownAddresses.REQUEST_CLIENT_IP) == '0.0.0.0' bundle.get(KnownAddresses.REQUEST_CLIENT_PORT) == 5555 + gatewayContext.isTransient == false + gatewayContext.isRasp == false } void 'the inferred ip address is distributed if published before the socket address'() { DataBundle bundle + GatewayContext gatewayContext when: eventDispatcher.getDataSubscribers(_) >> nonEmptyDsInfo - eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> - { bundle = it[2]; NoopFlow.INSTANCE } + eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { bundle = it[2]; gatewayContext = it[3]; NoopFlow.INSTANCE } and: reqHeadersDoneCB.apply(ctx) @@ -261,15 +266,18 @@ class GatewayBridgeSpecification extends DDSpecification { then: bundle.get(KnownAddresses.REQUEST_INFERRED_CLIENT_IP) == '1.2.3.4' + gatewayContext.isTransient == false + gatewayContext.isRasp == false } void 'setting headers then request uri triggers initial data event'() { DataBundle bundle + GatewayContext gatewayContext when: eventDispatcher.getDataSubscribers(_) >> nonEmptyDsInfo - eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> - { bundle = it[2]; NoopFlow.INSTANCE } + eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { bundle = it[2]; gatewayContext = it[3]; NoopFlow.INSTANCE } and: reqHeadersDoneCB.apply(ctx) @@ -278,16 +286,19 @@ class GatewayBridgeSpecification extends DDSpecification { then: bundle.get(KnownAddresses.REQUEST_URI_RAW) == '/a' + gatewayContext.isTransient == false + gatewayContext.isRasp == false } void 'the raw request uri is provided and decoded'() { DataBundle bundle + GatewayContext gatewayContext def adapter = TestURIDataAdapter.create(uri, supportsRaw) when: eventDispatcher.getDataSubscribers({ KnownAddresses.REQUEST_URI_RAW in it }) >> nonEmptyDsInfo - eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> - { bundle = it[2]; NoopFlow.INSTANCE } + eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { bundle = it[2]; gatewayContext = it[3]; NoopFlow.INSTANCE } and: requestMethodURICB.apply(ctx, 'GET', adapter) @@ -295,7 +306,9 @@ class GatewayBridgeSpecification extends DDSpecification { requestSocketAddressCB.apply(ctx, '0.0.0.0', 5555) then: - assert bundle.get(KnownAddresses.REQUEST_URI_RAW) == expected + bundle.get(KnownAddresses.REQUEST_URI_RAW) == expected + gatewayContext.isTransient == false + gatewayContext.isRasp == false if (null != uri) { def query = bundle.get(KnownAddresses.REQUEST_QUERY) @@ -312,13 +325,14 @@ class GatewayBridgeSpecification extends DDSpecification { void 'exercise all decoding paths'() { DataBundle bundle + GatewayContext gatewayContext String uri = "/?foo=$encoded" def adapter = TestURIDataAdapter.create(uri) when: eventDispatcher.getDataSubscribers({ KnownAddresses.REQUEST_URI_RAW in it }) >> nonEmptyDsInfo - eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> - { bundle = it[2]; NoopFlow.INSTANCE } + eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { bundle = it[2]; gatewayContext = it[3]; NoopFlow.INSTANCE } and: requestMethodURICB.apply(ctx, 'GET', adapter) @@ -327,7 +341,9 @@ class GatewayBridgeSpecification extends DDSpecification { then: def query = bundle.get(KnownAddresses.REQUEST_QUERY) - assert query['foo'] == [decoded] + query['foo'] == [decoded] + gatewayContext.isTransient == false + gatewayContext.isRasp == false where: encoded | decoded @@ -344,17 +360,20 @@ class GatewayBridgeSpecification extends DDSpecification { void 'path params are published'() { DataBundle bundle + GatewayContext gatewayContext when: eventDispatcher.getDataSubscribers({ KnownAddresses.REQUEST_PATH_PARAMS in it }) >> nonEmptyDsInfo - eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> - { bundle = it[2]; NoopFlow.INSTANCE } + eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { bundle = it[2]; gatewayContext = it[3]; NoopFlow.INSTANCE } and: pathParamsCB.apply(ctx, [a: 'b']) then: - assert bundle.get(KnownAddresses.REQUEST_PATH_PARAMS) == [a: 'b'] + bundle.get(KnownAddresses.REQUEST_PATH_PARAMS) == [a: 'b'] + gatewayContext.isTransient == false + gatewayContext.isRasp == false } void 'path params is not published twice'() { @@ -520,19 +539,22 @@ class GatewayBridgeSpecification extends DDSpecification { void 'forwards request body done events and distributes the body contents'() { DataBundle bundle + GatewayContext gatewayContext StoredBodySupplier supplier = Stub() setup: supplier.get() >> 'foobar' eventDispatcher.getDataSubscribers({ KnownAddresses.REQUEST_BODY_RAW in it }) >> nonEmptyDsInfo - eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> - { bundle = it[2]; NoopFlow.INSTANCE } + eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { bundle = it[2]; gatewayContext = it[3]; NoopFlow.INSTANCE } when: requestBodyDoneCB.apply(ctx, supplier) then: bundle.get(KnownAddresses.REQUEST_BODY_RAW) == 'foobar' + gatewayContext.isTransient == false + gatewayContext.isRasp == false } void 'request body does not get published twice'() { @@ -553,17 +575,21 @@ class GatewayBridgeSpecification extends DDSpecification { void 'forward request body processed'() { DataBundle bundle + GatewayContext gatewayContext Object obj = 'hello' setup: eventDispatcher.getDataSubscribers({KnownAddresses.REQUEST_BODY_OBJECT in it}) >> nonEmptyDsInfo - eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> { bundle = it[2]; NoopFlow.INSTANCE } + eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) + >> { bundle = it[2]; gatewayContext = it[3]; NoopFlow.INSTANCE } when: requestBodyProcessedCB.apply(ctx, obj) then: bundle.get(KnownAddresses.REQUEST_BODY_OBJECT) == 'hello' + gatewayContext.isTransient == false + gatewayContext.isRasp == false } void 'processed body does not published twice'() { @@ -583,6 +609,7 @@ class GatewayBridgeSpecification extends DDSpecification { setup: eventDispatcher.getDataSubscribers({ KnownAddresses.REQUEST_BODY_OBJECT in it }) >> nonEmptyDsInfo DataBundle bundle + GatewayContext gatewayContext when: Flow flow = requestBodyProcessedCB.apply(ctx, new Object() { @@ -591,21 +618,24 @@ class GatewayBridgeSpecification extends DDSpecification { }) then: - 1 * eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> - { a, b, db, c, e -> bundle = db; NoopFlow.INSTANCE } + 1 * eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { a, b, db, gw -> bundle = db; gatewayContext = gw; NoopFlow.INSTANCE } bundle.get(KnownAddresses.REQUEST_BODY_OBJECT) == [foo: 'bar'] flow.result == null flow.action == Flow.Action.Noop.INSTANCE + gatewayContext.isTransient == false + gatewayContext.isRasp == false } void 'forwards request method'() { DataBundle bundle + GatewayContext gatewayContext def adapter = TestURIDataAdapter.create('http://example.com/') setup: eventDispatcher.getDataSubscribers({ KnownAddresses.REQUEST_METHOD in it }) >> nonEmptyDsInfo - eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> - { bundle = it[2]; NoopFlow.INSTANCE } + eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { bundle = it[2]; gatewayContext = it[3]; NoopFlow.INSTANCE } when: requestMethodURICB.apply(ctx, 'POST', adapter) @@ -614,16 +644,19 @@ class GatewayBridgeSpecification extends DDSpecification { then: bundle.get(KnownAddresses.REQUEST_METHOD) == 'POST' + gatewayContext.isTransient == false + gatewayContext.isRasp == false } void 'scheme is extracted from the uri adapter'() { DataBundle bundle + GatewayContext gatewayContext def adapter = TestURIDataAdapter.create('https://example.com/') when: eventDispatcher.getDataSubscribers({ KnownAddresses.REQUEST_SCHEME in it }) >> nonEmptyDsInfo - eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> - { bundle = it[2]; NoopFlow.INSTANCE } + eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { bundle = it[2]; gatewayContext = it[3]; NoopFlow.INSTANCE } and: requestMethodURICB.apply(ctx, 'GET', adapter) @@ -632,6 +665,8 @@ class GatewayBridgeSpecification extends DDSpecification { then: bundle.get(KnownAddresses.REQUEST_SCHEME) == 'https' + gatewayContext.isTransient == false + gatewayContext.isRasp == false } void 'request data does not published twice'() { @@ -661,7 +696,7 @@ class GatewayBridgeSpecification extends DDSpecification { Flow flow2 = respHeadersDoneCB.apply(ctx) then: - 1 * eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, false, false) >> + 1 * eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> { NoopFlow.INSTANCE } flow1.result == null flow1.action == Flow.Action.Noop.INSTANCE @@ -673,6 +708,7 @@ class GatewayBridgeSpecification extends DDSpecification { setup: eventDispatcher.getDataSubscribers({ KnownAddresses.GRPC_SERVER_REQUEST_MESSAGE in it }) >> nonEmptyDsInfo DataBundle bundle + GatewayContext gatewayContext when: Flow flow = grpcServerRequestMessageCB.apply(ctx, new Object() { @@ -681,25 +717,31 @@ class GatewayBridgeSpecification extends DDSpecification { }) then: - 1 * eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, true, false) >> - { a, b, db, c, e -> bundle = db; NoopFlow.INSTANCE } + 1 * eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { a, b, db, gw -> bundle = db; gatewayContext = gw; NoopFlow.INSTANCE } bundle.get(KnownAddresses.GRPC_SERVER_REQUEST_MESSAGE) == [foo: 'bar'] flow.result == null flow.action == Flow.Action.Noop.INSTANCE + gatewayContext.isTransient == true + gatewayContext.isRasp == false } void 'grpc server method publishes'() { setup: eventDispatcher.getDataSubscribers(KnownAddresses.GRPC_SERVER_METHOD) >> nonEmptyDsInfo DataBundle bundle + GatewayContext gatewayContext when: Flow flow = grpcServerMethodCB.apply(ctx, '/my.package.Greeter/SayHello') then: - 1 * eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, true, false) >> - { args -> bundle = args[2]; NoopFlow.INSTANCE } + 1 * eventDispatcher.publishDataEvent(nonEmptyDsInfo, ctx.data, _ as DataBundle, _ as GatewayContext) >> + { args -> bundle = args[2]; gatewayContext = args[3]; NoopFlow.INSTANCE } bundle.get(KnownAddresses.GRPC_SERVER_METHOD) == '/my.package.Greeter/SayHello' + gatewayContext != null + gatewayContext.isTransient == true + gatewayContext.isRasp == false flow.result == null flow.action == Flow.Action.Noop.INSTANCE } diff --git a/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/powerwaf/PowerWAFModuleSpecification.groovy b/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/powerwaf/PowerWAFModuleSpecification.groovy index 58faa857c9f..72f91df9e43 100644 --- a/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/powerwaf/PowerWAFModuleSpecification.groovy +++ b/dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/powerwaf/PowerWAFModuleSpecification.groovy @@ -14,6 +14,7 @@ import com.datadog.appsec.event.data.DataBundle import com.datadog.appsec.event.data.KnownAddresses import com.datadog.appsec.event.data.MapDataBundle import com.datadog.appsec.gateway.AppSecRequestContext +import com.datadog.appsec.gateway.GatewayContext import com.datadog.appsec.report.AppSecEvent import com.datadog.appsec.stack_trace.StackTraceEvent import com.datadog.appsec.test.StubAppSecConfigService @@ -54,6 +55,7 @@ class PowerWAFModuleSpecification extends DDSpecification { } AppSecRequestContext ctx = Spy() + GatewayContext gwCtx = new GatewayContext(false, false) StubAppSecConfigService service PowerWAFModule pwafModule = new PowerWAFModule() @@ -193,7 +195,7 @@ class PowerWAFModuleSpecification extends DDSpecification { KnownAddresses.REQUEST_INFERRED_CLIENT_IP, '1.2.3.4' ) - dataListener.onDataAvailable(flow, ctx, newBundle, false, false) + dataListener.onDataAvailable(flow, ctx, newBundle, gwCtx) ctx.closeAdditive() then: @@ -227,7 +229,7 @@ class PowerWAFModuleSpecification extends DDSpecification { KnownAddresses.USER_ID, 'user-to-block-1' ) - dataListener.onDataAvailable(flow, ctx, bundle, false, false) + dataListener.onDataAvailable(flow, ctx, bundle, gwCtx) ctx.closeAdditive() then: @@ -267,7 +269,7 @@ class PowerWAFModuleSpecification extends DDSpecification { it.dirtyStatus.clearDirty() } - dataListener.onDataAvailable(flow, ctx, bundle, false, false) + dataListener.onDataAvailable(flow, ctx, bundle, gwCtx) ctx.closeAdditive() then: @@ -292,7 +294,7 @@ class PowerWAFModuleSpecification extends DDSpecification { KnownAddresses.USER_ID, 'user-to-block-2' ) - dataListener.onDataAvailable(flow, ctx, bundle, false, false) + dataListener.onDataAvailable(flow, ctx, bundle, gwCtx) ctx.closeAdditive() then: @@ -347,7 +349,7 @@ class PowerWAFModuleSpecification extends DDSpecification { KnownAddresses.USER_ID, 'user-to-block-2' ) - dataListener.onDataAvailable(flow, ctx, bundle, false, false) + dataListener.onDataAvailable(flow, ctx, bundle, gwCtx) ctx.closeAdditive() then: @@ -372,7 +374,7 @@ class PowerWAFModuleSpecification extends DDSpecification { KnownAddresses.USER_ID, 'user-to-block-1' ) - dataListener.onDataAvailable(flow, ctx, bundle, false, false) + dataListener.onDataAvailable(flow, ctx, bundle, gwCtx) ctx.closeAdditive() then: @@ -428,7 +430,7 @@ class PowerWAFModuleSpecification extends DDSpecification { 1 * reconf.reloadSubscriptions() when: - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -450,7 +452,7 @@ class PowerWAFModuleSpecification extends DDSpecification { KnownAddresses.REQUEST_INFERRED_CLIENT_IP, '192.168.0.1' ) - dataListener.onDataAvailable(flow, ctx, newBundle, false, false) + dataListener.onDataAvailable(flow, ctx, newBundle, gwCtx) ctx.closeAdditive() then: @@ -508,7 +510,7 @@ class PowerWAFModuleSpecification extends DDSpecification { 1 * reconf.reloadSubscriptions() when: - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -582,7 +584,7 @@ class PowerWAFModuleSpecification extends DDSpecification { 2 * reconf.reloadSubscriptions() when: - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -607,7 +609,7 @@ class PowerWAFModuleSpecification extends DDSpecification { DataBundle bundle = MapDataBundle.of(KnownAddresses.HEADERS_NO_COOKIES, new CaseInsensitiveMap>(['user-agent': 'redirect' + variant])) def flow = new ChangeableFlow() - dataListener.onDataAvailable(flow, ctx, bundle, false, false) + dataListener.onDataAvailable(flow, ctx, bundle, gwCtx) ctx.closeAdditive() then: @@ -672,7 +674,7 @@ class PowerWAFModuleSpecification extends DDSpecification { ChangeableFlow flow = new ChangeableFlow() when: - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -701,7 +703,7 @@ class PowerWAFModuleSpecification extends DDSpecification { ChangeableFlow flow = new ChangeableFlow() when: - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -726,7 +728,7 @@ class PowerWAFModuleSpecification extends DDSpecification { when: setupWithStubConfigService() pp = service.traceSegmentPostProcessors[1] - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() pp.processTraceSegment(segment, ctx, []) @@ -752,7 +754,7 @@ class PowerWAFModuleSpecification extends DDSpecification { ChangeableFlow flow = new ChangeableFlow() when: - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) then: 1 * ctx.getOrCreateAdditive(_, true, false) >> { @@ -778,7 +780,7 @@ class PowerWAFModuleSpecification extends DDSpecification { pwafModule = new PowerWAFModule() // replace the one created too soon when: - dataListener.onDataAvailable(Stub(ChangeableFlow), ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(Stub(ChangeableFlow), ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -816,7 +818,7 @@ class PowerWAFModuleSpecification extends DDSpecification { when: def bundle = MapDataBundle.of(KnownAddresses.HEADERS_NO_COOKIES, new CaseInsensitiveMap>(['user-agent': [password: 'Arachni/v0']])) - dataListener.onDataAvailable(Stub(ChangeableFlow), ctx, bundle, false, false) + dataListener.onDataAvailable(Stub(ChangeableFlow), ctx, bundle, gwCtx) ctx.closeAdditive() then: @@ -839,7 +841,7 @@ class PowerWAFModuleSpecification extends DDSpecification { when: def bundle = MapDataBundle.of(KnownAddresses.HEADERS_NO_COOKIES, new CaseInsensitiveMap>(['user-agent': [password: 'Arachni/v0']])) - dataListener.onDataAvailable(Stub(ChangeableFlow), ctx, bundle, false, false) + dataListener.onDataAvailable(Stub(ChangeableFlow), ctx, bundle, gwCtx) ctx.closeAdditive() then: @@ -861,7 +863,7 @@ class PowerWAFModuleSpecification extends DDSpecification { AppSecEvent event when: - dataListener.onDataAvailable(Stub(ChangeableFlow), ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(Stub(ChangeableFlow), ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -883,7 +885,7 @@ class PowerWAFModuleSpecification extends DDSpecification { new CaseInsensitiveMap>(['user-agent': 'Harmless'])) when: - dataListener.onDataAvailable(flow, ctx, db, false, false) + dataListener.onDataAvailable(flow, ctx, db, gwCtx) then: ctx.getOrCreateAdditive(_, true) >> { @@ -912,7 +914,7 @@ class PowerWAFModuleSpecification extends DDSpecification { ]) when: - dataListener.onDataAvailable(flow, ctx, db, false, false) + dataListener.onDataAvailable(flow, ctx, db, gwCtx) then: ctx.getOrCreateAdditive(_, true) >> { @@ -927,7 +929,7 @@ class PowerWAFModuleSpecification extends DDSpecification { DataBundle db = MapDataBundle.of(KnownAddresses.HEADERS_NO_COOKIES, [get: { null }] as List) when: - dataListener.onDataAvailable(flow, ctx, db, false, false) + dataListener.onDataAvailable(flow, ctx, db, gwCtx) then: ctx.getOrCreateAdditive(_, true) >> { @@ -949,7 +951,7 @@ class PowerWAFModuleSpecification extends DDSpecification { TraceSegmentPostProcessor pp = service.traceSegmentPostProcessors.last() when: - dataListener.onDataAvailable(flow, ctx, db, false, false) + dataListener.onDataAvailable(flow, ctx, db, gwCtx) then: ctx.getOrCreateAdditive(_, true) >> { @@ -983,7 +985,7 @@ class PowerWAFModuleSpecification extends DDSpecification { when: cfgService.listeners['waf'].onNewSubconfig(defaultConfig['waf'], reconf) dataListener = pwafModule.dataSubscriptions.first() - dataListener.onDataAvailable(Stub(ChangeableFlow), ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(Stub(ChangeableFlow), ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -1018,7 +1020,7 @@ class PowerWAFModuleSpecification extends DDSpecification { dataListener = pwafModule.dataSubscriptions.first() def bundle = MapDataBundle.of(KnownAddresses.REQUEST_INFERRED_CLIENT_IP, '1.2.3.4') - dataListener.onDataAvailable(flow, ctx, bundle, false, false) + dataListener.onDataAvailable(flow, ctx, bundle, gwCtx) ctx.closeAdditive() then: @@ -1074,7 +1076,7 @@ class PowerWAFModuleSpecification extends DDSpecification { dataListener = pwafModule.dataSubscriptions.first() def bundle = MapDataBundle.of(KnownAddresses.REQUEST_INFERRED_CLIENT_IP, '1.2.3.4') - dataListener.onDataAvailable(flow, ctx, bundle, false, false) + dataListener.onDataAvailable(flow, ctx, bundle, gwCtx) ctx.closeAdditive() then: 'no match; rule is disabled' @@ -1097,7 +1099,7 @@ class PowerWAFModuleSpecification extends DDSpecification { it.dirtyStatus.clearDirty() } - dataListener.onDataAvailable(flow, ctx, bundle, false, false) + dataListener.onDataAvailable(flow, ctx, bundle, gwCtx) ctx.closeAdditive() then: 'no match; data was cleared (though rule is no longer disabled)' @@ -1117,7 +1119,7 @@ class PowerWAFModuleSpecification extends DDSpecification { it.dirtyStatus.clearDirty() } - dataListener.onDataAvailable(flow, ctx, bundle, false, false) + dataListener.onDataAvailable(flow, ctx, bundle, gwCtx) ctx.closeAdditive() then: 'now we have match' @@ -1144,7 +1146,7 @@ class PowerWAFModuleSpecification extends DDSpecification { it.dirtyStatus.clearDirty() } - dataListener.onDataAvailable(flow, ctx, bundle, false, false) + dataListener.onDataAvailable(flow, ctx, bundle, gwCtx) ctx.closeAdditive() then: 'nothing again; we disabled the rule' @@ -1172,7 +1174,7 @@ class PowerWAFModuleSpecification extends DDSpecification { it.dirtyStatus.clearDirty() } dataListener = pwafModule.dataSubscriptions.first() - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -1194,7 +1196,7 @@ class PowerWAFModuleSpecification extends DDSpecification { service.listeners['waf'].onNewSubconfig(it, reconf) it.dirtyStatus.clearDirty() } - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -1217,7 +1219,7 @@ class PowerWAFModuleSpecification extends DDSpecification { service.listeners['waf'].onNewSubconfig(it, reconf) it.dirtyStatus.clearDirty() } - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -1243,7 +1245,7 @@ class PowerWAFModuleSpecification extends DDSpecification { service.listeners['waf'].onNewSubconfig(it, reconf) it.dirtyStatus.clearDirty() } - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -1355,7 +1357,7 @@ class PowerWAFModuleSpecification extends DDSpecification { KnownAddresses.REQUEST_BODY_OBJECT, '/cybercop' ) - dataListener.onDataAvailable(flow, ctx, transientBundle, false, false) + dataListener.onDataAvailable(flow, ctx, transientBundle, gwCtx) then: 1 * ctx.getOrCreateAdditive(_, true, false) >> { @@ -1370,7 +1372,7 @@ class PowerWAFModuleSpecification extends DDSpecification { 0 * _ when: - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) ctx.closeAdditive() then: @@ -1401,7 +1403,7 @@ class PowerWAFModuleSpecification extends DDSpecification { when: for (int t = 0; t < 20; t++) { CountDownLatch latch = new CountDownLatch(1) - dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false, false) + dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx) Thread thread = new Thread({ p -> latch.countDown() ctx.closeAdditive()