Skip to content
Open
Show file tree
Hide file tree
Changes from 11 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
2 changes: 2 additions & 0 deletions addOns/quickstart/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ All notable changes to this add-on will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## Unreleased
### Added
- Add Scan Policy option to the Automated Scan panel.


## [55] - 2026-03-09
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import org.parosproxy.paros.model.SiteNode;
import org.parosproxy.paros.view.View;
import org.zaproxy.zap.extension.alert.ExtensionAlert;
import org.zaproxy.zap.extension.ascan.ExtensionActiveScan;
import org.zaproxy.zap.extension.ascan.PolicyManager;
import org.zaproxy.zap.extension.search.SearchPanel;
import org.zaproxy.zap.utils.DisplayUtils;
import org.zaproxy.zap.view.LayoutHelper;
Expand All @@ -48,10 +50,12 @@ public class AttackPanel extends QuickStartSubPanel {
private static final long serialVersionUID = 1L;

private static final String DEFAULT_VALUE_URL_FIELD = "http://";
private static final String DEFAULT_SCAN_POLICY = "Dev Standard";

private ImageIcon icon;
private JButton attackButton;
private JButton stopButton;
private JComboBox<String> policyField;
private JComboBox<String> urlField;
private DefaultComboBoxModel<String> urlModel;
private JButton selectButton;
Expand Down Expand Up @@ -149,6 +153,11 @@ public JPanel getContentPanel() {
urlSelectPanel.add(this.getUrlField(), LayoutHelper.getGBC(0, 0, 1, 0.5D));
urlSelectPanel.add(selectButton, LayoutHelper.getGBC(1, 0, 1, 0.0D));
contentPanel.add(urlSelectPanel, LayoutHelper.getGBC(2, formPanelY, 3, 0.25D));
contentPanel.add(
new JLabel(Constant.messages.getString("quickstart.label.policy")),
LayoutHelper.getGBC(
1, ++formPanelY, 1, 0.0D, DisplayUtils.getScaledInsets(5, 5, 5, 5)));
contentPanel.add(getPolicyField(), LayoutHelper.getGBC(2, formPanelY, 1, 0.25D));

traditionalSpiderY = ++formPanelY;
plugableSpiderY = ++formPanelY;
Expand All @@ -173,6 +182,39 @@ public JPanel getContentPanel() {
return contentPanel;
}

private JComboBox<String> getPolicyField() {
if (policyField == null) {
policyField = new JComboBox<>();
ExtensionActiveScan extAscan =
Control.getSingleton()
.getExtensionLoader()
.getExtension(ExtensionActiveScan.class);
if (extAscan != null) {
String savedPolicy =
getExtensionQuickStart().getQuickStartParam().getScanPolicyName();
String defaultPolicy = null;
extAscan.getPolicyManager().getAllPolicyNames().forEach(policyField::addItem);
if (PolicyManager.policyExists(DEFAULT_SCAN_POLICY)) {
defaultPolicy = DEFAULT_SCAN_POLICY;
}
if (savedPolicy != null && PolicyManager.policyExists(savedPolicy)) {
policyField.setSelectedItem(savedPolicy);
} else if (defaultPolicy != null) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use policyExists(…) again.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Preferable to inline in the if than declare variables upfront that might not be even used.

policyField.setSelectedItem(defaultPolicy);
}
}
}
return policyField;
}

public String getSelectedPolicy() {
if (policyField == null) {
return null;
}
Object selected = policyField.getSelectedItem();
return selected != null ? selected.toString() : null;
Comment thread
kingthorin marked this conversation as resolved.
}

private JLabel getProgressLabel() {
if (progressLabel == null) {
progressLabel =
Expand Down Expand Up @@ -402,6 +444,7 @@ boolean attackUrl() {
return false;
}
this.getExtensionQuickStart().getQuickStartParam().addRecentUrl(urlStr);
this.getExtensionQuickStart().getQuickStartParam().setScanPolicyName(getSelectedPolicy());
getAttackButton().setEnabled(false);
getStopButton().setEnabled(true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.parosproxy.paros.model.SiteNode;
import org.zaproxy.zap.extension.ascan.ActiveScan;
import org.zaproxy.zap.extension.ascan.ExtensionActiveScan;
import org.zaproxy.zap.extension.ascan.ScanPolicy;
import org.zaproxy.zap.model.Target;
import org.zaproxy.zap.network.HttpRequestConfig;
import org.zaproxy.zap.utils.Stats;
Expand All @@ -52,6 +53,7 @@ public enum Progress {
private PlugableSpider plugableSpider;
private boolean stopAttack = false;
private boolean useStdSpider;
private String scanPolicyName;

private static final Logger LOGGER = LogManager.getLogger(AttackThread.class);

Expand All @@ -72,6 +74,10 @@ public void setTraditionalSpider(TraditionalSpider traditionalSpider) {
this.traditionalSpider = traditionalSpider;
}

public void setScanPolicyName(String scanPolicyName) {
this.scanPolicyName = scanPolicyName;
}

public void setPlugableSpider(PlugableSpider plugableSpider) {
this.plugableSpider = plugableSpider;
}
Expand Down Expand Up @@ -191,7 +197,18 @@ public void run() {
return;
} else {
extension.notifyProgress(Progress.ascan);
scanId = extAscan.startScan(target);
ScanPolicy scanPolicy = null;
if (scanPolicyName != null && !scanPolicyName.isEmpty()) {
try {
scanPolicy = extAscan.getPolicyManager().getPolicy(scanPolicyName);
} catch (Exception ex) {
LOGGER.warn("Failed to load policy {}, using default", scanPolicyName);
Comment thread
thc202 marked this conversation as resolved.
}
}
if (scanPolicy == null) {
scanPolicy = extAscan.getPolicyManager().getDefaultScanPolicy();
}
Comment thread
Adarshkumar0509 marked this conversation as resolved.
scanId = extAscan.startScan(target, null, new Object[] {scanPolicy});
}

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,12 @@ public void attack(URL url, boolean useStdSpider) {
attackThread.setURL(url);
attackThread.setTraditionalSpider(traditionalSpider);
attackThread.setPlugableSpider(plugableSpider);
if (hasView()) {
attackThread.setScanPolicyName(
getQuickStartPanel().getAttackPanel().getSelectedPolicy());
} else {
attackThread.setScanPolicyName(getQuickStartParam().getScanPolicyName());
}
attackThread.start();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ public class QuickStartParam extends VersionedAbstractParam {

private static final String PARAM_CLEARED_NEWS_ITEM = PARAM_BASE_KEY + ".clearedNews";

private static final String PARAM_SCAN_POLICY_NAME = PARAM_BASE_KEY + ".scanPolicyName";

/**
* The current version of the configurations. Used to keep track of configuration changes
* between releases, in case changes/updates are needed.
Expand Down Expand Up @@ -90,6 +92,7 @@ public class QuickStartParam extends VersionedAbstractParam {
private String ajaxSpiderSelection;
private String ajaxSpiderDefaultBrowser;
private String clearedNewsItem;
private String scanPolicyName;

@Override
protected void parseImpl() {
Comment thread
thc202 marked this conversation as resolved.
Expand Down Expand Up @@ -138,6 +141,11 @@ protected void parseImpl() {
} catch (Exception e) {
LOGGER.error("Failed to load the cleared news item configuration", e);
}
try {
scanPolicyName = getConfig().getString(PARAM_SCAN_POLICY_NAME, "");
} catch (Exception e) {
LOGGER.error("Failed to load the cleared news item configuration", e);
}
}

@Override
Expand Down Expand Up @@ -250,6 +258,15 @@ public void addRecentUrl(String url) {
QuickStartHelper.raiseOptionsChangedEvent();
}

public String getScanPolicyName() {
return scanPolicyName;
}

public void setScanPolicyName(String scanPolicyName) {
this.scanPolicyName = scanPolicyName;
getConfig().setProperty(PARAM_SCAN_POLICY_NAME, scanPolicyName);
}

public String getClearedNewsItem() {
return clearedNewsItem;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ <H3>URL to attack</H3>
This is because https://example.com/test/ is treated as a leaf node internally, which would mean that ZAP would not attack
URLs like https://example.com/test/1 etc.

<H3>Scan Policy</H3>

The scan policy to use when performing the active scan.
Comment thread
thc202 marked this conversation as resolved.
Note that the policies will not be shown dynamically, any added/removed policies will be missing until a restart is done.
<br><br>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Remove.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe this is still outstanding


<H3>Use traditional spider</H3>

The traditional spider explores the application by finding links in HTML pages.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ quickstart.label.exploreurl = URL to explore:
quickstart.label.hud = Enable HUD:
quickstart.label.hud.warn.scope = Warning: the HUD is only enabled for URLs in scope
quickstart.label.news = News
quickstart.label.policy = Scan Policy:
quickstart.label.progress = Progress:
quickstart.label.show = Show this tab on start up:
quickstart.label.tradspider = Use traditional spider:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2026 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.zap.extension.quickstart;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.zaproxy.zap.utils.ZapXmlConfiguration;

/** Unit test for {@link QuickStartParam}. */
class QuickStartParamUnitTest {

private QuickStartParam param;
private ZapXmlConfiguration configuration;

@BeforeEach
void setUp() {
param = new QuickStartParam();
configuration = new ZapXmlConfiguration();
param.load(configuration);
}

@Test
void shouldDefaultScanPolicyNameToEmpty() {
assertThat(param.getScanPolicyName(), is(equalTo("")));
}

@Test
void shouldSaveScanPolicyName() {
// Given
String policyName = "Test Policy";
// When
param.setScanPolicyName(policyName);
// Then
assertThat(param.getScanPolicyName(), is(equalTo(policyName)));
}

@Test
void shouldLoadScanPolicyNameFromConfig() {
// Given
configuration.setProperty("quickstart.scanPolicyName", "My Policy");
// When
param.load(configuration);
// Then
assertThat(param.getScanPolicyName(), is(equalTo("My Policy")));
}
}
3 changes: 2 additions & 1 deletion gradle.properties
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There should be no changes to this file

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

For gradle.properties: reply i Reverted in latest commit.

Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.parallel=true
org.gradle.jvmargs=-Xmx2g
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should be reverted.

Loading