Skip to content
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
3 changes: 3 additions & 0 deletions docker/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changelog
All notable changes to the docker containers will be documented in this file.

### 2025-11-03
- Set statsId and readonly for scan policies.

### 2025-10-31
- Added config options for recording which packaged scan is being run.

Expand Down
2 changes: 2 additions & 0 deletions docker/policies/API-Minimal.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>API Minimal</policy>
<statsId>dock-api-min<statsId>
<readonly>true</readonly>
<scanner>
<level>OFF</level>
<strength>MEDIUM</strength>
Expand Down
2 changes: 2 additions & 0 deletions docker/policies/Default Policy.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>Default Policy</policy>
<statsId>dock-default<statsId>
<readonly>true</readonly>
<scanner>
<level>MEDIUM</level>
<strength>MEDIUM</strength>
Expand Down
2 changes: 2 additions & 0 deletions docker/policies/St-High-Th-High.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>St-High-Th-High</policy>
<statsId>dock-high-high<statsId>
<readonly>true</readonly>
<scanner>
<level>HIGH</level>
<strength>HIGH</strength>
Expand Down
2 changes: 2 additions & 0 deletions docker/policies/St-High-Th-Low.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>St-High-Th-Low</policy>
<statsId>dock-high-low<statsId>
<readonly>true</readonly>
<scanner>
<level>LOW</level>
<strength>HIGH</strength>
Expand Down
2 changes: 2 additions & 0 deletions docker/policies/St-High-Th-Med.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>St-High-Th-Med</policy>
<statsId>dock-high-med<statsId>
<readonly>true</readonly>
<scanner>
<level>MEDIUM</level>
<strength>HIGH</strength>
Expand Down
2 changes: 2 additions & 0 deletions docker/policies/St-Ins-Th-High.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>St-Ins-Th-High</policy>
<statsId>dock-ins-high<statsId>
<readonly>true</readonly>
<scanner>
<level>HIGH</level>
<strength>INSANE</strength>
Expand Down
2 changes: 2 additions & 0 deletions docker/policies/St-Ins-Th-Low.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>St-Ins-Th-Low</policy>
<statsId>dock-ins-low<statsId>
<readonly>true</readonly>
<scanner>
<level>LOW</level>
<strength>INSANE</strength>
Expand Down
2 changes: 2 additions & 0 deletions docker/policies/St-Ins-Th-Med.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>St-Ins-Th-Med</policy>
<statsId>dock-ins-med<statsId>
<readonly>true</readonly>
<scanner>
<level>MEDIUM</level>
<strength>INSANE</strength>
Expand Down
4 changes: 3 additions & 1 deletion docker/policies/St-Low-Th-High.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>St-Low-Th-Med</policy>
<policy>St-Low-Th-High</policy>
<statsId>dock-low-high<statsId>
<readonly>true</readonly>
<scanner>
<level>HIGH</level>
<strength>LOW</strength>
Expand Down
2 changes: 2 additions & 0 deletions docker/policies/St-Low-Th-Low.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>St-Low-Th-Low</policy>
<statsId>dock-low-low<statsId>
<readonly>true</readonly>
<scanner>
<level>LOW</level>
<strength>LOW</strength>
Expand Down
2 changes: 2 additions & 0 deletions docker/policies/St-Low-Th-Med.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>St-Low-Th-Med</policy>
<statsId>dock-low-med<statsId>
<readonly>true</readonly>
<scanner>
<level>MEDIUM</level>
<strength>LOW</strength>
Expand Down
2 changes: 2 additions & 0 deletions docker/policies/St-Med-Th-High.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>St-Med-Th-High</policy>
<statsId>dock-med-high<statsId>
<readonly>true</readonly>
<scanner>
<level>HIGH</level>
<strength>MEDIUM</strength>
Expand Down
2 changes: 2 additions & 0 deletions docker/policies/St-Med-Th-Low.policy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<policy>St-Med-Th-Low</policy>
<statsId>dock-med-low<statsId>
<readonly>true</readonly>
<scanner>
<level>LOW</level>
<strength>MEDIUM</strength>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
// ZAP: 2023/01/10 Tidy up logger.
// ZAP: 2023/05/30 Stop HostProcess to stop the Analyser.
// ZAP: 2024/11/20 Include ID of the scan in relevant log messages.
// ZAP: 2025/11/03 Record stats for built-in policies.
package org.parosproxy.paros.core.scanner;

import java.security.InvalidParameterException;
Expand Down Expand Up @@ -213,6 +214,10 @@ public void start(Target target) {
if (this.user != null) {
Stats.incCounter(ASCAN_SCAN_STARTED_USER_STATS);
}
Stats.incCounter(
"stats.ascan.started.policy." + this.scanPolicy.getStatsId() != null
? this.scanPolicy.getStatsId()
: "user");
}

