Skip to content

Commit 82c4568

Browse files
committed
automation: Allow selecting rules via Alert Tags
Signed-off-by: ricekot <[email protected]>
1 parent bdbcd47 commit 82c4568

File tree

18 files changed

+812
-120
lines changed

18 files changed

+812
-120
lines changed

addOns/automation/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
88
- Support for step delay in Browser Based Authentication.
99
- Support for min wait for in Client Script Authentication.
1010
- Support for url in activeScan job.
11+
- Allow selecting rules in policy definitions using alert tags.
1112

1213
### Changed
1314
- Refer to output panel for errors.

addOns/automation/src/main/java/org/zaproxy/addon/automation/gui/ActiveScanJobDialog.java

Lines changed: 77 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222
import java.awt.Component;
2323
import java.util.ArrayList;
2424
import java.util.List;
25+
import java.util.Locale;
2526
import javax.swing.JButton;
2627
import javax.swing.JTextField;
2728
import org.parosproxy.paros.core.scanner.Plugin.AlertThreshold;
2829
import org.parosproxy.paros.core.scanner.Plugin.AttackStrength;
2930
import org.zaproxy.addon.automation.jobs.ActiveScanJob;
3031
import org.zaproxy.addon.automation.jobs.ActiveScanJob.Parameters;
3132
import org.zaproxy.addon.automation.jobs.JobUtils;
33+
import org.zaproxy.addon.automation.jobs.PolicyDefinition;
3234
import org.zaproxy.addon.automation.jobs.PolicyDefinition.Rule;
3335
import org.zaproxy.zap.utils.DisplayUtils;
3436

@@ -41,6 +43,7 @@ public class ActiveScanJobDialog extends ActiveScanPolicyDialog {
4143
"automation.dialog.tab.params",
4244
"automation.dialog.ascan.tab.policydefaults",
4345
"automation.dialog.ascan.tab.policyrules",
46+
"automation.dialog.ascan.tab.policyalerttags",
4447
"automation.dialog.ascan.tab.adv"
4548
};
4649

