Skip to content

Update metrics: appsec.waf.updates and appsec.waf.init #8280

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

Merged
merged 3 commits into from
Feb 3, 2025
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 @@ -245,12 +245,6 @@ private void initializeNewWafCtx(
currentRulesVersion = initReport.rulesetVersion;
}

if (prevContextAndAddresses == null) {
WafMetricCollector.get().wafInit(Powerwaf.LIB_VERSION, currentRulesVersion);
} else {
WafMetricCollector.get().wafUpdates(currentRulesVersion);
}

if (initReport != null) {
log.info(
"Created {} WAF context with rules ({} OK, {} BAD), version {}",
Expand All @@ -273,11 +267,13 @@ private void initializeNewWafCtx(
}
} catch (InvalidRuleSetException irse) {
initReport = irse.ruleSetInfo;
sendWafMetrics(prevContextAndAddresses, false);
throw new AppSecModuleActivationException("Error creating WAF rules", irse);
} catch (RuntimeException | AbstractPowerwafException e) {
if (newPwafCtx != null) {
newPwafCtx.close();
}
sendWafMetrics(prevContextAndAddresses, false);
throw new AppSecModuleActivationException("Error creating WAF rules", e);
} finally {
if (initReport != null) {
Expand All @@ -287,16 +283,27 @@ private void initializeNewWafCtx(

if (!this.ctxAndAddresses.compareAndSet(prevContextAndAddresses, newContextAndAddresses)) {
newPwafCtx.close();
sendWafMetrics(prevContextAndAddresses, false);
throw new AppSecModuleActivationException("Concurrent update of WAF configuration");
}

sendWafMetrics(prevContextAndAddresses, true);

if (prevContextAndAddresses != null) {
prevContextAndAddresses.ctx.close();
}

reconf.reloadSubscriptions();
}

private void sendWafMetrics(CtxAndAddresses prevContextAndAddresses, boolean success) {
if (prevContextAndAddresses == null) {
WafMetricCollector.get().wafInit(Powerwaf.LIB_VERSION, currentRulesVersion, success);
} else {
WafMetricCollector.get().wafUpdates(currentRulesVersion, success);
}
}

private Map<String, ActionInfo> calculateEffectiveActions(
CtxAndAddresses prevContextAndAddresses, AppSecConfig ruleConfig) {
Map<String, ActionInfo> actionInfoMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ class PowerWAFModuleSpecification extends DDSpecification {
Additive pwafAdditive
PowerwafMetrics metrics

WafMetricCollector wafMetricCollector = Mock(WafMetricCollector)

void setup() {
WafMetricCollector.INSTANCE = wafMetricCollector
AgentTracer.forceRegister(tracer)
}

Expand Down Expand Up @@ -206,6 +209,8 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then:
1 * wafMetricCollector.wafInit(Powerwaf.LIB_VERSION, _, true)
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
1 * flow.setAction({ Flow.Action.RequestBlockingAction rba ->
rba.statusCode == 501 &&
Expand Down Expand Up @@ -241,6 +246,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then:
1 * wafMetricCollector.wafInit(Powerwaf.LIB_VERSION, _, true)
1 * flow.setAction({ Flow.Action.RequestBlockingAction rba ->
rba.statusCode == 403 &&
rba.blockingContentType == BlockingContentType.AUTO
Expand Down Expand Up @@ -282,6 +288,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then:
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
1 * flow.setAction({ Flow.Action.RequestBlockingAction rba ->
rba.statusCode == 403 &&
Expand Down Expand Up @@ -364,6 +371,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then:
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
1 * flow.setAction({ Flow.Action.RequestBlockingAction rba ->
rba.statusCode == 403 &&
Expand Down Expand Up @@ -440,7 +448,10 @@ class PowerWAFModuleSpecification extends DDSpecification {
}

then:
1 * wafMetricCollector.wafInit(Powerwaf.LIB_VERSION, _, true)
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
0 * _

when:
dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx)
Expand Down Expand Up @@ -522,7 +533,10 @@ class PowerWAFModuleSpecification extends DDSpecification {
}

then:
1 * wafMetricCollector.wafInit(Powerwaf.LIB_VERSION, _, true)
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
0 * _

when:
dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx)
Expand Down Expand Up @@ -597,7 +611,10 @@ class PowerWAFModuleSpecification extends DDSpecification {
}

then:
1 * wafMetricCollector.wafInit(Powerwaf.LIB_VERSION, _, true)
2 * wafMetricCollector.wafUpdates(_, true)
2 * reconf.reloadSubscriptions()
0 * _

when:
dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx)
Expand Down Expand Up @@ -972,9 +989,6 @@ class PowerWAFModuleSpecification extends DDSpecification {
TraceSegment segment = Mock()
TraceSegmentPostProcessor pp = service.traceSegmentPostProcessors.last()

def mockWafMetricCollector = Mock(WafMetricCollector)
WafMetricCollector.INSTANCE = mockWafMetricCollector

when:
dataListener.onDataAvailable(flow, ctx, db, gwCtx)

Expand All @@ -987,7 +1001,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
pwafAdditive = it[0].openAdditive() }
1 * ctx.getWafMetrics()
1 * ctx.increaseWafTimeouts()
1 * mockWafMetricCollector.get().wafRequestTimeout()
1 * wafMetricCollector.get().wafRequestTimeout()
0 * _

when:
Expand All @@ -1014,9 +1028,6 @@ class PowerWAFModuleSpecification extends DDSpecification {
TraceSegment segment = Mock()
TraceSegmentPostProcessor pp = service.traceSegmentPostProcessors.last()

def mockWafMetricCollector = Mock(WafMetricCollector)
WafMetricCollector.INSTANCE = mockWafMetricCollector

gwCtx = new GatewayContext(false, RuleType.SQL_INJECTION)

when:
Expand All @@ -1032,8 +1043,8 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getRaspMetrics()
1 * ctx.getRaspMetricsCounter()
1 * ctx.increaseRaspTimeouts()
1 * mockWafMetricCollector.get().raspTimeout(gwCtx.raspRuleType)
1 * mockWafMetricCollector.raspRuleEval(RuleType.SQL_INJECTION)
1 * wafMetricCollector.get().raspTimeout(gwCtx.raspRuleType)
1 * wafMetricCollector.raspRuleEval(RuleType.SQL_INJECTION)
0 * _

when:
Expand All @@ -1059,6 +1070,7 @@ class PowerWAFModuleSpecification extends DDSpecification {

then:
thrown AppSecModule.AppSecModuleActivationException
0 * _

when:
cfgService.listeners['waf'].onNewSubconfig(defaultConfig['waf'], reconf)
Expand All @@ -1070,7 +1082,14 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getOrCreateAdditive(_, true, false) >> {
pwafAdditive = it[0].openAdditive() }
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.isAdditiveClosed()
1 * ctx.getWafMetrics()
1 * ctx.isThrottled(null)
1 * ctx.closeAdditive()
2 * tracer.activeSpan()
1 * wafMetricCollector.wafInit(Powerwaf.LIB_VERSION, _, true)
1 * reconf.reloadSubscriptions()
0 * _
}

void 'rule data given through configuration'() {
Expand Down Expand Up @@ -1102,6 +1121,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then:
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
1 * ctx.getOrCreateAdditive(_, true, false) >> { pwafAdditive = it[0].openAdditive() }
2 * tracer.activeSpan()
Expand Down Expand Up @@ -1159,6 +1179,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then: 'no match; rule is disabled'
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
1 * ctx.getOrCreateAdditive(_, true, false) >> {
pwafAdditive = it[0].openAdditive() }
Expand Down Expand Up @@ -1189,6 +1210,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getWafMetrics()
1 * ctx.isAdditiveClosed() >> false
1 * ctx.closeAdditive() >> {pwafAdditive.close()}
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
_ * ctx.increaseWafTimeouts()
_ * ctx.increaseRaspTimeouts()
Expand All @@ -1206,6 +1228,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then: 'now we have match'
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
1 * ctx.getOrCreateAdditive(_, true, false) >> {
pwafAdditive = it[0].openAdditive() }
Expand Down Expand Up @@ -1235,6 +1258,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then: 'nothing again; we disabled the rule'
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
1 * ctx.getOrCreateAdditive(_, true, false) >> { pwafAdditive = it[0].openAdditive() }
1 * ctx.getWafMetrics()
Expand Down Expand Up @@ -1265,6 +1289,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then:
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
// no attack
1 * ctx.getOrCreateAdditive(_, true, false) >> { pwafAdditive = it[0].openAdditive() }
Expand All @@ -1289,6 +1314,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then:
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
// no attack
1 * ctx.getOrCreateAdditive(_, true, false) >> {
Expand All @@ -1314,6 +1340,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then:
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
// attack found
1 * ctx.getOrCreateAdditive(_, true, false) >> {
Expand Down Expand Up @@ -1342,6 +1369,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then:
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
// no attack
1 * ctx.getOrCreateAdditive(_, true, false) >> {
Expand Down Expand Up @@ -1390,7 +1418,9 @@ class PowerWAFModuleSpecification extends DDSpecification {
pwafModule.config(cfgService)

then:
1 * wafMetricCollector.wafInit(Powerwaf.LIB_VERSION, _, true)
!pwafModule.dataSubscriptions.first().subscribedAddresses.contains(doesNotExistAddress)
0 * _
}

void 'bad initial configuration is given results in no subscriptions'() {
Expand All @@ -1403,6 +1433,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
then:
thrown AppSecModule.AppSecModuleActivationException
pwafModule.dataSubscriptions.empty
0 * _
}

void 'rule data not a config'() {
Expand All @@ -1414,9 +1445,8 @@ class PowerWAFModuleSpecification extends DDSpecification {

then:
thrown AppSecModule.AppSecModuleActivationException

then:
pwafModule.ctxAndAddresses.get() == null
0 * _
}

void 'bad ResultWithData - empty list'() {
Expand Down Expand Up @@ -1554,7 +1584,18 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then:
1 * ctx.isAdditiveClosed()
1 * ctx.getOrCreateAdditive(_ as PowerwafContext, true, false) >> {
pwafAdditive = it[0].openAdditive()
}
1 * ctx.getWafMetrics()
1 * ctx.isThrottled(null)
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.closeAdditive()
2 * tracer.activeSpan()
1 * flow.isBlocking()
0 * flow.setAction(_)
0 * _

when:
final ipData = new AppSecData(exclusion: [
Expand All @@ -1576,11 +1617,22 @@ class PowerWAFModuleSpecification extends DDSpecification {
ctx.closeAdditive()

then:
1 * wafMetricCollector.wafUpdates(_, true)
1 * reconf.reloadSubscriptions()
1 * flow.setAction({ Flow.Action.RequestBlockingAction rba ->
rba.statusCode == 402 && rba.blockingContentType == BlockingContentType.AUTO
})
1 * flow.isBlocking()
1 * ctx.isAdditiveClosed() >> false
1 * ctx.getOrCreateAdditive(_ as PowerwafContext, true, false) >> {
pwafAdditive = it[0].openAdditive()
}
1 * ctx.getWafMetrics()
1 * ctx.isThrottled(null)
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.closeAdditive()
2 * tracer.activeSpan()
0 * _
}

void 'http endpoint fingerprint support'() {
Expand Down Expand Up @@ -1668,6 +1720,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
then:
1 * ctx.closeAdditive()
1 * ctx.isAdditiveClosed() >> true
1 * wafMetricCollector.wafInit(Powerwaf.LIB_VERSION, _, true)
0 * _
}

Expand Down
Loading
Loading