public void stop() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,9 @@ public void validateParam(Object obj) throws Exception {
throw new Exception(Constant.messages.getString("ascan.policy.warn.exists"));
}
}
if (policy.isReadOnly() && newName.equals(currentName)) {
throw new Exception(Constant.messages.getString("ascan.policy.warn.readonly"));
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ public PolicyAllCategoryPanel getPolicyAllCategoryPanel() {
@Override
public void saveParam() throws Exception {
super.saveParam();

extension.getPolicyManager().savePolicy(policy, currentName);
extension.getPolicyManager().savePolicy(policy, policy.isReadOnly() ? null : currentName);
pmd.policyNamesChanged();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,7 @@ public void savePolicy(ScanPolicy policy, String previousName) throws Configurat
File file = new File(Constant.getPoliciesDir(), policy.getName() + POLICY_EXTENSION);

ZapXmlConfiguration conf = new ZapXmlConfiguration();
conf.setProperty("policy", policy.getName());
conf.setProperty("scanner.level", policy.getDefaultThreshold().name());
conf.setProperty("scanner.strength", policy.getDefaultStrength().name());

policy.getPluginFactory().saveTo(conf);
policy.saveTo(conf);

if (previousName != null && !previousName.equals(policy.getName())) {
File oldFile = new File(Constant.getPoliciesDir(), previousName + POLICY_EXTENSION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,19 @@ public void actionPerformed(ActionEvent e) {
.getValueAt(
getParamsTable().getSelectedRow(), 0);
if (name != null) {
if (View.getSingleton()
ScanPolicy policy = null;
try {
policy = extension.getPolicyManager().getPolicy(name);
} catch (ConfigurationException e1) {
// Ignore
}
if (policy != null && policy.isReadOnly()) {
View.getSingleton()
.showWarningDialog(
PolicyManagerDialog.this,
Constant.messages.getString(
"ascan.policymgr.warn.builtin"));
} else if (View.getSingleton()
.showConfirmDialog(
PolicyManagerDialog.this,
Constant.messages.getString(
Expand Down
44 changes: 44 additions & 0 deletions zap/src/main/java/org/zaproxy/zap/extension/ascan/ScanPolicy.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
*/
package org.zaproxy.zap.extension.ascan;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.FileConfiguration;
import org.apache.commons.lang3.EnumUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.core.scanner.Plugin;
import org.parosproxy.paros.core.scanner.Plugin.AlertThreshold;
import org.parosproxy.paros.core.scanner.Plugin.AttackStrength;
Expand All @@ -35,6 +37,8 @@ public class ScanPolicy {
private static final Logger LOGGER = LogManager.getLogger(ScanPolicy.class);

private String name;
private String statsId;
private boolean readOnly;
private PluginFactory pluginFactory = new PluginFactory();
private AlertThreshold defaultThreshold;
private AttackStrength defaultStrength;
Expand All @@ -51,6 +55,12 @@ public ScanPolicy() {
public ScanPolicy(ZapXmlConfiguration conf) throws ConfigurationException {
this.conf = conf;
name = conf.getString("policy", "");
statsId = conf.getString("statsId", null);
readOnly = conf.getBoolean("readonly", false);
if (statsId == null
&& name.equals(Constant.messages.getString("ascan.policymgr.default.name"))) {
statsId = "default";
}
pluginFactory.loadAllPlugin(conf);

setDefaultThreshold(getAlertThresholdFromConfig());
Expand All @@ -73,6 +83,20 @@ public void cloneInto(ScanPolicy policy) {
policy.pluginFactory.loadFrom(this.pluginFactory);
policy.defaultStrength = this.getDefaultStrength();
policy.defaultThreshold = this.getDefaultThreshold();
policy.statsId = this.statsId;
policy.readOnly = this.readOnly;
}

/**
* Saves the policy to the specified file. Will not maintain the readonly or statsId properties.
*
* @since 2.17.0
*/
public void saveTo(Configuration conf) throws ConfigurationException {
conf.setProperty("policy", getName());
conf.setProperty("scanner.level", getDefaultThreshold().name());
conf.setProperty("scanner.strength", getDefaultStrength().name());
getPluginFactory().saveTo(conf);
}

public String getName() {
Expand Down Expand Up @@ -146,4 +170,24 @@ private AttackStrength getAttackStrengthFromConfig() {
}
return AttackStrength.valueOf(attackStrength);
}

/**
* Returns a string to be used when recording stats. Only expected to be supplied for 'built in'
* policies.
*
* @since 2.17.0
*/
public String getStatsId() {
return statsId;
}

/**
* Returns true if the policy is 'built in' (according to the configs) - the UI should ensure it
* is not changed.
*
* @since 2.17.0
*/
public boolean isReadOnly() {
return readOnly;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,9 @@ ascan.policy.table.threshold = Threshold
ascan.policy.title = Scan Policy
ascan.policy.unfulfilled.dependencies = The scan rule cannot be enabled because of unfulfilled dependencies.
ascan.policy.warn.badname = The Policy name must not contain any of the characters: {0}
ascan.policy.warn.exists = A policy with this name already exists
ascan.policy.warn.noname = You must supply a policy name
ascan.policy.warn.exists = A policy with this name already exists.
ascan.policy.warn.noname = You must supply a policy name.
ascan.policy.warn.readonly = You cannot change a built-in policy unless you also change the name.
ascan.policymgr.button.add = Add
ascan.policymgr.button.export = Export
ascan.policymgr.button.import = Import
Expand All @@ -563,6 +564,7 @@ ascan.policymgr.button.remove = Remove
ascan.policymgr.default.name = Default Policy
ascan.policymgr.table.policy = Policy Name
ascan.policymgr.title = Scan Policy Manager
ascan.policymgr.warn.builtin = You cannot delete built-in policies.
ascan.policymgr.warn.delete = Are you sure you want to delete this Policy?
ascan.progress.chart.1xx = 1xx
ascan.progress.chart.2xx = 2xx
Expand Down
Loading