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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Add cautionary note to help and readme.
- Maintenance and documentation changes.
- Active and passive READMEs to include lastest JS script examples.
- Reduce usage of fully qualified objects in loops or main methods to address potential classloader performance issues, in JavaScript scripts (Issue 9187).

### Fixed
- The following scripts were not being loaded as scan rules:
- active/SSTI.js
- passive/Mutliple Security Header Check.js
- Updated Alert_on_HTTP_Response_Code_Errors.js to work with GraalVM JavaScript engine.

### Removed
- Links to videos which no longer exist.
Expand Down
2 changes: 1 addition & 1 deletion active/OpenModelContextProtocolServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var ScanRuleMetadata = Java.type(
"org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata"
);
var CommonAlertTag = Java.type("org.zaproxy.addon.commonlib.CommonAlertTag");
var HttpClientURI = Java.type("org.apache.commons.httpclient.URI");

function getMetadata() {
return ScanRuleMetadata.fromYaml(`
Expand Down Expand Up @@ -131,7 +132,6 @@ function testMcpEndpoint(as, originalMsg, testUrl, payload) {
var requestHeader = testMsg.getRequestHeader();

// Set the new URL using Apache Commons HttpClient URI
var HttpClientURI = Java.type("org.apache.commons.httpclient.URI");
requestHeader.setURI(new HttpClientURI(testUrl, false));
requestHeader.setMethod("POST");

Expand Down
18 changes: 9 additions & 9 deletions authentication/DjangoAuthentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
* Every request made by this script is logged separately to the History tab.
*/

function authenticate(helper, paramsValues, credentials) {
var AuthenticationHelper = Java.type(
"org.zaproxy.zap.authentication.AuthenticationHelper"
);
var HttpRequestHeader = Java.type(
"org.parosproxy.paros.network.HttpRequestHeader"
);
var HttpHeader = Java.type("org.parosproxy.paros.network.HttpHeader");
var URI = Java.type("org.apache.commons.httpclient.URI");
var AuthenticationHelper = Java.type(
"org.zaproxy.zap.authentication.AuthenticationHelper"
);
var HttpRequestHeader = Java.type(
"org.parosproxy.paros.network.HttpRequestHeader"
);
var HttpHeader = Java.type("org.parosproxy.paros.network.HttpHeader");
var URI = Java.type("org.apache.commons.httpclient.URI");

function authenticate(helper, paramsValues, credentials) {
var targetURL = paramsValues.get("Target URL");
var baseURL = targetURL.match(/^(.+?[^\/:](?=[?\/]|$))/i)[1];

Expand Down
6 changes: 4 additions & 2 deletions extender/ZAP onEvent Handler.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// A script which listens for events generated by the ProxyListenerLogEventPublisher.
// You can change this to listen for events generated by any other event publisher

const ZAP = Java.type("org.zaproxy.zap.ZAP");

var consumer;

function install(helper) {
Expand Down Expand Up @@ -31,12 +33,12 @@ function install(helper) {
},
});

org.zaproxy.zap.ZAP.getEventBus().registerConsumer(
ZAP.getEventBus().registerConsumer(
consumer,
"org.parosproxy.paros.extension.history.ProxyListenerLogEventPublisher"
);
}

function uninstall(helper) {
org.zaproxy.zap.ZAP.getEventBus().unregisterConsumer(consumer);
ZAP.getEventBus().unregisterConsumer(consumer);
}
5 changes: 3 additions & 2 deletions extender/arpSyndicateSubdomainDiscovery.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const HistoryReference = Java.type(
const HttpSender = Java.type("org.parosproxy.paros.network.HttpSender");
const HttpMessage = Java.type("org.parosproxy.paros.network.HttpMessage");
const URI = Java.type("org.apache.commons.httpclient.URI");
const ZAP = Java.type("org.zaproxy.zap.ZAP");
const requestedSubdomains = [];
const sender = new HttpSender(HttpSender.MANUAL_REQUEST_INITIATOR);

Expand Down Expand Up @@ -58,12 +59,12 @@ function consumer(event) {
}

function install(helper) {
org.zaproxy.zap.ZAP.getEventBus().registerConsumer(
ZAP.getEventBus().registerConsumer(
consumer,
"org.parosproxy.paros.model.SiteMapEventPublisher"
);
}

function uninstall(helper) {
org.zaproxy.zap.ZAP.getEventBus().unregisterConsumer(consumer);
ZAP.getEventBus().unregisterConsumer(consumer);
}
8 changes: 6 additions & 2 deletions httpfuzzerprocessor/addCacheBusting.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
const HtmlParameter = Java.type("org.parosproxy.paros.network.HtmlParameter");
const HtmlParameterType = Java.type(
"org.parosproxy.paros.network.HtmlParameter.Type"
);
const URL_TYPE = HtmlParameterType.url;

function processMessage(utils, message) {
var cbValue = "" + Math.floor(Math.random() * 10000);
setCacheBusting(message, cbValue);
message.getRequestHeader().setHeader("X-Cache-Busting", cbValue);
}

function setCacheBusting(message, cbValue) {
var HtmlParameter = Java.type("org.parosproxy.paros.network.HtmlParameter");
var URL_TYPE = org.parosproxy.paros.network.HtmlParameter.Type.url;
var params = message.getUrlParams();
var newParam = new HtmlParameter(
URL_TYPE,
Expand Down
8 changes: 6 additions & 2 deletions httpfuzzerprocessor/add_msgs_sites_tree.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// A Fuzzer HTTP Processor script that allows to populate the Sites tree
// with messages sent by the fuzzer (by default the fuzz result/messages
// are not shown in the Fuzzer tab).
const HistoryReference = Java.type(
"org.parosproxy.paros.model.HistoryReference"
);
const EventQueue = Java.type("java.awt.EventQueue");

var session = model.getSession();

Expand All @@ -11,9 +15,9 @@ function processResult(utils, fuzzResult) {
// The type 15 indicates that the message was sent by the user.
// Refer to the HistoryReference for more details on the available types.
// Persist the message to the session.
var ref = new org.parosproxy.paros.model.HistoryReference(session, 15, msg);
var ref = new HistoryReference(session, 15, msg);
// Add the message to Sites tree.
java.awt.EventQueue.invokeLater(function () {
EventQueue.invokeLater(function () {
session.getSiteTree().addPath(ref, msg);
});

Expand Down
35 changes: 17 additions & 18 deletions httpsender/Alert on HTTP Response Code Errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@
// By default it will raise 'Info' level alerts for Client Errors (4xx) (apart from 404s) and 'Low' Level alerts for Server Errors (5xx)
// But it can be easily changed.

var Pattern = Java.type("java.util.regex.Pattern");
const Integer = Java.type("java.lang.Integer");
const Pattern = Java.type("java.util.regex.Pattern");

const Alert = Java.type("org.parosproxy.paros.core.scanner.Alert");
const ExtensionAlert = Java.type(
"org.zaproxy.zap.extension.alert.ExtensionAlert"
);
const HistoryReference = Java.type(
"org.parosproxy.paros.model.HistoryReference"
);

pluginid = 100000; // https://github.com/zaproxy/zaproxy/blob/main/docs/scanners.md

function sendingRequest(msg, initiator, helper) {
Expand All @@ -16,7 +26,7 @@ function responseReceived(msg, initiator, helper) {
}
var extensionAlert = control
.getExtensionLoader()
.getExtension(org.zaproxy.zap.extension.alert.ExtensionAlert.NAME);
.getExtension(ExtensionAlert.NAME);
if (extensionAlert != null) {
var code = msg.getResponseHeader().getStatusCode();
if (code < 400 || code >= 600 || code == 404) {
Expand All @@ -30,17 +40,12 @@ function responseReceived(msg, initiator, helper) {
title = "A Server Error response code was returned by the server";
}
// CONFIDENCE_HIGH = 3 (we can be pretty sure we're right)
var alert = new org.parosproxy.paros.core.scanner.Alert(
pluginid,
risk,
3,
title
);
var alert = new Alert(pluginid, risk, 3, title);
var ref = msg.getHistoryRef();
if (
ref != null &&
org.parosproxy.paros.model.HistoryReference.getTemporaryTypes().contains(
java.lang.Integer.valueOf(ref.getHistoryType())
HistoryReference.getTemporaryTypes().contains(
Integer.valueOf(ref.getHistoryType())
)
) {
// Dont use temporary types as they will get deleted
Expand Down Expand Up @@ -78,11 +83,7 @@ function responseReceived(msg, initiator, helper) {
type = 15; // User - fallback
break;
}
ref = new org.parosproxy.paros.model.HistoryReference(
model.getSession(),
type,
msg
);
ref = new HistoryReference(model.getSession(), type, msg);
}
alert.setMessage(msg);
alert.setUri(msg.getRequestHeader().getURI().toString());
Expand All @@ -93,9 +94,7 @@ function responseReceived(msg, initiator, helper) {
"This may indicate that the application is failing to handle unexpected input correctly.\n" +
"Raised by the 'Alert on HTTP Response Code Error' script"
);
// Use a regex to extract the evidence from the response header
var regex = new RegExp("^HTTP.*" + code);
Comment thread
thc202 marked this conversation as resolved.
alert.setEvidence(msg.getResponseHeader().toString().match(regex));
alert.setEvidence(code.toString());
Comment thread
thc202 marked this conversation as resolved.
alert.setCweId(388); // CWE CATEGORY: Error Handling
alert.setWascId(20); // WASC Improper Input Handling
extensionAlert.alertFound(alert, ref);
Expand Down
33 changes: 17 additions & 16 deletions httpsender/Alert on Unexpected Content Types.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@
// By default it will raise 'Low' level alerts for content types that are not expected to be returned by APIs.
// But it can be easily changed.

var Pattern = Java.type("java.util.regex.Pattern");
const Integer = Java.type("java.lang.Integer");
const Pattern = Java.type("java.util.regex.Pattern");

var pluginid = 100001; // https://github.com/zaproxy/zaproxy/blob/main/docs/scanners.md
const Alert = Java.type("org.parosproxy.paros.core.scanner.Alert");
const ExtensionAlert = Java.type(
"org.zaproxy.zap.extension.alert.ExtensionAlert"
);
const HistoryReference = Java.type(
"org.parosproxy.paros.model.HistoryReference"
);

var extensionAlert = control
.getExtensionLoader()
.getExtension(org.zaproxy.zap.extension.alert.ExtensionAlert.NAME);
.getExtension(ExtensionAlert.NAME);

var pluginid = 100001; // https://github.com/zaproxy/zaproxy/blob/main/docs/scanners.md

var expectedTypes = ["application/octet-stream", "text/plain"];

Expand All @@ -23,6 +32,7 @@ function responseReceived(msg, initiator, helper) {
// Not of interest.
return;
}

if (extensionAlert != null) {
var ctype = msg.getResponseHeader().getHeader("Content-Type");
if (ctype != null) {
Expand All @@ -38,17 +48,12 @@ function responseReceived(msg, initiator, helper) {
var risk = 1; // Low
var title = "Unexpected Content-Type was returned";
// CONFIDENCE_HIGH = 3 (we can be pretty sure we're right)
var alert = new org.parosproxy.paros.core.scanner.Alert(
pluginid,
risk,
3,
title
);
var alert = new Alert(pluginid, risk, 3, title);
var ref = msg.getHistoryRef();
if (
ref != null &&
org.parosproxy.paros.model.HistoryReference.getTemporaryTypes().contains(
java.lang.Integer.valueOf(ref.getHistoryType())
HistoryReference.getTemporaryTypes().contains(
Integer.valueOf(ref.getHistoryType())
)
) {
// Dont use temporary types as they will get deleted
Expand Down Expand Up @@ -86,11 +91,7 @@ function responseReceived(msg, initiator, helper) {
type = 15; // User - fallback
break;
}
ref = new org.parosproxy.paros.model.HistoryReference(
model.getSession(),
type,
msg
);
ref = new HistoryReference(model.getSession(), type, msg);
}
alert.setMessage(msg);
alert.setUri(msg.getRequestHeader().getURI().toString());
Expand Down
21 changes: 11 additions & 10 deletions httpsender/Capture and Replace Anti CSRF Token.js
Comment thread
thc202 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@

// REPLACE the values for the variables as applicable to your application.

var ScriptVars = Java.type("org.zaproxy.zap.extension.script.ScriptVars");
var HtmlParameterType = Java.type(
"org.parosproxy.paros.network.HtmlParameter.Type"
);
var formParamType = HtmlParameterType.form;
var urlParamType = HtmlParameterType.url;
var cookieParamType = HtmlParameterType.cookie;

// Regular expression for the request URI that returns CSRF token in response.
// If the application under test returns csrf token in every response or in response to more than request, set a generic regex that matches with host name or domain name of the application.
// REPLACE the value with RegEx for your application.
Expand All @@ -27,17 +35,13 @@ var matcherGroupNumber = 1;
// REPLACE the value with csrf token name for your application.
var antiCsrfTokenName = "secureToken";

var formParamType = org.parosproxy.paros.network.HtmlParameter.Type.form;
var urlParamType = org.parosproxy.paros.network.HtmlParameter.Type.url;
var cookieParamType = org.parosproxy.paros.network.HtmlParameter.Type.cookie;

// HTML parameter types to look for antiCsrfTokenName and replace with new anti CSRF Token value.
// Comma separated list of HTML parameter types.
// Supported values: formParamType, urlParamType, cookieParamType.
// REPLACE the value with the params to scan for CSRF token and replace with latest vaule.
var parameterTypesList = [formParamType, urlParamType, cookieParamType];

//print ("AntiCsrfTokenValue: " + org.zaproxy.zap.extension.script.ScriptVars.getGlobalVar("anti.csrf.token.value"))
//print("AntiCsrfTokenValue: " + ScriptVars.getGlobalVar("anti.csrf.token.value"));

function sendingRequest(msg, initiator, helper) {
// print('sendingRequest called for url=' + msg.getRequestHeader().getURI().toString())
Expand Down Expand Up @@ -83,7 +87,7 @@ function responseReceived(msg, initiator, helper) {
.match(csrfTokenValueRegEx);
if (csrfTokenValue != null && csrfTokenValue.length > matcherGroupNumber) {
print("Latest CSRF Token value: " + csrfTokenValue[matcherGroupNumber]);
org.zaproxy.zap.extension.script.ScriptVars.setGlobalVar(
ScriptVars.setGlobalVar(
"anti.csrf.token.value",
csrfTokenValue[matcherGroupNumber]
);
Expand All @@ -98,10 +102,7 @@ function modifyParams(params) {
// Check if the url parameters has the antiCsrfTokenName in it.
if (param.getName().equals(antiCsrfTokenName)) {
var secureTokenValue = param.getValue();
var antiCsrfTokenValue =
org.zaproxy.zap.extension.script.ScriptVars.getGlobalVar(
"anti.csrf.token.value"
);
var antiCsrfTokenValue = ScriptVars.getGlobalVar("anti.csrf.token.value");
// Check for the value of AntiCsrfTokenName in the existing request with the latest value captured from previous requests.
if (
antiCsrfTokenValue != null &&
Expand Down
5 changes: 4 additions & 1 deletion httpsender/greenbone-maintain-auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ function isStaticUrl(url) {
return false;
}

var COOKIE_TYPE = org.parosproxy.paros.network.HtmlParameter.Type.cookie;
var HtmlParameterType = Java.type(
"org.parosproxy.paros.network.HtmlParameter.Type"
);
var COOKIE_TYPE = HtmlParameterType.cookie;
var ScriptVars = Java.type("org.zaproxy.zap.extension.script.ScriptVars");
var HtmlParameter = Java.type("org.parosproxy.paros.network.HtmlParameter");
var HttpSender = Java.type("org.parosproxy.paros.network.HttpSender");
Expand Down
10 changes: 5 additions & 5 deletions httpsender/inject_js_in_html_page.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@

FILE = "/tmp/test.js";

function loadScriptFromFile(file) {
var Files = Java.type("java.nio.file.Files");
var Paths = Java.type("java.nio.file.Paths");
var String = Java.type("java.lang.String");
var Files = Java.type("java.nio.file.Files");
var Paths = Java.type("java.nio.file.Paths");
var JString = Java.type("java.lang.String");

function loadScriptFromFile(file) {
var filePath = Paths.get(file);
return new String(Files.readAllBytes(filePath), "UTF-8");
return new JString(Files.readAllBytes(filePath), "UTF-8");
}

function sendingRequest(msg, initiator, helper) {}
Expand Down
5 changes: 4 additions & 1 deletion httpsender/keep-cookies-going.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ function logger() {

var ScriptVars = Java.type("org.zaproxy.zap.extension.script.ScriptVars");
var HtmlParameter = Java.type("org.parosproxy.paros.network.HtmlParameter");
var COOKIE_TYPE = org.parosproxy.paros.network.HtmlParameter.Type.cookie;
var HtmlParameterType = Java.type(
"org.parosproxy.paros.network.HtmlParameter.Type"
);
var COOKIE_TYPE = HtmlParameterType.cookie;

function sendingRequest(msg, initiator, helper) {
var headers = msg.getRequestHeader();
Expand Down
5 changes: 4 additions & 1 deletion httpsender/maintain-jwt.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ function logger() {
var HttpSender = Java.type("org.parosproxy.paros.network.HttpSender");
var ScriptVars = Java.type("org.zaproxy.zap.extension.script.ScriptVars");
var HtmlParameter = Java.type("org.parosproxy.paros.network.HtmlParameter");
var COOKIE_TYPE = org.parosproxy.paros.network.HtmlParameter.Type.cookie;
var HtmlParameterType = Java.type(
"org.parosproxy.paros.network.HtmlParameter.Type"
);
var COOKIE_TYPE = HtmlParameterType.cookie;

function sendingRequest(msg, initiator, helper) {
if (initiator === HttpSender.AUTHENTICATION_INITIATOR) {
Expand Down
Loading
Loading