Skip to content
Open
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 @@ -320,15 +320,25 @@ private void handleWafUpdateResultReport(String configKey, Map<String, Object> r
}
}
} catch (InvalidRuleSetException e) {
log.debug(
log.warn(
"Invalid rule during waf config update for config key {}: {}",
configKey,
e.wafDiagnostics);
if (e.wafDiagnostics.getNumConfigError() > 0) {
WafMetricCollector.get().addWafConfigError(e.wafDiagnostics.getNumConfigError());
}
// TODO: Propagate diagostics back to remote config apply_error

// TODO: Propagate diagnostics back to remote config apply_error
if (e.wafDiagnostics.rulesetVersion != null
&& !e.wafDiagnostics.rulesetVersion.isEmpty()
&& (!defaultConfigActivated || currentRuleVersion == null)) {
currentRuleVersion = e.wafDiagnostics.rulesetVersion;
if (!e.wafDiagnostics.rules.getLoaded().isEmpty()) {
statsReporter.setRulesVersion(currentRuleVersion);
}
if (modulesToUpdateVersionIn != null) {
modulesToUpdateVersionIn.forEach(module -> module.setRuleVersion(currentRuleVersion));
}
}
initReporter.setReportForPublication(e.wafDiagnostics);
throw new RuntimeException(e);
} catch (UnclassifiedWafException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.datadog.appsec.config

import com.datadog.appsec.AppSecModule
import com.datadog.appsec.AppSecSystem
import com.datadog.appsec.util.AbortStartupException
import static datadog.remoteconfig.Capabilities.CAPABILITY_ASM_EXTENDED_DATA_COLLECTION
Expand Down Expand Up @@ -703,6 +704,49 @@ class AppSecConfigServiceImplSpecification extends DDSpecification {
noExceptionThrown()
}

void 'currentRuleVersion is updated from diagnostics when InvalidRuleSetException is thrown on RC update'() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Move the new regression test to JUnit 5

The root AGENTS.md for this repo says, “Test frameworks: Always use JUnit 5. Do not write new Groovy / Spock tests,” but this change adds a new Spock test method to the Groovy spec. Even though the surrounding file is existing Groovy, new coverage should be added as a JUnit 5 test (or the relevant spec migrated) to avoid expanding the deprecated test style.

Useful? React with 👍 / 👎.

setup:
final key = new ParsedConfigKey('Test', '1234', 1, 'ASM_DD', 'ID')
final service = new AppSecConfigServiceImpl(config, poller, reconf)
AppSecSystem.active = true
config.getAppSecActivation() >> ProductActivation.FULLY_ENABLED
AppSecModule wafModule = Mock()
wafModule.isWafBuilderSet() >> false
service.modulesToUpdateVersionIn([wafModule])

when:
service.maybeSubscribeConfigPolling()

then:
1 * poller.addListener(Product.ASM_DD, _) >> {
listeners.savedWafDataChangesListener = it[1]
}

when:
listeners.savedWafDataChangesListener.accept(
key,
'''{
"version": "2.2",
"metadata": {"rules_version": "1.99.0"},
"rules": [{
"id": "invalid-rule",
"name": "Invalid Rule",
"tags": {"type": "attack_attempt", "category": "attack_attempt"},
"conditions": [{
"operator": "invalid_operator",
"parameters": {"inputs": [{"address": "server.request.query"}]}
}]
}]
}'''.getBytes(),
NOOP)

then:
thrown RuntimeException
service.getCurrentRuleVersion() == '1.99.0'
1 * wafModule.setWafBuilder(_)
1 * wafModule.setRuleVersion('1.99.0')
}

void 'config keys are added and removed to the set when receiving ASM_DD payloads'() {
setup:
final key = new ParsedConfigKey('Test', '1234', 1, 'ASM_DD', 'ID')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ private WafMetricCollector() {
private static final BlockingQueue<WafMetric> rawMetricsQueue =
new ArrayBlockingQueue<>(RAW_QUEUE_SIZE);

private static final AtomicInteger wafInitCounter = new AtomicInteger();
private static final AtomicInteger wafUpdatesCounter = new AtomicInteger();

private static final int WAF_REQUEST_COMBINATIONS = 128; // 2^7
private final AtomicLongArray wafRequestCounter = new AtomicLongArray(WAF_REQUEST_COMBINATIONS);

Expand Down Expand Up @@ -80,14 +77,11 @@ private WafMetricCollector() {
public void wafInit(final String wafVersion, final String rulesVersion, final boolean success) {
WafMetricCollector.wafVersion = wafVersion;
WafMetricCollector.rulesVersion = rulesVersion;
rawMetricsQueue.offer(
new WafInitRawMetric(wafInitCounter.incrementAndGet(), wafVersion, rulesVersion, success));
rawMetricsQueue.offer(new WafInitRawMetric(1L, wafVersion, rulesVersion, success));
}

public void wafUpdates(final String rulesVersion, final boolean success) {
rawMetricsQueue.offer(
new WafUpdatesRawMetric(
wafUpdatesCounter.incrementAndGet(), wafVersion, rulesVersion, success));
rawMetricsQueue.offer(new WafUpdatesRawMetric(1L, wafVersion, rulesVersion, success));

// Flush request metrics to get the new version.
if (rulesVersion != null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class WafMetricCollectorTest extends DDSpecification {

def updateMetric2 = (WafMetricCollector.WafUpdatesRawMetric) metrics[2]
updateMetric2.type == 'count'
updateMetric2.value == 2
updateMetric2.value == 1
updateMetric2.namespace == 'appsec'
updateMetric2.metricName == 'waf.updates'
updateMetric2.tags.toSet() == ['waf_version:waf_ver1', 'event_rules_version:rules.3', 'success:false'].toSet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class WafMetricPeriodicActionSpecification extends DDSpecification {
1 * telemetryService.addMetric( { Metric metric ->
metric.namespace == 'appsec' &&
metric.metric == 'waf.updates' &&
metric.points[0][1] == 2 &&
metric.points[0][1] == 1 &&
metric.tags == ['waf_version:0.0.0', 'event_rules_version:rules_ver_3', 'success:true']
} )
0 * _._
Expand Down