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
1 change: 1 addition & 0 deletions addOns/reports/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Unreleased
### Changed
- Update dependencies.
- All relevant reports to support nodeName and systemic counts.

## [0.41.0] - 2025-09-04
### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package org.zaproxy.addon.reports;

import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
Expand Down Expand Up @@ -302,4 +303,69 @@ public static HttpMessage getHttpMessage(int id) {
}
return null;
}

/**
* Returns the nodeName for the alert. This will return null for versions before ZAP 2.17.
*
* @since 0.42.0
*/
public static String getNodeName(Alert alert) {
if (alert == null) {
return null;
}
try {
Method method = alert.getClass().getMethod("getNodeName");
Object ret = method.invoke(alert);
if (ret != null && ret instanceof String str) {
return str;
}
} catch (Exception e) {
// Ignore
}
return null;
}

/**
* Returns whether the alert node is systemic. This will return false for versions before ZAP
* 2.17.
*
* @since 0.42.0
*/
public static boolean isSystemic(AlertNode node) {
if (node == null) {
return false;
}
try {
Method method = node.getClass().getMethod("isSystemic");
Object ret = method.invoke(node);
if (ret != null && ret instanceof Boolean bool) {
return bool;
}
} catch (Exception e) {
// Ignore
}
return false;
}

