Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ gradle-app.setting
*.classpath
*.project
*.settings
*.idea
/bin

33 changes: 21 additions & 12 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,24 @@ plugins {
id("org.zaproxy.common")
}

description = "A template for a 3rd party ZAP Java add-on."
description = (
"Includes request and response data in XML reports and provides the ability " +
"to upload reports directly to a Software Risk Manager server"
)

zapAddOn {
addOnId.set("addonjava")
addOnName.set("A Template Java Add-on")
addOnId.set("srm")
addOnName.set("Software Risk Manager Extension")
zapVersion.set("2.16.0")
addOnStatus.set(AddOnStatus.ALPHA)

releaseLink.set("https://github.com/youruser/javaexample/compare/v@[email protected]@CURRENT_VERSION@")
unreleasedLink.set("https://github.com/youruser/javaexample/compare/v@[email protected]")

manifest {
author.set("ZAP Dev Team")
url.set("https://www.zaproxy.org/docs/desktop/addons/addonjava/")
repo.set("https://github.com/zaproxy/addon-java")
author.set("Black Duck, Inc.")
url.set("https://www.zaproxy.org/docs/desktop/addons/software-risk-manager/")
repo.set("https://github.com/codedx/srm-zap-extension/")
changesFile.set(tasks.named<ConvertMarkdownToHtml>("generateManifestChanges").flatMap { it.html })

dependencies {
Expand All @@ -35,18 +38,24 @@ zapAddOn {
}
}

dependencies {
compileOnly("org.zaproxy.addon:commonlib:1.36.0")
implementation("org.apache.httpcomponents:httpmime:4.5.13")
implementation("com.googlecode.json-simple:json-simple:1.1.1") {
// Not needed.
exclude(group = "junit")
}
}

java {
val javaVersion = JavaVersion.VERSION_17
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
}

spotless {
kotlinGradle {
ktlint()
java {
// Don't check license nor format/style, 3rd-party add-on.
clearSteps()
}
}

dependencies {
compileOnly("org.zaproxy.addon:commonlib:1.36.0")
}
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version=0.1.0
version=2025.9.0
release=false
17 changes: 17 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
}

dependencyResolutionManagement {
versionCatalogs {
create("libs") {
version("log4j", "2.24.2")
library("log4j-core", "org.apache.logging.log4j", "log4j-core").versionRef("log4j")
library("log4j-slf4j", "org.apache.logging.log4j", "log4j-slf4j-impl").versionRef("log4j")
library("log4j-slf4j2", "org.apache.logging.log4j", "log4j-slf4j2-impl").versionRef("log4j")
}
}
}
plugins {
id("org.zaproxy.common.settings") version "0.5.0"
id("com.diffplug.spotless") version "6.25.0" apply false
Expand Down
104 changes: 104 additions & 0 deletions src/main/java/com/github/srm/zap/srm/ExtensionAlertHttp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2025 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 com.github.srm.zap.srm;

import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.core.scanner.Alert;
import org.parosproxy.paros.model.SiteNode;
import org.parosproxy.paros.network.HttpMessage;

public class ExtensionAlertHttp {

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

public ExtensionAlertHttp() {}

public String getXml(SiteNode site) {
StringBuilder xml = new StringBuilder();
xml.append("<alerts>");
List<Alert> alerts = site.getAlerts();
for (Alert alert : alerts) {
if (alert.getConfidence() != Alert.CONFIDENCE_FALSE_POSITIVE) {
String urlParamXML = getUrlParamXML(alert);
xml.append(alert.toPluginXML(urlParamXML));
}
}
xml.append("</alerts>");
return xml.toString();
}

private String getHTML(Alert alert) {
// gets HttpMessage request and response data from each alert and removes illegal and
// special characters
StringBuilder httpMessage = new StringBuilder();

HttpMessage message = alert.getMessage();

if (message == null) {
LOGGER.warn(Constant.messages.getString("srm.error.httpMessage", alert.getAlertId()));
return httpMessage.toString();
}

String requestHeader = message.getRequestHeader().toString();
String requestBody = message.getRequestBody().toString();
String responseHeader = message.getResponseHeader().toString();
String responseBody = message.getResponseBody().toString();

httpMessage.append("<requestdata>");
httpMessage.append(ReportGenerator.entityEncode(requestHeader));
httpMessage.append(ReportGenerator.entityEncode(requestBody));
httpMessage.append("\n</requestdata>\n");
httpMessage.append("<responsedata>");
httpMessage.append(ReportGenerator.entityEncode(responseHeader));
httpMessage.append(ReportGenerator.entityEncode(responseBody));
httpMessage.append("\n</responsedata>\n");

return httpMessage.toString();
}

public String getUrlParamXML(Alert alert) {

String uri = alert.getUri();
String param = alert.getParam();
String attack = alert.getAttack();
String otherInfo = alert.getOtherInfo();
String evidence = alert.getEvidence();

StringBuilder sb = new StringBuilder(200); // ZAP: Changed the type to StringBuilder.
sb.append(getHTML(alert));
sb.append(" <uri>").append(ReportGenerator.entityEncode(uri)).append("</uri>\r\n");
sb.append(" <param>").append(ReportGenerator.entityEncode(param)).append("</param>\r\n");
sb.append(" <attack>")
.append(ReportGenerator.entityEncode(attack))
.append("</attack>\r\n");
if (evidence != null && evidence.length() > 0) {
sb.append(" <evidence>")
.append(ReportGenerator.entityEncode(evidence))
.append("</evidence>\r\n");
}
sb.append(" <otherinfo>")
.append(ReportGenerator.entityEncode(otherInfo))
.append("</otherinfo>\r\n");
return sb.toString();
}
}
Loading
Loading