Skip to content
Closed
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
9 changes: 6 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@

<properties>
<apache-log4j.version>2.25.3</apache-log4j.version>
<zap-clientapi.version>1.16.0</zap-clientapi.version>
<zap-clientapi.version>1.17.0</zap-clientapi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.version>3.8.1</maven.compiler.version>
<maven.compiler.version>3.13.0</maven.compiler.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
Comment thread
sr4850 marked this conversation as resolved.
<github.url>https://maven.pkg.github.com/dvsa/vol-app-security-lib</github.url>
Comment on lines +13 to 16
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

<maven.compiler.source> and <maven.compiler.target> are defined as properties, but the maven-compiler-plugin config below hardcodes 17 instead of referencing these properties. Consider wiring the plugin values to the properties (or removing the unused properties) to avoid configuration drift.

Copilot uses AI. Check for mistakes.
</properties>

Expand All @@ -21,7 +23,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.version}</version>
<configuration>
<release>11</release>
<source>17</source>
<target>17</target>
Comment thread
sr4850 marked this conversation as resolved.
</configuration>
Comment on lines 25 to 28
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

Consider using 17 instead of separate /. ensures the correct platform APIs are targeted and is the recommended maven-compiler-plugin configuration for reproducible builds.

Copilot uses AI. Check for mistakes.
</plugin>
</plugins>
Expand Down
166 changes: 66 additions & 100 deletions src/main/java/scanner/ScannerMethods.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,48 @@ public ScannerMethods(String ZAP_IP_ADDRESS, int ZAP_PORT) {
* Method for creating summary table for HTML report
*/
private String createReportSummaryTable() {
return "<table width=45% border=0>" + "<tr bgcolor=#666666>" +
"<td width=45% height=24>" + "<strong>" + "<font color=#FFFFFF size=2 face=Arial, Helvetica, sans-serif>URLs SCANNED" + "</font></strong></td></tr>" +
"<tr bgcolor=#e8e8e8>" +
String.format("<td><font size=2 face=Arial, Helvetica, sans-serif><a href=#%s>%s</a></font></td>", this.reportURL, this.reportURL) +
"</tr>" +
"<p></p>" +
"<p></p>" +
"<p></p>" +
"<p></p>";
return String.format("""
<table width=45%% border=0>
<tr bgcolor=#666666>
<td width=45%% height=24>
<strong>
<font color=#FFFFFF size=2 face=Arial, Helvetica, sans-serif>URLs SCANNED</font>
</strong>
</td>
</tr>
<tr bgcolor=#e8e8e8>
<td><font size=2 face=Arial, Helvetica, sans-serif><a href=#%s>%s</a></font></td>
</tr>
<p></p>
<p></p>
<p></p>
<p></p>""", this.reportURL, this.reportURL);
Comment on lines +48 to +52
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

This summary table HTML inserts multiple

elements directly inside a (outside any /
) and doesn’t close the table, which is invalid markup and can render inconsistently. Consider using CSS spacing or spacer
rows, and ensure the table is properly closed.

Copilot uses AI. Check for mistakes.
}

/**
* Method for creating header response and requests summary table for HTML report
*/
private String headersAndResponseSummaryTable() throws ClientApiException {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("<table width=45% border=0>")
.append("<tr bgcolor=#666666>")
.append("<h3>Server Requests and Responses</h3>").append("<div class=spacer></div>")
.append("<td width=50%>Request</td>")
.append("<td width=50%><p>Response</p></td>");
stringBuilder.append("""
<table width=45%% border=0>
<tr bgcolor=#666666>
<h3>Server Requests and Responses</h3><div class=spacer></div>
<td width=50%%>Request</td>
<td width=50%%><p>Response</p></td>""");
Comment on lines +61 to +65
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The header markup is not valid table structure:

and
are placed directly inside a rather than within a /, and the opening isn’t closed before additional rows are appended. Move the heading outside the table (or use ) and ensure each row has proper ... with cells.

Copilot uses AI. Check for mistakes.

response = this.clientApi.core.messages(this.reportURL, "-1", "-1");
ApiResponseList apiResponseList = (ApiResponseList) response;
for (ApiResponse apiResponse : apiResponseList.getItems()) {
ApiResponseSet serverResponse = (ApiResponseSet) apiResponse;
stringBuilder.append("<tr bgcolor=#e8e8e8>")
.append(String.format("<td width=100><p>%s</p></td>", serverResponse.getStringValue("requestHeader")))
.append(String.format("<td width=100><p>%s</p></td>", serverResponse.getStringValue("responseHeader")))
.append("</tr>");
if (apiResponse instanceof ApiResponseSet serverResponse) {
stringBuilder.append(String.format("""
<tr bgcolor=#e8e8e8>
<td width=100><p>%s</p></td>
<td width=100><p>%s</p></td>
</tr>""",
serverResponse.getStringValue("requestHeader"),
serverResponse.getStringValue("responseHeader")));
}
}
return stringBuilder.toString();
}
Expand All @@ -82,7 +94,8 @@ public void createReport(String reportName, String reportURL) {
}
try {
this.clientApi.reports.generate(reportName, "traditional-html", null, null, null,
null, null, null, null, reportName.concat(date + " -" + seconds), null, System.getProperty("user.dir").concat("/" + dir), null);
null, null, null, null, String.format("%s%s - %d", reportName, date, seconds), null,
String.format("%s/%s", System.getProperty("user.dir"), dir), null);
Comment on lines +97 to +98
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The report output path is built with a hardcoded '/' separator (String.format("%s/%s", ...)), which is not portable across OSes. Prefer dir.getAbsolutePath() or Paths.get(System.getProperty("user.dir"), dir.getPath()).toString() / File(base, child) to construct the path safely.

Suggested change
null, null, null, null, String.format("%s%s - %d", reportName, date, seconds), null,
String.format("%s/%s", System.getProperty("user.dir"), dir), null);
null, null, null, null, String.format("%s%s - %d", reportName, date, seconds), null,
new File(System.getProperty("user.dir"), dir.getPath()).getAbsolutePath(), null);