@@ -68,48 +71,51 @@ public class ActiveScanJobDialog extends ActiveScanPolicyDialog {
6871
public ActiveScanJobDialog(ActiveScanJob job) {
6972
super(TITLE, DisplayUtils.getScaledDimension(500, 400), TAB_LABELS);
7073
this.job = job;
74+
int tabIndex = -1;
7175

72-
this.addTextField(0, NAME_PARAM, this.job.getData().getName());
76+
this.addTextField(++tabIndex, NAME_PARAM, this.job.getData().getName());
7377
List<String> contextNames = this.job.getEnv().getContextNames();
7478
// Add blank option
7579
contextNames.add(0, "");
76-
this.addComboField(0, CONTEXT_PARAM, contextNames, this.job.getParameters().getContext());
80+
this.addComboField(
81+
tabIndex, CONTEXT_PARAM, contextNames, this.job.getParameters().getContext());
7782

7883
List<String> users = job.getEnv().getAllUserNames();
7984
// Add blank option
8085
users.add(0, "");
81-
this.addComboField(0, USER_PARAM, users, this.job.getData().getParameters().getUser());
86+
this.addComboField(
87+
tabIndex, USER_PARAM, users, this.job.getData().getParameters().getUser());
8288

8389
// Cannot select the node as it might not be present in the Sites tree
84-
this.addNodeSelectField(0, URL_PARAM, null, true, false);
90+
this.addNodeSelectField(tabIndex, URL_PARAM, null, true, false);
8591
Component urlField = this.getField(URL_PARAM);
8692
if (urlField instanceof JTextField) {
8793
((JTextField) urlField).setText(this.job.getParameters().getUrl());
8894
}
8995

90-
this.addTextField(0, POLICY_PARAM, this.job.getParameters().getPolicy());
96+
this.addTextField(tabIndex, POLICY_PARAM, this.job.getParameters().getPolicy());
9197
this.addNumberField(
92-
0,
98+
tabIndex,
9399
MAX_RULE_DURATION_PARAM,
94100
0,
95101
Integer.MAX_VALUE,
96102
JobUtils.unBox(job.getParameters().getMaxRuleDurationInMins()));
97103
this.addNumberField(
98-
0,
104+
tabIndex,
99105
MAX_SCAN_DURATION_PARAM,
100106
0,
101107
Integer.MAX_VALUE,
102108
JobUtils.unBox(job.getParameters().getMaxScanDurationInMins()));
103109
addNumberField(
104-
0,
110+
tabIndex,
105111
MAX_ALERTS_PER_RULE_PARAM,
106112
0,
107113
Integer.MAX_VALUE,
108114
JobUtils.unBox(job.getParameters().getMaxAlertsPerRule()));
109-
this.addCheckBoxField(0, FIELD_ADVANCED, advOptionsSet());
115+
this.addCheckBoxField(tabIndex, FIELD_ADVANCED, advOptionsSet());
110116
this.addFieldListener(FIELD_ADVANCED, e -> setAdvancedTabs(getBoolValue(FIELD_ADVANCED)));
111117

112-
this.addPadding(0);
118+
this.addPadding(tabIndex);
113119

114120
String thresholdName =
115121
JobUtils.thresholdToI18n(job.getData().getPolicyDefinition().getDefaultThreshold());
@@ -131,7 +137,7 @@ public ActiveScanJobDialog(ActiveScanJob job) {
131137
allthresholds.add(JobUtils.thresholdToI18n(at.name()));
132138
}
133139

134-
this.addComboField(1, DEFAULT_THRESHOLD_PARAM, allthresholds, thresholdName);
140+
this.addComboField(++tabIndex, DEFAULT_THRESHOLD_PARAM, allthresholds, thresholdName);
135141

136142
List<String> allstrengths = new ArrayList<>();
137143

@@ -142,45 +148,73 @@ public ActiveScanJobDialog(ActiveScanJob job) {
142148
allstrengths.add(JobUtils.strengthToI18n(at.name()));
143149
}
144150

145-
this.addComboField(1, DEFAULT_STRENGTH_PARAM, allstrengths, strengthName);
151+
this.addComboField(tabIndex, DEFAULT_STRENGTH_PARAM, allstrengths, strengthName);
146152

147-
this.addPadding(1);
153+
this.addPadding(tabIndex);
148154

149155
List<JButton> buttons = new ArrayList<>();
150156
buttons.add(getAddButton());
151157
buttons.add(getModifyButton());
152158
buttons.add(getRemoveButton());
153159

154-
this.addTableField(2, getRulesTable(), buttons);
160+
this.addTableField(++tabIndex, getRulesTable(), buttons);
161+
162+
String tagRuleThresholdName =
163+
JobUtils.thresholdToI18n(
164+
job.getData()
165+
.getPolicyDefinition()
166+
.getAlertTagRule()
167+
.getThreshold()
168+
.name());
169+
if (tagRuleThresholdName.isEmpty()) {
170+
tagRuleThresholdName = JobUtils.thresholdToI18n(AlertThreshold.MEDIUM.name());
171+
}
172+
String tagRuleStrengthName =
173+
JobUtils.strengthToI18n(
174+
job.getData().getPolicyDefinition().getAlertTagRule().getStrength().name());
175+
if (tagRuleStrengthName.isEmpty()) {
176+
tagRuleStrengthName = JobUtils.strengthToI18n(AttackStrength.MEDIUM.name());
177+
}
178+
this.addComboField(
179+
++tabIndex, TAG_RULE_THRESHOLD_PARAM, allthresholds, tagRuleThresholdName);
180+
this.addComboField(tabIndex, TAG_RULE_STRENGTH_PARAM, allstrengths, tagRuleStrengthName);
181+
this.addTableField(
182+
tabIndex,
183+
getIncludedAlertTagsTable(),
184+
List.of(getAddIncludedAlertTagButton(), getRemoveIncludedAlertTagButton()));
185+
this.addTableField(
186+
tabIndex,
187+
getExcludedAlertTagsTable(),
188+
List.of(getAddExcludedAlertTagButton(), getRemoveExcludedAlertTagButton()));
155189

156190
this.addNumberField(
157-
3,
191+
++tabIndex,
158192
DELAY_IN_MS_PARAM,
159193
0,
160194
Integer.MAX_VALUE,
161195
JobUtils.unBox(job.getParameters().getDelayInMs()));
162196
this.addNumberField(
163-
3,
197+
tabIndex,
164198
THREADS_PER_HOST_PARAM,
165199
1,
166200
Integer.MAX_VALUE,
167201
JobUtils.unBox(job.getParameters().getThreadPerHost()));
168202
this.addCheckBoxField(
169-
3, ADD_QUERY_PARAM, JobUtils.unBox(job.getParameters().getAddQueryParam()));
203+
tabIndex, ADD_QUERY_PARAM, JobUtils.unBox(job.getParameters().getAddQueryParam()));
170204
this.addCheckBoxField(
171-
3,
205+
tabIndex,
172206
HANDLE_ANTI_CSRF_PARAM,
173207
JobUtils.unBox(job.getParameters().getHandleAntiCSRFTokens()));
174208
this.addCheckBoxField(
175-
3,
209+
tabIndex,
176210
INJECT_PLUGIN_ID_PARAM,
177211
JobUtils.unBox(job.getParameters().getInjectPluginIdInHeader()));
178212
this.addCheckBoxField(
179-
3,
213+
tabIndex,
180214
SCAN_HEADERS_PARAM,
181215
JobUtils.unBox(job.getParameters().getScanHeadersAllRequests()));
182216

183-
this.addPadding(3);
217+
this.addPadding(tabIndex);
184218

185219
setAdvancedTabs(getBoolValue(FIELD_ADVANCED));
186220
}
@@ -248,6 +282,23 @@ public void save() {
248282
this.job.getParameters().setScanHeadersAllRequests(null);
249283
}
250284
this.job.getData().getPolicyDefinition().setRules(this.getRulesModel().getRules());
285+
this.job
286+
.getData()
287+
.getPolicyDefinition()
288+
.setAlertTagRule(
289+
new PolicyDefinition.AlertTagRuleConfig(
290+
this.getIncludedTagsTableModel().getAlertTagPatterns(),
291+
this.getExcludedTagsTableModel().getAlertTagPatterns(),
292+
AttackStrength.valueOf(
293+
JobUtils.i18nToStrength(
294+
this.getStringValue(
295+
TAG_RULE_STRENGTH_PARAM))
296+
.toUpperCase(Locale.ROOT)),
297+
AlertThreshold.valueOf(
298+
JobUtils.i18nToThreshold(
299+
this.getStringValue(
300+
TAG_RULE_THRESHOLD_PARAM))
301+
.toUpperCase(Locale.ROOT))));
251302
this.job.resetAndSetChanged();
252303
}
253304

