Skip to content

Commit f4f0981

Browse files
authored
Merge pull request #7281 from psiinon/commonlib/vibe-fix
commonLib: Alert menu item for generating a fix prompt
2 parents ea2ba47 + bfcf147 commit f4f0981

8 files changed

Lines changed: 287 additions & 0 deletions

File tree

addOns/commonlib/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## Unreleased
8+
### Added
9+
- Generate Fix Prompt alert menu item.
10+
811
### Changed
912
- Update dependencies.
1013

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Zed Attack Proxy (ZAP) and its related class files.
3+
*
4+
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
5+
*
6+
* Copyright 2026 The ZAP Development Team
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
package org.zaproxy.addon.commonlib;
21+
22+
import org.parosproxy.paros.common.AbstractParam;
23+
24+
/** Persisted configuration for the Common Library add-on. */
25+
public class CommonlibParam extends AbstractParam {
26+
27+
private static final String PARAM_BASE_KEY = "commonlib";
28+
29+
private static final String PARAM_SHOW_FIX_PROMPT_COPIED_DIALOG =
30+
PARAM_BASE_KEY + ".alert.generatefixprompt.showCopiedDialog";
31+
32+
private boolean showFixPromptCopiedDialog = true;
33+
34+
@Override
35+
protected void parse() {
36+
showFixPromptCopiedDialog = getBoolean(PARAM_SHOW_FIX_PROMPT_COPIED_DIALOG, true);
37+
}
38+
39+
/**
40+
* Returns whether the "fix prompt copied to clipboard" confirmation dialog should be shown.
41+
*
42+
* @return {@code true} if the dialog should be shown, {@code false} otherwise.
43+
*/
44+
public boolean isShowFixPromptCopiedDialog() {
45+
return showFixPromptCopiedDialog;
46+
}
47+
48+
/**
49+
* Sets whether the "fix prompt copied to clipboard" confirmation dialog should be shown.
50+
*
51+
* @param show {@code true} if the dialog should be shown, {@code false} otherwise.
52+
*/
53+
public void setShowFixPromptCopiedDialog(boolean show) {
54+
if (showFixPromptCopiedDialog != show) {
55+
showFixPromptCopiedDialog = show;
56+
getConfig().setProperty(PARAM_SHOW_FIX_PROMPT_COPIED_DIALOG, showFixPromptCopiedDialog);
57+
}
58+
}
59+
}

addOns/commonlib/src/main/java/org/zaproxy/addon/commonlib/ExtensionCommonlib.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.parosproxy.paros.extension.SessionChangedListener;
3030
import org.parosproxy.paros.model.Session;
3131
import org.zaproxy.addon.commonlib.internal.vulns.LegacyVulnerabilities;
32+
import org.zaproxy.addon.commonlib.ui.GenerateFixPromptMenu;
3233
import org.zaproxy.addon.commonlib.ui.ProgressPanel;
3334
import org.zaproxy.addon.commonlib.ui.TabbedOutputPanel;
3435