/**
* Returns whether the alert node is systemic. This will return false for versions before ZAP
* 2.17.
*
* @since 0.42.0
*/
public static boolean isSystemic(Alert alert) {
if (alert == null) {
return false;
}
try {
Method method = alert.getClass().getMethod("isSystemic");
Object ret = method.invoke(alert);
if (ret != null && ret instanceof Boolean bool) {
return bool;
}
} catch (Exception e) {
// Ignore
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ <H3>Sample</H3>
"instances":[
{
"uri": "http://localhost:8080/bodgeit/search.jsp?q=%3C%2Ffont%3E%3CscrIpt%3Ealert%281%29%3B%3C%2FscRipt%3E%3Cfont%3E",
"nodeName": "http://localhost:8080/bodgeit/search.jsp (q)",
"method": "GET",
"param": "q",
"attack": "&lt;/font&gt;&lt;scrIpt&gt;alert(1);&lt;/scRipt&gt;&lt;font&gt;",
Expand All @@ -65,6 +66,7 @@ <H3>Sample</H3>
},
{
"uri": "http://localhost:8080/bodgeit/contact.jsp",
"nodeName": "http://localhost:8080/bodgeit/contact.jsp",
"method": "POST",
"param": "comments",
"attack": "&lt;/td&gt;&lt;scrIpt&gt;alert(1);&lt;/scRipt&gt;&lt;td&gt;",
Expand All @@ -77,6 +79,7 @@ <H3>Sample</H3>
}
],
"count": "2",
"systemic": false,
"solution": "&lt;p&gt;Phase: Architecture and Design&lt;/p&gt;&lt;p&gt;Use a vetted library or framework that does not ...&lt;/p&gt;",
"otherinfo": "",
"reference": "&lt;p&gt;http://projects.webappsec.org/Cross-Site-Scripting&lt;/p&gt;&lt;p&gt;http://cwe.mitre.org/data/definitions/79.html&lt;/p&gt;",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ <H3>Sample</H3>
"instances":[
{
"uri": "http://localhost:8080/bodgeit/search.jsp?q=%3C%2Ffont%3E%3CscrIpt%3Ealert%281%29%3B%3C%2FscRipt%3E%3Cfont%3E",
"nodeName": "http://localhost:8080/bodgeit/search.jsp (q)",
"method": "GET",
"param": "q",
"attack": "&lt;/font&gt;&lt;scrIpt&gt;alert(1);&lt;/scRipt&gt;&lt;font&gt;",
Expand All @@ -40,6 +41,7 @@ <H3>Sample</H3>
},
{
"uri": "http://localhost:8080/bodgeit/contact.jsp",
"nodeName": "http://localhost:8080/bodgeit/contact.jsp",
"method": "POST",
"param": "comments",
"attack": "&lt;/td&gt;&lt;scrIpt&gt;alert(1);&lt;/scRipt&gt;&lt;td&gt;",
Expand All @@ -48,6 +50,7 @@ <H3>Sample</H3>
}
],
"count": "2",
"systemic": false,
"solution": "&lt;p&gt;Phase: Architecture and Design&lt;/p&gt;&lt;p&gt;Use a vetted library or framework that does not ...&lt;/p&gt;",
"otherinfo": "",
"reference": "&lt;p&gt;http://projects.webappsec.org/Cross-Site-Scripting&lt;/p&gt;&lt;p&gt;http://cwe.mitre.org/data/definitions/79.html&lt;/p&gt;",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,21 @@ <H4>
CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.

* URL: http://localhost:8080/bodgeit/advanced.jsp
* Node Name: http://localhost:8080/bodgeit/advanced.jsp
* Method: `GET`
* Parameter: ``
* Attack: ``
* Evidence: `&lt;form id="advanced" name="advanced" method="POST" onsubmit="return validateForm(this);false;"&gt;`
* Other Info: ``
* URL: http://localhost:8080/bodgeit/advanced.jsp
* Node Name: http://localhost:8080/bodgeit/advanced.jsp
* Method: `GET`
* Parameter: ``
* Attack: ``
* Evidence: `&lt;form id="query" name="advanced" method="POST"&gt;`
* Other Info: ``
* URL: http://localhost:8080/bodgeit/basket.jsp
* Node Name: http://localhost:8080/bodgeit/basket.jsp
* Method: `GET`
* Parameter: ``
* Attack: ``
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ <H3>Sample</H3>

&lt;instance&gt;
&lt;uri&gt;http://localhost:8080/bodgeit/js&lt;/uri&gt;
&lt;nodeName&gt;http://localhost:8080/bodgeit/js&lt;/nodeName&gt;
&lt;method&gt;GET&lt;/method&gt;
&lt;param&gt;&lt;/param&gt;
&lt;attack&gt;&lt;/attack&gt;
Expand Down Expand Up @@ -61,6 +62,7 @@ <H3>Sample</H3>

&lt;instance&gt;
&lt;uri&gt;http://localhost:8080/bodgeit/js/util.js&lt;/uri&gt;
&lt;nodeName&gt;http://localhost:8080/bodgeit/js/util.js&lt;/nodeName&gt;
&lt;method&gt;GET&lt;/method&gt;
&lt;param&gt;&lt;/param&gt;
&lt;attack&gt;&lt;/attack&gt;
Expand Down Expand Up @@ -157,6 +159,7 @@ <H3>Sample</H3>

&lt;/instances&gt;
&lt;count&gt;3&lt;/count&gt;
&lt;systemic&gt;false&lt;/systemic&gt;
&lt;solution&gt;&lt;/solution&gt;
&lt;otherinfo&gt;NOTE: Because of its name this cookie may be important, but dropping it appears to have no effect: [JSESSIONID]
Cookies that don&amp;apos;t have expected effects can reveal flaws in application logic. In the worst case, this can reveal where authentication via cookie token(s) is not actually enforced.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ <H3>Sample</H3>
&lt;confidencedesc&gt;Medium&lt;/confidencedesc&gt;
&lt;desc&gt;&lt;p&gt;A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge...&lt;/desc&gt;
&lt;instances&gt;

&lt;instance&gt;
&lt;uri&gt;http://localhost:8080/bodgeit/advanced.jsp&lt;/uri&gt;
&lt;nodeName&gt;http://localhost:8080/bodgeit/advanced.jsp&lt;/nodeName&gt;
&lt;method&gt;GET&lt;/method&gt;
&lt;param&gt;&lt;/param&gt;
&lt;attack&gt;&lt;/attack&gt;
Expand All @@ -38,6 +38,7 @@ <H3>Sample</H3>

&lt;instance&gt;
&lt;uri&gt;http://localhost:8080/bodgeit/advanced.jsp&lt;/uri&gt;
&lt;nodeName&gt;http://localhost:8080/bodgeit/advanced.jsp&lt;/nodeName&gt;
&lt;method&gt;GET&lt;/method&gt;
&lt;param&gt;&lt;/param&gt;
&lt;attack&gt;&lt;/attack&gt;
Expand All @@ -47,13 +48,17 @@ <H3>Sample</H3>

&lt;instance&gt;
&lt;uri&gt;http://localhost:8080/bodgeit/basket.jsp&lt;/uri&gt;
&lt;nodeName&gt;http://localhost:8080/bodgeit/basket.jsp&lt;/nodeName&gt;
&lt;method&gt;GET&lt;/method&gt;
&lt;param&gt;&lt;/param&gt;
&lt;attack&gt;&lt;/attack&gt;
&lt;evidence&gt;&lt;form action=&quot;basket.jsp&quot; method=&quot;post&quot;&gt;&lt;/evidence&gt;
&lt;otherinfo&gt;&lt;/otherinfo&gt;
&lt;/instance&gt;

&lt;count&gt;2&lt;/count&gt;
&lt;systemic&gt;false&lt;/systemic&gt;
&lt;solution&gt;The solution&lt;/solution&gt;
&lt;otherinfo&gt;The other info&lt;/otherinfo&gt;

</pre>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ reports.report.alerts.detail.description = Description
reports.report.alerts.detail.evidence = Evidence
reports.report.alerts.detail.instances = Instances
reports.report.alerts.detail.method = Method
reports.report.alerts.detail.nodename = Node Name
reports.report.alerts.detail.otherinfo = Other Info
reports.report.alerts.detail.param = Parameter
reports.report.alerts.detail.pluginid = Plugin Id
Expand All @@ -113,6 +114,7 @@ reports.report.alerts.list = Alerts
reports.report.alerts.list.name = Name
reports.report.alerts.list.numinstances = Number of Instances
reports.report.alerts.list.risklevel = Risk Level
reports.report.alerts.list.systemic = Systemic
reports.report.alerts.summary = Summary of Alerts
reports.report.alerts.summary.numalerts = Number of Alerts
reports.report.alerts.summary.risklevel = Risk Level
Expand Down
23 changes: 21 additions & 2 deletions addOns/reports/src/main/zapHomeFiles/reports/modern/report.html
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,12 @@ <h3 th:text="#{report.alerts.list}">Alerts</h3>
Name</a></td>
<td align="center" th:class="${'risk-' + alert.risk}"
th:text="${helper.getRiskString(alert.risk)}">Risk</td>
<td align="center" th:text="${alert.childCount}">Count</td>
<th:block th:if="${helper.isSystemic(alert)}">
<td align="center" th:text="#{report.alerts.list.systemic}">Systemic</td>
</th:block>
<th:block th:unless="${helper.isSystemic(alert)}">
<td align="center" th:text="${alert.childCount}">Count</td>
</th:block>
</tr>
</table>
</div>
Expand Down Expand Up @@ -437,6 +442,15 @@ <h3 th:text="#{report.alerts.detail}">Alert Detail</h3>
<td width="80%"><a th:href="${instance.userObject.uri}"
th:text="${instance.userObject.uri}" href="url.html">URL</a></td>
</tr>
<th:block
th:if="${helper.getNodeName(instance.userObject) != null}">
<tr>
<td th:text="#{report.alerts.detail.nodename}" width="20%"
class="indent2">Node Name</td>
<td th:text="${helper.getNodeName(instance.userObject)}"
width="80%">Node Name</td>
</tr>
</th:block>
<tr>
<td th:text="#{report.alerts.detail.method}" width="20%"
class="indent2">Method</td>
Expand Down Expand Up @@ -543,7 +557,12 @@ <h3 th:text="#{report.alerts.detail}">Alert Detail</h3>
</th:block>
<tr>
<td th:text="#{report.alerts.detail.instances}" width="20%">Instances</td>
<td th:text="${alert.childCount}" width="80%">Instances</td>
<th:block th:if="${helper.isSystemic(alert)}">
<td th:text="#{report.alerts.list.systemic}" width="80%">Systemic</td>
</th:block>
<th:block th:unless="${helper.isSystemic(alert)}">
<td th:text="${alert.childCount}" width="80%">Instances</td>
</th:block>
</tr>
<tr>
<td th:text="#{report.alerts.detail.solution}" width="20%">Solution</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,12 @@ <h3 th:text="#{report.alerts.list}">Alerts</h3>
th:text="${alert.nodeName}" href="#plugin-pluginId">Alert Name</a></td>
<td align="center" th:class="${'risk-' + alert.risk}"
th:text="${helper.getRiskString(alert.risk)}">Risk</td>
<th:block th:if="${helper.isSystemic(alert)}">
<td align="center" th:text="#{report.alerts.list.systemic}">Systemic</td>
</th:block>
<th:block th:unless="${helper.isSystemic(alert)}">
<td align="center" th:text="${alert.childCount}">Count</td>
</th:block>
</tr>
</table>
<div class="spacer-lg"></div>
Expand Down Expand Up @@ -410,6 +415,11 @@ <h3 th:text="#{report.alerts.detail}">Alert Detail</h3>
<td width="80%"><a th:href="${instance.userObject.uri}"
th:text="${instance.userObject.uri}" href="url.html">URL</a></td>
</tr>
<th:block th:if="${helper.getNodeName(instance.userObject) != null}"><tr>
<td th:text="#{report.alerts.detail.nodename}" width="20%"
class="indent2">Node Name</td>
<td th:text="${helper.getNodeName(instance.userObject)}" width="80%">Node Name</td>
</tr></th:block>
<tr>
<td th:text="#{report.alerts.detail.method}" width="20%"
class="indent2">Method</td>
Expand Down Expand Up @@ -518,7 +528,12 @@ <h3 th:text="#{report.alerts.detail}">Alert Detail</h3>
</th:block>
<tr>
<td th:text="#{report.alerts.detail.instances}" width="20%">Instances</td>
<th:block th:if="${helper.isSystemic(alert)}">
<td th:text="#{report.alerts.list.systemic}" width="80%">Systemic</td>
</th:block>
<th:block th:unless="${helper.isSystemic(alert)}">
<td th:text="${alert.childCount}" width="80%">Instances</td>
</th:block>
</tr>
<tr>
<td th:text="#{report.alerts.detail.solution}" width="20%">Solution</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,12 @@ <h3 th:text="#{report.alerts.list}">Alerts</h3>
th:text="${alert.nodeName}" href="#oluginId">Alert Name</a></td>
<td align="center" th:class="${'risk-' + alert.risk}"
th:text="${helper.getRiskString(alert.risk)}">Risk</td>
<th:block th:if="${helper.isSystemic(alert)}">
<td align="center" th:text="#{report.alerts.list.systemic}">Systemic</td>
</th:block>
<th:block th:unless="${helper.isSystemic(alert)}">
<td align="center" th:text="${alert.childCount}">Count</td>
</th:block>
</tr>
</table>
<div class="spacer-lg"></div>
Expand Down Expand Up @@ -359,6 +364,11 @@ <h3 th:text="#{report.alerts.detail}">Alert Detail</h3>
<td width="80%"><a th:href="${instance.userObject.uri}"
th:text="${instance.userObject.uri}" href="url.html">URL</a></td>
</tr>
<th:block th:if="${helper.getNodeName(instance.userObject) != null}"><tr>
<td th:text="#{report.alerts.detail.nodename}" width="20%"
class="indent2">Node Name</td>
<td th:text="${helper.getNodeName(instance.userObject)}" width="80%">Node Name</td>
</tr></th:block>
<tr>
<td th:text="#{report.alerts.detail.method}" width="20%"
class="indent2">Method</td>
Expand Down Expand Up @@ -388,7 +398,12 @@ <h3 th:text="#{report.alerts.detail}">Alert Detail</h3>
</th:block>
<tr>
<td th:text="#{report.alerts.detail.instances}" width="20%">Instances</td>
<th:block th:if="${helper.isSystemic(alert)}">
<td th:text="#{report.alerts.list.systemic}" width="80%">Systemic</td>
</th:block>
<th:block th:unless="${helper.isSystemic(alert)}">
<td th:text="${alert.childCount}" width="80%">Instances</td>
</th:block>
</tr>
<tr>
<td th:text="#{report.alerts.detail.solution}" width="20%">Solution</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
{
"id": "[(${instance.alertId})]",
"uri": "[(${helper.legacyEscapeText(instance.uri, true)})]",
"nodeName": "[(${helper.legacyEscapeText(helper.getNodeName(instance))})]",
"method": "[(${helper.legacyEscapeText(instance.method, true)})]",
"param": "[(${helper.legacyEscapeTextAlertParam(instance, true)})]",
"attack": "[(${helper.legacyEscapeText(instance.attack, true)})]",
Expand All @@ -35,6 +36,7 @@
}[/th:block]
],
"count": "[(${instances.size})]",
"systemic": [(${helper.isSystemic(alert)})],
"solution": "[(${helper.legacyEscapeParagraph(alert.solution, true)})]",
"otherinfo": "[(${helper.legacyEscapeParagraph(alert.otherinfo, true)})]",
"reference": "[(${helper.legacyEscapeParagraph(alert.reference, true)})]",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
{
"id": "[(${instance.alertId})]",
"uri": "[(${helper.legacyEscapeText(instance.uri, true)})]",
"nodeName": "[(${helper.legacyEscapeText(helper.getNodeName(instance))})]",
"method": "[(${helper.legacyEscapeText(instance.method, true)})]",
"param": "[(${helper.legacyEscapeTextAlertParam(instance, true)})]",
"attack": "[(${helper.legacyEscapeText(instance.attack, true)})]",
Expand All @@ -31,6 +32,7 @@
}[/th:block]
],
"count": "[(${instances.size})]",
"systemic": [(${helper.isSystemic(alert)})],
"solution": "[(${helper.legacyEscapeParagraph(alert.solution, true)})]",
"otherinfo": "[(${helper.legacyEscapeParagraph(alert.otherinfo, true)})]",
"reference": "[(${helper.legacyEscapeParagraph(alert.reference, true)})]",
Expand Down
Loading