@@ -261,4 +312,9 @@ public String validateFields() {
261312
protected List<Rule> getRules() {
262313
return job.getData().getPolicyDefinition().getRules();
263314
}
315+
316+
@Override
317+
protected PolicyDefinition.AlertTagRuleConfig getAlertTagRule() {
318+
return job.getData().getPolicyDefinition().getAlertTagRule();
319+
}
264320
}

addOns/automation/src/main/java/org/zaproxy/addon/automation/gui/ActiveScanPolicyDialog.java

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,28 @@
2222
import java.awt.Dimension;
2323
import java.awt.event.MouseAdapter;
2424
import java.awt.event.MouseEvent;
25+
import java.util.ArrayList;
2526
import java.util.List;
27+
import java.util.function.Supplier;
28+
import java.util.regex.Pattern;
2629
import javax.swing.JButton;
2730
import javax.swing.JOptionPane;
2831
import javax.swing.JTable;
32+
import lombok.AccessLevel;
33+
import lombok.Getter;
2934
import org.apache.commons.configuration.ConfigurationException;
3035
import org.apache.logging.log4j.LogManager;
3136
import org.apache.logging.log4j.Logger;
3237
import org.parosproxy.paros.Constant;
3338
import org.parosproxy.paros.view.View;
39+
import org.zaproxy.addon.automation.jobs.PolicyDefinition.AlertTagRuleConfig;
3440
import org.zaproxy.addon.automation.jobs.PolicyDefinition.Rule;
3541
import org.zaproxy.zap.utils.DisplayUtils;
3642
import org.zaproxy.zap.view.StandardFieldsDialog;
3743

