Skip to content

Commit

Permalink
Merge pull request #5984 from psiinon/auto/exitStatus
Browse files Browse the repository at this point in the history
Automation: exitStatus job
  • Loading branch information
thc202 authored Dec 6, 2024
2 parents c460f0d + 2f84296 commit 87d70a5
Show file tree
Hide file tree
Showing 18 changed files with 829 additions and 23 deletions.
1 change: 1 addition & 0 deletions addOns/automation/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Add job to configure the active scanner, `activeScan-config`.
- Allow to enable/disable jobs (Issue 5845).
- Method to allow the user to set the exit code via a script.
- Add exitStatus job (Issue #6928)

### Changed
- Maintenance changes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import org.zaproxy.addon.automation.jobs.ActiveScanJob;
import org.zaproxy.addon.automation.jobs.ActiveScanPolicyJob;
import org.zaproxy.addon.automation.jobs.DelayJob;
import org.zaproxy.addon.automation.jobs.ExitStatusJob;
import org.zaproxy.addon.automation.jobs.ParamsJob;
import org.zaproxy.addon.automation.jobs.RequestorJob;
import org.zaproxy.zap.ZAP;
Expand All @@ -84,6 +85,9 @@ public class ExtensionAutomation extends ExtensionAdaptor implements CommandLine
public static final String PREFIX = "automation";

public static final String RESOURCES_DIR = "/org/zaproxy/addon/automation/resources/";
public static final int OK_EXIT_VALUE = 0;
public static final int ERROR_EXIT_VALUE = 1;
public static final int WARN_EXIT_VALUE = 2;

protected static final String PLANS_RUN_STATS = "stats.auto.plans.run";
protected static final String TOTAL_JOBS_RUN_STATS = "stats.auto.jobs.run";
Expand Down Expand Up @@ -114,7 +118,7 @@ public class ExtensionAutomation extends ExtensionAdaptor implements CommandLine

private AutomationPanel automationPanel;

private Integer exitOverride;
private static Integer exitOverride;

public ExtensionAutomation() {
super(NAME);
Expand All @@ -132,6 +136,7 @@ public void init() {
registerAutomationJob(new org.zaproxy.addon.automation.jobs.AddOnJob());
registerAutomationJob(new RequestorJob());
registerAutomationJob(new DelayJob());
registerAutomationJob(new ExitStatusJob());
registerAutomationJob(
new ActiveScanConfigJob(
Control.getSingleton()
Expand Down Expand Up @@ -701,18 +706,18 @@ private void runPlanCommandLine(String source) {
if (exitOverride != null) {
setExitStatus(exitOverride, "set by user", false);
} else if (progress == null || progress.hasErrors()) {
setExitStatus(1, "plan errors", false);
setExitStatus(ERROR_EXIT_VALUE, "plan errors", false);
} else if (progress.hasWarnings()) {
setExitStatus(2, "plan warnings", false);
setExitStatus(WARN_EXIT_VALUE, "plan warnings", false);
}
}

public Integer getExitOverride() {
public static Integer getExitOverride() {
return exitOverride;
}

public void setExitOverride(Integer exitOverride) {
this.exitOverride = exitOverride;
public static void setExitOverride(Integer exitOverride) {
ExtensionAutomation.exitOverride = exitOverride;
}

private static URI createUri(String source) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2024 The ZAP Development Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.zaproxy.addon.automation.gui;

import org.apache.commons.lang3.ArrayUtils;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.core.scanner.Alert;
import org.parosproxy.paros.view.View;
import org.zaproxy.addon.automation.ExtensionAutomation;
import org.zaproxy.addon.automation.jobs.ExitStatusJob;
import org.zaproxy.addon.automation.jobs.JobUtils;
import org.zaproxy.zap.utils.DisplayUtils;
import org.zaproxy.zap.view.StandardFieldsDialog;

@SuppressWarnings("serial")
public class ExitStatusJobDialog extends StandardFieldsDialog {

private static final long serialVersionUID = 1L;

private static final String TITLE = "automation.dialog.exitstatus.title";
private static final String NAME_PARAM = "automation.dialog.all.name";
private static final String ERROR_LEVEL_PARAM = "automation.dialog.exitstatus.errorLevel";
private static final String WARN_LEVEL_PARAM = "automation.dialog.exitstatus.warnLevel";
private static final String OK_EXIT_VALUE_PARAM = "automation.dialog.exitstatus.okExitValue";
private static final String WARN_EXIT_VALUE_PARAM =
"automation.dialog.exitstatus.warnExitValue";
private static final String ERROR_EXIT_VALUE_PARAM =
"automation.dialog.exitstatus.errorExitValue";

private ExitStatusJob job;

private static String[] getRiskOptions() {
return ArrayUtils.add(Alert.MSG_RISK, "");
}

public ExitStatusJobDialog(ExitStatusJob job) {
super(View.getSingleton().getMainFrame(), TITLE, DisplayUtils.getScaledDimension(300, 270));
this.job = job;

this.addTextField(NAME_PARAM, this.job.getData().getName());
this.addComboField(
ERROR_LEVEL_PARAM,
getRiskOptions(),
this.job.getData().getParameters().getErrorLevel());
this.addComboField(
WARN_LEVEL_PARAM,
getRiskOptions(),
this.job.getData().getParameters().getWarnLevel());
this.addNumberField(
OK_EXIT_VALUE_PARAM,
0,
255,
getInt(
this.job.getParameters().getOkExitValue(),
ExtensionAutomation.OK_EXIT_VALUE));
this.addNumberField(
WARN_EXIT_VALUE_PARAM,
0,
255,
getInt(
this.job.getParameters().getWarnExitValue(),
ExtensionAutomation.WARN_EXIT_VALUE));
this.addNumberField(
ERROR_EXIT_VALUE_PARAM,
0,
255,
getInt(
this.job.getParameters().getErrorExitValue(),
ExtensionAutomation.ERROR_EXIT_VALUE));

this.addPadding();
}

private int getInt(Integer integer, int defaultValue) {
if (integer == null) {
return defaultValue;
}
return integer.intValue();
}

private Integer getInteger(int i, int defaultValue) {
if (i == defaultValue) {
return null;
}
return Integer.valueOf(i);
}

@Override
public void save() {
this.job.getData().setName(this.getStringValue(NAME_PARAM));
this.job.getParameters().setErrorLevel(this.getStringValue(ERROR_LEVEL_PARAM));
this.job.getParameters().setWarnLevel(this.getStringValue(WARN_LEVEL_PARAM));
this.job
.getParameters()
.setOkExitValue(
getInteger(
this.getIntValue(OK_EXIT_VALUE_PARAM),
ExtensionAutomation.OK_EXIT_VALUE));
this.job
.getParameters()
.setWarnExitValue(
getInteger(
this.getIntValue(WARN_EXIT_VALUE_PARAM),
ExtensionAutomation.WARN_EXIT_VALUE));
this.job
.getParameters()
.setErrorExitValue(
getInteger(
this.getIntValue(ERROR_EXIT_VALUE_PARAM),
ExtensionAutomation.ERROR_EXIT_VALUE));
this.job.resetAndSetChanged();
}

@Override
public String validateFields() {
Integer errorRisk = JobUtils.parseAlertRisk(this.getStringValue(ERROR_LEVEL_PARAM));
Integer warnRisk = JobUtils.parseAlertRisk(this.getStringValue(WARN_LEVEL_PARAM));
if (warnRisk != null && errorRisk != null && warnRisk > errorRisk) {
return Constant.messages.getString(
"automation.exitstatus.error.badlevels",
this.getStringValue(ERROR_LEVEL_PARAM),
this.getStringValue(WARN_LEVEL_PARAM));
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.zaproxy.addon.automation.AutomationPlan;
import org.zaproxy.addon.automation.ExtensionAutomation;
import org.zaproxy.addon.automation.jobs.ActiveScanJob;
import org.zaproxy.addon.automation.jobs.ExitStatusJob;
import org.zaproxy.zap.utils.DisplayUtils;
import org.zaproxy.zap.view.StandardFieldsDialog;

Expand All @@ -64,7 +65,12 @@ public class NewPlanDialog extends StandardFieldsDialog {
private static final String REPORT_JOB_NAME = "report";

private static final String[] BASELINE_PROFILE = {
"passiveScan-config", "spider", "spiderAjax", "passiveScan-wait", REPORT_JOB_NAME
"passiveScan-config",
"spider",
"spiderAjax",
"passiveScan-wait",
REPORT_JOB_NAME,
ExitStatusJob.JOB_NAME
};
private static final String[] IMPORT_PROFILE = {
"passiveScan-config",
Expand All @@ -73,24 +79,41 @@ public class NewPlanDialog extends StandardFieldsDialog {
"spiderAjax",
"passiveScan-wait",
ActiveScanJob.JOB_NAME,
REPORT_JOB_NAME
REPORT_JOB_NAME,
ExitStatusJob.JOB_NAME
};
private static final String[] OPENAPI_PROFILE = {
"passiveScan-config", "openapi", "passiveScan-wait", ActiveScanJob.JOB_NAME, REPORT_JOB_NAME
"passiveScan-config",
"openapi",
"passiveScan-wait",
ActiveScanJob.JOB_NAME,
REPORT_JOB_NAME,
ExitStatusJob.JOB_NAME
};
private static final String[] GRAPHQL_PROFILE = {
"passiveScan-config", "graphql", "passiveScan-wait", ActiveScanJob.JOB_NAME, REPORT_JOB_NAME
"passiveScan-config",
"graphql",
"passiveScan-wait",
ActiveScanJob.JOB_NAME,
REPORT_JOB_NAME,
ExitStatusJob.JOB_NAME
};
private static final String[] SOAP_PROFILE = {
"passiveScan-config", "soap", "passiveScan-wait", ActiveScanJob.JOB_NAME, REPORT_JOB_NAME
"passiveScan-config",
"soap",
"passiveScan-wait",
ActiveScanJob.JOB_NAME,
REPORT_JOB_NAME,
ExitStatusJob.JOB_NAME
};
private static final String[] FULL_SCAN_PROFILE = {
"passiveScan-config",
"spider",
"spiderAjax",
"passiveScan-wait",
ActiveScanJob.JOB_NAME,
REPORT_JOB_NAME
REPORT_JOB_NAME,
ExitStatusJob.JOB_NAME
};

private JList<String> contextList;
Expand Down
Loading

0 comments on commit 87d70a5

Please sign in to comment.