Copilot uses AI. Check for mistakes.
} catch (ClientApiException e) {
LOGGER.info(e);
}
Expand Down Expand Up @@ -156,8 +169,9 @@ public void includeInContext(String CONTEXT_NAME, String url) throws ClientApiEx
*/
public void setAuthenticationMethod(String siteUrl, String loginRequest, String authentication) throws Exception {

String formBasedConfig = "loginUrl=" + URLEncoder.encode(siteUrl, StandardCharsets.UTF_8) +
"&loginRequestData=" + URLEncoder.encode(loginRequest, StandardCharsets.UTF_8);
String formBasedConfig = String.format("loginUrl=%s&loginRequestData=%s",
URLEncoder.encode(siteUrl, StandardCharsets.UTF_8),
URLEncoder.encode(loginRequest, StandardCharsets.UTF_8));
this.clientApi.authentication.setAuthenticationMethod(CONTEXT_ID, authentication, formBasedConfig);
// Check if everything is set up ok
LOGGER.info("Authentication Setup: {}", clientApi.authentication.getAuthenticationMethod(CONTEXT_ID).toString(0));
Expand Down Expand Up @@ -204,8 +218,9 @@ public void allowRescan(boolean setStatus) throws ClientApiException {
public void authenticateUser(String username, String password) throws Exception {
user = "VOLUser";

String userAuthConfig = "username=" + URLEncoder.encode(username, StandardCharsets.UTF_8) +
"&password=" + URLEncoder.encode(password, StandardCharsets.UTF_8);
String userAuthConfig = String.format("username=%s&password=%s",
URLEncoder.encode(username, StandardCharsets.UTF_8),
URLEncoder.encode(password, StandardCharsets.UTF_8));

userId = extractUserId(clientApi.users.newUser(CONTEXT_ID, user));

Expand Down Expand Up @@ -258,81 +273,32 @@ public void filterAlerts(String ruleId, String newLevel) throws Exception {
* @param policyName Policy Ids to be used when scanning
*/
public String setPolicyId(String policyName) {
String scannerId;
switch (policyName) {
case "directory-browsing":
scannerId = "0";
break;
case "cross-site-scripting":
scannerId = "40012,40014,40016,40017";
break;
case "sql-injection":
scannerId = "40018";
break;
case "path-traversal":
scannerId = "6";
break;
case "remote-file-inclusion":
scannerId = "7";
break;
case "server-side-include":
scannerId = "40009";
break;
case "script-active-scan-rules":
scannerId = "50000";
break;
case "server-side-code-injection":
scannerId = "90019";
break;
case "remote-os-command-injection":
scannerId = "90020";
break;
case "external-redirect":
scannerId = "20019";
break;
case "crlf-injection":
scannerId = "40003";
break;
case "source-code-disclosure":
scannerId = "42,10045,20017";
break;
case "shell-shock":
scannerId = "10048";
break;
case "remote-code-execution":
scannerId = "20018";
break;
case "ldap-injection":
scannerId = "40015";
break;
case "xpath-injection":
scannerId = "90021";
break;
case "xml-external-entity":
scannerId = "90023";
break;
case "padding-oracle":
scannerId = "90024";
break;
case "el-injection":
scannerId = "90025";
break;
case "insecure-http-methods":
scannerId = "90028";
break;
case "parameter-pollution":
scannerId = "20014";
break;
case "parameter-tampering":
scannerId = "40008";
break;
case "SOAP XML Injection":
scannerId = "90029";
break;
default:
throw new RuntimeException("No policy id found for: " + policyName);
}
return scannerId;
return switch (policyName) {
case "directory-browsing" -> "0";
case "cross-site-scripting" -> "40012,40014,40016,40017";
case "sql-injection" -> "40018";
case "path-traversal" -> "6";
case "remote-file-inclusion" -> "7";
case "server-side-include" -> "40009";
case "script-active-scan-rules" -> "50000";
case "server-side-code-injection" -> "90019";
case "remote-os-command-injection" -> "90020";
case "external-redirect" -> "20019";
case "crlf-injection" -> "40003";
case "source-code-disclosure" -> "42,10045,20017";
case "shell-shock" -> "10048";
case "remote-code-execution" -> "20018";
case "ldap-injection" -> "40015";
case "xpath-injection" -> "90021";
case "xml-external-entity" -> "90023";
case "padding-oracle" -> "90024";
case "el-injection" -> "90025";
case "insecure-http-methods" -> "90028";
case "parameter-pollution" -> "20014";
case "parameter-tampering" -> "40008";
case "SOAP XML Injection" -> "90029";
default -> throw new RuntimeException("No policy id found for: " + policyName);
};
}

public void enableAllPassiveScanners() throws Exception {
Expand Down Expand Up @@ -464,7 +430,7 @@ public void performActiveAttack(String url, String policy) throws Exception {
scanId = ((ApiResponseElement) response).getValue();
while (true) {
progress = Integer.parseInt(((ApiResponseElement) this.clientApi.ascan.status(scanId)).getValue());
LOGGER.info("Dynamic scan in progress : " + progress + "%");
LOGGER.info("Dynamic scan in progress : {}%", progress);
if (progress == 100) {
break;
}
Expand Down