3844
@SuppressWarnings("serial")
3945
/** An abstract class that provides the methods needed to add active scan policy management tabs. */
46+
@Getter(value = AccessLevel.PROTECTED)
4047
public abstract class ActiveScanPolicyDialog extends StandardFieldsDialog {
4148

4249
private static final long serialVersionUID = 1L;
@@ -47,6 +54,10 @@ public abstract class ActiveScanPolicyDialog extends StandardFieldsDialog {
4754
"automation.dialog.ascan.defaultthreshold";
4855
protected static final String DEFAULT_STRENGTH_PARAM =
4956
"automation.dialog.ascan.defaultstrength";
57+
protected static final String TAG_RULE_THRESHOLD_PARAM =
58+
"automation.dialog.ascanpolicyalerttags.threshold";
59+
protected static final String TAG_RULE_STRENGTH_PARAM =
60+
"automation.dialog.ascanpolicyalerttags.strength";
5061

5162
private JButton addButton = null;
5263
private JButton modifyButton = null;
@@ -55,6 +66,26 @@ public abstract class ActiveScanPolicyDialog extends StandardFieldsDialog {
5566
private JTable rulesTable = null;
5667
private AscanRulesTableModel rulesModel = null;
5768

69+
private JTable includedTagsTable;
70+
private final AlertTagsTableModel includedTagsTableModel =
71+
new AlertTagsTableModel(
72+
Constant.messages.getString(
73+
"automation.dialog.ascanpolicyalerttags.includedtagpatterns"));
74+
private final JButton addIncludedAlertTagButton =
75+
createAddAlertTagButton(includedTagsTableModel);
76+
private final JButton removeIncludedAlertTagButton =
77+
createRemoveAlertTagButton(includedTagsTableModel, this::getIncludedAlertTagsTable);
78+
79+
private final AlertTagsTableModel excludedTagsTableModel =
80+
new AlertTagsTableModel(
81+
Constant.messages.getString(
82+
"automation.dialog.ascanpolicyalerttags.excludedtagpatterns"));
83+
private JTable excludedTagsTable;
84+
private final JButton addExcludedAlertTagButton =
85+
createAddAlertTagButton(excludedTagsTableModel);
86+
private final JButton removeExcludedAlertTagButton =
87+
createRemoveAlertTagButton(excludedTagsTableModel, this::getExcludedAlertTagsTable);
88+
5889
public ActiveScanPolicyDialog(String title, Dimension dimension, String[] tabLabels) {
5990
super(View.getSingleton().getMainFrame(), title, dimension, tabLabels);
6091
}
@@ -185,4 +216,61 @@ protected AscanRulesTableModel getRulesModel() {
185216
}
186217

187218
protected abstract List<Rule> getRules();
219+
220+
protected JTable getIncludedAlertTagsTable() {
221+
if (includedTagsTable == null) {
222+
includedTagsTable =
223+
createAlertTagsTable(
224+
getIncludedTagsTableModel(),
225+
getAlertTagRule().getIncludePatterns(),
226+
getRemoveIncludedAlertTagButton());
227+
}
228+
return includedTagsTable;
229+
}
230+
231+
protected JTable getExcludedAlertTagsTable() {
232+
if (excludedTagsTable == null) {
233+
excludedTagsTable =
234+
createAlertTagsTable(
235+
getExcludedTagsTableModel(),
236+
getAlertTagRule().getExcludePatterns(),
237+
getRemoveExcludedAlertTagButton());
238+
}
239+
return excludedTagsTable;
240+
}
241+
242+
protected AlertTagRuleConfig getAlertTagRule() {
243+
return null;
244+
}
245+
246+
private JButton createAddAlertTagButton(AlertTagsTableModel model) {
247+
var button = new JButton(Constant.messages.getString("automation.dialog.button.add"));
248+
button.addActionListener(
249+
e -> {
250+
var dialog = new AddAlertTagDialog(this, model, -1);
251+
dialog.setVisible(true);
252+
});
253+
return button;
254+
}
255+
256+
private JButton createRemoveAlertTagButton(
257+
AlertTagsTableModel model, Supplier<JTable> tableSupplier) {
258+
var button = new JButton(Constant.messages.getString("automation.dialog.button.remove"));
259+
button.setEnabled(false);
260+
button.addActionListener(e -> model.remove(tableSupplier.get().getSelectedRow()));
261+
return button;
262+
}
263+
264+
private JTable createAlertTagsTable(
265+
AlertTagsTableModel model, List<Pattern> patterns, JButton removeButton) {
266+
JTable table = new JTable(model);
267+
model.setAlertTagPatterns(new ArrayList<>(patterns));
268+
table.getSelectionModel()
269+
.addListSelectionListener(
270+
e -> {
271+
boolean singleRowSelected = table.getSelectedRowCount() == 1;
272+
removeButton.setEnabled(singleRowSelected);
273+
});
274+
return table;
275+
}
188276
}

0 commit comments

Comments
 (0)