Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace ASM transient mechanism with WAF ephemeral addresses #6687

Merged
merged 1 commit into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.datadog.appsec.event.data.Address;
import com.datadog.appsec.event.data.DataBundle;
import com.datadog.appsec.event.data.KnownAddresses;
import com.datadog.appsec.report.AppSecEvent;
import com.datadog.appsec.util.StandardizedLogging;
import datadog.trace.api.http.StoredBodySupplier;
Expand Down Expand Up @@ -74,6 +73,7 @@ public class AppSecRequestContext implements DataBundle, Closeable {
private boolean rawReqBodyPublished;
private boolean convertedReqBodyPublished;
private boolean respDataPublished;
private boolean pathParamsPublished;
private Map<String, String> apiSchemas;

// should be guarded by this
Expand Down Expand Up @@ -327,7 +327,11 @@ public void setReqDataPublished(boolean reqDataPublished) {
}

public boolean isPathParamsPublished() {
return persistentData.containsKey(KnownAddresses.REQUEST_PATH_PARAMS);
return pathParamsPublished;
}

public void setPathParamsPublished(boolean pathParamsPublished) {
this.pathParamsPublished = pathParamsPublished;
}

public boolean isRawReqBodyPublished() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,10 @@ public void init() {
EVENTS.requestPathParams(),
(ctx_, data) -> {
AppSecRequestContext ctx = ctx_.getData(RequestContextSlot.APPSEC);
if (ctx == null) {
return NoopFlow.INSTANCE;
}

if (ctx.isPathParamsPublished()) {
log.debug("Second or subsequent publication of request params");
if (ctx == null || ctx.isPathParamsPublished()) {
return NoopFlow.INSTANCE;
}
ctx.setPathParamsPublished(true);

while (true) {
DataSubscriberInfo subInfo = pathParamsSubInfo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -511,8 +511,7 @@ private Powerwaf.ResultWithData doRunPowerwaf(
PowerwafMetrics metrics = reqCtx.getWafMetrics();

if (isTransient) {
DataBundle bundle = DataBundle.unionOf(newData, reqCtx);
return runPowerwafTransient(metrics, bundle, ctxAndAddr);
return runPowerwafTransient(additive, metrics, newData, ctxAndAddr);
} else {
return runPowerwafAdditive(additive, metrics, newData, ctxAndAddr);
}
Expand All @@ -527,9 +526,9 @@ private Powerwaf.ResultWithData runPowerwafAdditive(
}

private Powerwaf.ResultWithData runPowerwafTransient(
PowerwafMetrics metrics, DataBundle bundle, CtxAndAddresses ctxAndAddr)
Additive additive, PowerwafMetrics metrics, DataBundle bundle, CtxAndAddresses ctxAndAddr)
throws AbstractPowerwafException {
return ctxAndAddr.ctx.runRules(
return additive.runEphemeral(
new DataBundleMapWrapper(ctxAndAddr.addressesOfInterest, bundle), LIMITS, metrics);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.datadog.appsec.event.EventDispatcher
import com.datadog.appsec.event.EventProducerService
import com.datadog.appsec.event.data.DataBundle
import com.datadog.appsec.event.data.KnownAddresses
import com.datadog.appsec.event.data.SingletonDataBundle
import com.datadog.appsec.report.AppSecEvent
import com.datadog.appsec.report.AppSecEventWrapper
import datadog.trace.api.internal.TraceSegment
Expand Down Expand Up @@ -380,8 +379,10 @@ class GatewayBridgeSpecification extends DDSpecification {
void 'path params is not published twice'() {
Flow flow

setup:
pathParamsCB.apply(ctx, [a: 'b'])

when:
arCtx.addAll(new SingletonDataBundle(KnownAddresses.REQUEST_PATH_PARAMS, [a: 'b']))
flow = pathParamsCB.apply(ctx, [c: 'd'])

then:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,44 @@ class PowerWAFModuleSpecification extends DDSpecification {
ret.isEmpty()
}

void 'ephemeral and persistent addresses'() {
setupWithStubConfigService()
ChangeableFlow flow = Mock()

when:
def transientBundle = MapDataBundle.of(
KnownAddresses.REQUEST_BODY_OBJECT,
'/cybercop'
)
dataListener.onDataAvailable(flow, ctx, transientBundle, false)

then:
1 * ctx.getOrCreateAdditive(_, true) >> {
pwafAdditive = it[0].openAdditive() }
1 * ctx.reportEvents(_ as Collection<AppSecEvent>) >> {
it[0].iterator().next().ruleMatches[0].parameters[0].value == '/cybercop'
}
1 * ctx.getWafMetrics()
1 * flow.isBlocking()
0 * _

when:
dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, false)
ctx.closeAdditive()

then:
1 * ctx.getOrCreateAdditive(_, true) >> {
pwafAdditive }
1 * flow.setAction({ it.blocking })
1 * ctx.reportEvents(_ as Collection<AppSecEvent>) >> {
it[0].iterator().next().ruleMatches[0].parameters[0].value == 'user-to-block-1'
}
1 * ctx.getWafMetrics()
1 * ctx.closeAdditive()
1 * flow.isBlocking()
0 * _
}

/**
* This test simulates double REQUEST_END with increasing interval
* The race condition shouldn't happen when closing Additive
Expand Down
Loading