From cb0e66d7b79003302c7d3b7f1dbbe7fe2b5ca468 Mon Sep 17 00:00:00 2001 From: kingthorin Date: Wed, 4 Dec 2024 13:02:48 -0500 Subject: [PATCH] automation: Preserve Rule ID zero - Set Jackson to always include the Rule ID. - CHANGELOG add fix note. - UnitTest to ensure rule ID is serialized as expected. Signed-off-by: kingthorin --- addOns/automation/CHANGELOG.md | 1 + .../addon/automation/AutomationPlan.java | 13 ++++++++----- .../automation/jobs/PolicyDefinition.java | 3 +++ .../jobs/PolicyDefinitionUnitTest.java | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/addOns/automation/CHANGELOG.md b/addOns/automation/CHANGELOG.md index 3df86fc7f40..0bc2d08f423 100644 --- a/addOns/automation/CHANGELOG.md +++ b/addOns/automation/CHANGELOG.md @@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Allow to choose one thread for the `activeScan` job through the GUI. - Active Scan jobs will once again use the default policy if neither a policy nor a policyDefinition has been set. - Bug in job alert tests related to alert matching. +- Active scan rule ID 0 (Directory Browsing) will be included in the plan (yaml) when saved (Issue 8746). ## [0.43.0] - 2024-10-07 ### Fixed diff --git a/addOns/automation/src/main/java/org/zaproxy/addon/automation/AutomationPlan.java b/addOns/automation/src/main/java/org/zaproxy/addon/automation/AutomationPlan.java index 76199b834f9..f6ea4d38725 100644 --- a/addOns/automation/src/main/java/org/zaproxy/addon/automation/AutomationPlan.java +++ b/addOns/automation/src/main/java/org/zaproxy/addon/automation/AutomationPlan.java @@ -306,17 +306,20 @@ public boolean save() throws FileNotFoundException, JsonProcessingException { data.addJob(job.getData()); } - FilterProvider filters = - new SimpleFilterProvider() - .addFilter( - DefaultPropertyFilter.FILTER_ID, new DefaultPropertyFilter()); - writer.println(YAML_OBJECT_MAPPER.writer(filters).writeValueAsString(data)); + writer.println(writeObjectAsString(data)); } this.changed = false; AutomationEventPublisher.publishEvent(AutomationEventPublisher.PLAN_SAVED, this, null); return true; } + public static String writeObjectAsString(Object obj) throws JsonProcessingException { + FilterProvider filters = + new SimpleFilterProvider() + .addFilter(DefaultPropertyFilter.FILTER_ID, new DefaultPropertyFilter()); + return YAML_OBJECT_MAPPER.writer(filters).writeValueAsString(obj); + } + public static class Data { private AutomationEnvironment.Data env; diff --git a/addOns/automation/src/main/java/org/zaproxy/addon/automation/jobs/PolicyDefinition.java b/addOns/automation/src/main/java/org/zaproxy/addon/automation/jobs/PolicyDefinition.java index 1911527656e..a396793ac2c 100644 --- a/addOns/automation/src/main/java/org/zaproxy/addon/automation/jobs/PolicyDefinition.java +++ b/addOns/automation/src/main/java/org/zaproxy/addon/automation/jobs/PolicyDefinition.java @@ -19,6 +19,7 @@ */ package org.zaproxy.addon.automation.jobs; +import com.fasterxml.jackson.annotation.JsonInclude; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -230,7 +231,9 @@ public void removeRule(Rule rule) { @Getter @Setter public static class Rule extends AutomationData { + @JsonInclude(JsonInclude.Include.ALWAYS) private int id; + private String name; private String threshold; private String strength; diff --git a/addOns/automation/src/test/java/org/zaproxy/addon/automation/jobs/PolicyDefinitionUnitTest.java b/addOns/automation/src/test/java/org/zaproxy/addon/automation/jobs/PolicyDefinitionUnitTest.java index fc939851689..085cfe4a93b 100644 --- a/addOns/automation/src/test/java/org/zaproxy/addon/automation/jobs/PolicyDefinitionUnitTest.java +++ b/addOns/automation/src/test/java/org/zaproxy/addon/automation/jobs/PolicyDefinitionUnitTest.java @@ -19,12 +19,14 @@ */ package org.zaproxy.addon.automation.jobs; +import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import com.fasterxml.jackson.core.JsonProcessingException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -49,6 +51,7 @@ import org.parosproxy.paros.core.scanner.PluginFactoryTestHelper; import org.parosproxy.paros.core.scanner.PluginTestHelper; import org.yaml.snakeyaml.Yaml; +import org.zaproxy.addon.automation.AutomationPlan; import org.zaproxy.addon.automation.AutomationProgress; import org.zaproxy.addon.automation.jobs.PolicyDefinition.Rule; import org.zaproxy.zap.extension.ascan.ScanPolicy; @@ -349,4 +352,20 @@ void shouldReturnNullPolicyIfDefinitionYamlIsEmptyOrNullObject(String defnYamlSt assertThat(progress.hasWarnings(), is(equalTo(false))); assertThat(policyDefinition.getScanPolicy("test", progress), is(nullValue())); } + + @ParameterizedTest + @ValueSource(ints = {0, 1, 50000, 99999}) + void shouldAlwaysIncludeIdWhenSerializingARule(int id) throws JsonProcessingException { + // Given + Rule rule = + new Rule( + id, + "Test Rule", + AttackStrength.MEDIUM.name(), + AlertThreshold.MEDIUM.name()); + // When + String ruleYaml = AutomationPlan.writeObjectAsString(rule); + // Then + assertThat(ruleYaml, containsString("id: " + id)); + } }