@@ -108,9 +109,13 @@ public ExtensionCommonlib() {
108109

109110
@Override
110111
public void hook(ExtensionHook extensionHook) {
112+
CommonlibParam commonlibParam = new CommonlibParam();
113+
extensionHook.addOptionsParamSet(commonlibParam);
114+
111115
if (hasView()) {
112116
extensionHook.getHookView().addStatusPanel(getProgressPanel());
113117
getView().setOutputPanel(new TabbedOutputPanel());
118+
extensionHook.getHookMenu().addPopupMenuItem(new GenerateFixPromptMenu(commonlibParam));
114119
}
115120
extensionHook.addSessionListener(new SessionChangedListenerImpl());
116121
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Zed Attack Proxy (ZAP) and its related class files.
3+
*
4+
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
5+
*
6+
* Copyright 2026 The ZAP Development Team
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
package org.zaproxy.addon.commonlib.ui;
21+
22+
import java.awt.Toolkit;
23+
import java.awt.datatransfer.StringSelection;
24+
import javax.swing.JCheckBox;
25+
import javax.swing.JOptionPane;
26+
import org.apache.commons.lang3.StringUtils;
27+
import org.parosproxy.paros.Constant;
28+
import org.parosproxy.paros.core.scanner.Alert;
29+
import org.parosproxy.paros.view.View;
30+
import org.zaproxy.addon.commonlib.CommonAlertTag;
31+
import org.zaproxy.addon.commonlib.CommonlibParam;
32+
import org.zaproxy.zap.extension.alert.PopupMenuItemAlert;
33+
34+
/**
35+
* A right-click menu item for alerts that generates a prompt the user can paste into an LLM to ask
36+
* it to fix the vulnerability. The prompt is copied to the system clipboard.
37+
*
38+
* <p>The prompt text is intentionally written in English rather than translated, as LLMs generally
39+
* perform better with English input.
40+
*/
41+
@SuppressWarnings("serial")
42+
public class GenerateFixPromptMenu extends PopupMenuItemAlert {
43+
44+
private static final long serialVersionUID = 1L;
45+
46+
// Prompt text is not i18n - LLMs handle English better than other languages.
47+
private static final String INTRO =
48+
"A security scanner (ZAP by Checkmarx) has found a vulnerability in the application you are"
49+
+ " working on. Please identify where in the codebase this vulnerability exists"
50+
+ " and provide a fix.";
51+
private static final String SYSTEMIC_NOTE =
52+
"Note: This vulnerability appears to occur across the application - there may be"
53+
+ " multiple instances that all need to be fixed.";
54+
private static final String CLOSING =
55+
"Please identify where in the codebase this vulnerability exists and provide a fix.";
56+
57+
private final CommonlibParam param;
58+
59+
public GenerateFixPromptMenu(CommonlibParam param) {
60+
super(Constant.messages.getString("commonlib.alert.generatefixprompt.menu"), false);
61+
this.param = param;
62+
}
63+
64+
@Override
65+
public void performAction(Alert alert) {
66+
String prompt = buildPrompt(alert);
67+
Toolkit.getDefaultToolkit()
68+
.getSystemClipboard()
69+
.setContents(new StringSelection(prompt), null);
70+
71+
if (param.isShowFixPromptCopiedDialog()) {
72+
JCheckBox doNotShowAgain =
73+
new JCheckBox(
74+
Constant.messages.getString(
75+
"commonlib.alert.generatefixprompt.donotshowagain"));
76+
JOptionPane.showMessageDialog(
77+
View.getSingleton().getMainFrame(),
78+
new Object[] {
79+
Constant.messages.getString("commonlib.alert.generatefixprompt.copied"),
80+
" ",
81+
doNotShowAgain
82+
},
83+
Constant.messages.getString("commonlib.alert.generatefixprompt.title"),
84+
JOptionPane.INFORMATION_MESSAGE);
85+
param.setShowFixPromptCopiedDialog(!doNotShowAgain.isSelected());
86+
}
87+
}
88+
89+
static String buildPrompt(Alert alert) {
90+
StringBuilder sb = new StringBuilder();
91+
92+
sb.append(INTRO);
93+
sb.append("\n\n");
94+
95+
boolean systemic =
96+
alert.getTags() != null
97+
&& alert.getTags().containsKey(CommonAlertTag.SYSTEMIC.getTag());
98+
if (systemic) {
99+
sb.append(SYSTEMIC_NOTE);
100+
sb.append("\n\n");
101+
}
102+
103+
sb.append("## Vulnerability\n\n");
104+
105+
appendField(sb, "Name", alert.getName());
106+
107+
int risk = alert.getRisk();
108+
if (risk >= 0 && risk < Alert.MSG_RISK.length) {
109+
appendField(sb, "Risk", Alert.MSG_RISK[risk]);
110+
}
111+
112+
int confidence = alert.getConfidence();
113+
if (confidence >= 0 && confidence < Alert.MSG_CONFIDENCE.length) {
114+
appendField(sb, "Confidence", Alert.MSG_CONFIDENCE[confidence]);
115+
}
116+
117+
appendField(sb, "URL", alert.getUri());
118+
appendField(sb, "Method", alert.getMethod());
119+
appendField(sb, "Parameter", alert.getParam());
120+
appendField(sb, "Attack", alert.getAttack());
121+
appendField(sb, "Evidence", alert.getEvidence());
122+
123+
appendSection(sb, "Description", alert.getDescription());
124+
appendSection(sb, "Solution", alert.getSolution());
125+
appendSection(sb, "References", alert.getReference());
126+
appendSection(sb, "Other Information", alert.getOtherInfo());
127+
128+
sb.append("\n").append(CLOSING);
129+
130+
return sb.toString();
131+
}
132+
133+
private static void appendField(StringBuilder sb, String label, String value) {
134+
if (StringUtils.isNotBlank(value)) {
135+
sb.append("**").append(label).append("**: ").append(value).append("\n");
136+
}
137+
}
138+
139+
private static void appendSection(StringBuilder sb, String heading, String value) {
140+
if (StringUtils.isNotBlank(value)) {
141+
sb.append("\n## ").append(heading).append("\n\n");
142+
sb.append(value).append("\n");
143+
}
144+
}
145+
146+
@Override
147+
public boolean isSafe() {
148+
return true;
149+
}
150+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
2+
<html>
3+
<head>
4+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5+
<title>
6+
Generate Fix Prompt
7+
</title>
8+
</head>
9+
<body>
10+
<h1>Generate Fix Prompt</h1>
11+
12+
The <strong>Generate Fix Prompt</strong> right-click menu option is available on alerts in the Alerts tab.
13+
It generates a prompt that you can paste into any Large Language Model (LLM) — such as ChatGPT, GitHub Copilot,
14+
or Claude — and ask it to fix the vulnerability in your codebase.
15+
16+
<h2>Usage</h2>
17+
18+
<ol>
19+
<li>Right-click an alert in the Alerts tab.</li>
20+
<li>Select <strong>Generate Fix Prompt</strong>.</li>
21+
<li>The prompt is copied to your clipboard.</li>
22+
<li>Paste it into your LLM of choice and review its suggested fix.</li>
23+
</ol>
24+
25+
<h2>What the prompt contains</h2>
26+
27+
The generated prompt includes all information ZAP has about the vulnerability:
28+
29+
<ul>
30+
<li><strong>Name</strong> — the alert name.</li>
31+
<li><strong>Risk</strong> — Informational, Low, Medium, or High.</li>
32+
<li><strong>Confidence</strong> — how confident ZAP is that the finding is a true positive.</li>
33+
<li><strong>URL</strong> — the URL at which the vulnerability was found.</li>
34+
<li><strong>Method</strong> — the HTTP method used (GET, POST, etc.).</li>
35+
<li><strong>Parameter</strong> — the affected parameter, if applicable.</li>
36+
<li><strong>Attack</strong> — the payload ZAP used to trigger the vulnerability, if applicable.</li>
37+
<li><strong>Evidence</strong> — the string found in the response that confirmed the vulnerability, if applicable.</li>
38+
<li><strong>Description</strong> — a full description of the vulnerability class.</li>
39+
<li><strong>Solution</strong> — ZAP's recommended remediation guidance.</li>
40+
<li><strong>References</strong> — links to further reading.</li>
41+
<li><strong>Other Information</strong> — any additional context provided by the scan rule.</li>
42+
</ul>
43+
44+
<h2>Systemic vulnerabilities</h2>
45+
46+
Some scan rules raise <em>systemic</em> alerts — issues that tend to affect the whole application rather than a single
47+
endpoint, such as missing security headers or insecure cookie settings. When a systemic alert is detected the prompt
48+
includes a note telling the LLM that there may be multiple instances across the codebase that all need to be fixed.
49+
50+
<h2>Confirmation dialog</h2>
51+
52+
After the prompt is copied a confirmation dialog is shown. You can suppress this dialog in future by selecting
53+
<strong>Do not show this message again</strong> before dismissing it. This preference is saved in the ZAP
54+
configuration file and can be restored by resetting ZAP's options.
55+
56+
<p>
57+
See also:
58+
<ul>
59+
<li><a href="https://www.zaproxy.org/docs/desktop/ui/tabs/alerts/">Alerts tab</a></li>
60+
</ul>
61+
62+
</body>
63+
</html>

addOns/commonlib/src/main/javahelp/help/map.jhm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77
<mapID target="commonlib" url="contents/commonlib.html" />
88
<mapID target="commonlib.output.panel" url="contents/output-panel.html" />
99
<mapID target="commonlib.alert.tags" url="contents/alerttags.html" />
10+
<mapID target="commonlib.alert.generatefixprompt" url="contents/generate-fix-prompt.html" />
1011
</map>

addOns/commonlib/src/main/javahelp/help/toc.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<tocitem text="Common Library" target="commonlib">
1010
<tocitem text="Tabbed Output Panel" target="commonlib.output.panel" />
1111
<tocitem text="Alert Tags" target="commonlib.alert.tags" />
12+
<tocitem text="Generate Fix Prompt" target="commonlib.alert.generatefixprompt" />
1213
</tocitem>
1314
</tocitem>
1415
</tocitem>

addOns/commonlib/src/main/resources/org/zaproxy/addon/commonlib/resources/Messages.properties

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
commonlib.alert.generatefixprompt.copied = The fix prompt has been copied to the clipboard.\nYou can now paste it into an LLM to ask it to fix the vulnerability.
2+
commonlib.alert.generatefixprompt.donotshowagain = Do not show this message again
3+
commonlib.alert.generatefixprompt.menu = Generate Fix Prompt
4+
commonlib.alert.generatefixprompt.title = Fix Prompt Copied
5+
16
commonlib.desc = A library of shared functionality
27

38
commonlib.name = Common Library

0 commit comments

Comments
 (0)