Skip to content

Commit 3a975c8

Browse files
committed
Address potential classloader performance issues
Signed-off-by: kingthorin <kingthorin@users.noreply.github.com>
1 parent 8a7190b commit 3a975c8

42 files changed

Lines changed: 230 additions & 179 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1616
- Add cautionary note to help and readme.
1717
- Maintenance and documentation changes.
1818
- Active and passive READMEs to include lastest JS script examples.
19+
- Reduce usage of fully qualified objects in loops or main methods to address potential classloader performance issues, in JavaScript scripts (Issue 9187).
1920

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

2527
### Removed
2628
- Links to videos which no longer exist.

active/OpenModelContextProtocolServer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ var ScanRuleMetadata = Java.type(
55
"org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata"
66
);
77
var CommonAlertTag = Java.type("org.zaproxy.addon.commonlib.CommonAlertTag");
8+
var HttpClientURI = Java.type("org.apache.commons.httpclient.URI");
89

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

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

authentication/DjangoAuthentication.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010
* Every request made by this script is logged separately to the History tab.
1111
*/
1212

13-
function authenticate(helper, paramsValues, credentials) {
14-
var AuthenticationHelper = Java.type(
15-
"org.zaproxy.zap.authentication.AuthenticationHelper"
16-
);
17-
var HttpRequestHeader = Java.type(
18-
"org.parosproxy.paros.network.HttpRequestHeader"
19-
);
20-
var HttpHeader = Java.type("org.parosproxy.paros.network.HttpHeader");
21-
var URI = Java.type("org.apache.commons.httpclient.URI");
13+
var AuthenticationHelper = Java.type(
14+
"org.zaproxy.zap.authentication.AuthenticationHelper"
15+
);
16+
var HttpRequestHeader = Java.type(
17+
"org.parosproxy.paros.network.HttpRequestHeader"
18+
);
19+
var HttpHeader = Java.type("org.parosproxy.paros.network.HttpHeader");
20+
var URI = Java.type("org.apache.commons.httpclient.URI");
2221

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

extender/ZAP onEvent Handler.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// A script which listens for events generated by the ProxyListenerLogEventPublisher.
22
// You can change this to listen for events generated by any other event publisher
33

4+
const ZAP = Java.type("org.zaproxy.zap.ZAP");
5+
46
var consumer;
57

68
function install(helper) {
@@ -31,12 +33,12 @@ function install(helper) {
3133
},
3234
});
3335

34-
org.zaproxy.zap.ZAP.getEventBus().registerConsumer(
36+
ZAP.getEventBus().registerConsumer(
3537
consumer,
3638
"org.parosproxy.paros.extension.history.ProxyListenerLogEventPublisher"
3739
);
3840
}
3941

4042
function uninstall(helper) {
41-
org.zaproxy.zap.ZAP.getEventBus().unregisterConsumer(consumer);
43+
ZAP.getEventBus().unregisterConsumer(consumer);
4244
}

extender/arpSyndicateSubdomainDiscovery.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const HistoryReference = Java.type(
1010
const HttpSender = Java.type("org.parosproxy.paros.network.HttpSender");
1111
const HttpMessage = Java.type("org.parosproxy.paros.network.HttpMessage");
1212
const URI = Java.type("org.apache.commons.httpclient.URI");
13+
const ZAP = Java.type("org.zaproxy.zap.ZAP");
1314
const requestedSubdomains = [];
1415
const sender = new HttpSender(HttpSender.MANUAL_REQUEST_INITIATOR);
1516

@@ -58,12 +59,12 @@ function consumer(event) {
5859
}
5960

6061
function install(helper) {
61-
org.zaproxy.zap.ZAP.getEventBus().registerConsumer(
62+
ZAP.getEventBus().registerConsumer(
6263
consumer,
6364
"org.parosproxy.paros.model.SiteMapEventPublisher"
6465
);
6566
}
6667

6768
function uninstall(helper) {
68-
org.zaproxy.zap.ZAP.getEventBus().unregisterConsumer(consumer);
69+
ZAP.getEventBus().unregisterConsumer(consumer);
6970
}

httpfuzzerprocessor/addCacheBusting.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1+
const HtmlParameter = Java.type("org.parosproxy.paros.network.HtmlParameter");
2+
const HtmlParameterType = Java.type(
3+
"org.parosproxy.paros.network.HtmlParameter.Type"
4+
);
5+
const URL_TYPE = HtmlParameterType.url;
6+
17
function processMessage(utils, message) {
28
var cbValue = "" + Math.floor(Math.random() * 10000);
39
setCacheBusting(message, cbValue);
410
message.getRequestHeader().setHeader("X-Cache-Busting", cbValue);
511
}
612

713
function setCacheBusting(message, cbValue) {
8-
var HtmlParameter = Java.type("org.parosproxy.paros.network.HtmlParameter");
9-
var URL_TYPE = org.parosproxy.paros.network.HtmlParameter.Type.url;
1014
var params = message.getUrlParams();
1115
var newParam = new HtmlParameter(
1216
URL_TYPE,

httpfuzzerprocessor/add_msgs_sites_tree.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// A Fuzzer HTTP Processor script that allows to populate the Sites tree
22
// with messages sent by the fuzzer (by default the fuzz result/messages
33
// are not shown in the Fuzzer tab).
4+
const HistoryReference = Java.type(
5+
"org.parosproxy.paros.model.HistoryReference"
6+
);
7+
const EventQueue = Java.type("java.awt.EventQueue");
48

59
var session = model.getSession();
610

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

httpsender/Alert on HTTP Response Code Errors.js

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,17 @@
22
// By default it will raise 'Info' level alerts for Client Errors (4xx) (apart from 404s) and 'Low' Level alerts for Server Errors (5xx)
33
// But it can be easily changed.
44

5-
var Pattern = Java.type("java.util.regex.Pattern");
5+
const Integer = Java.type("java.lang.Integer");
6+
const Pattern = Java.type("java.util.regex.Pattern");
7+
8+
const Alert = Java.type("org.parosproxy.paros.core.scanner.Alert");
9+
const ExtensionAlert = Java.type(
10+
"org.zaproxy.zap.extension.alert.ExtensionAlert"
11+
);
12+
const HistoryReference = Java.type(
13+
"org.parosproxy.paros.model.HistoryReference"
14+
);
15+
616
pluginid = 100000; // https://github.com/zaproxy/zaproxy/blob/main/docs/scanners.md
717

818
function sendingRequest(msg, initiator, helper) {
@@ -16,7 +26,7 @@ function responseReceived(msg, initiator, helper) {
1626
}
1727
var extensionAlert = control
1828
.getExtensionLoader()
19-
.getExtension(org.zaproxy.zap.extension.alert.ExtensionAlert.NAME);
29+
.getExtension(ExtensionAlert.NAME);
2030
if (extensionAlert != null) {
2131
var code = msg.getResponseHeader().getStatusCode();
2232
if (code < 400 || code >= 600 || code == 404) {
@@ -30,17 +40,12 @@ function responseReceived(msg, initiator, helper) {
3040
title = "A Server Error response code was returned by the server";
3141
}
3242
// CONFIDENCE_HIGH = 3 (we can be pretty sure we're right)
33-
var alert = new org.parosproxy.paros.core.scanner.Alert(
34-
pluginid,
35-
risk,
36-
3,
37-
title
38-
);
43+
var alert = new Alert(pluginid, risk, 3, title);
3944
var ref = msg.getHistoryRef();
4045
if (
4146
ref != null &&
42-
org.parosproxy.paros.model.HistoryReference.getTemporaryTypes().contains(
43-
java.lang.Integer.valueOf(ref.getHistoryType())
47+
HistoryReference.getTemporaryTypes().contains(
48+
Integer.valueOf(ref.getHistoryType())
4449
)
4550
) {
4651
// Dont use temporary types as they will get deleted
@@ -78,11 +83,7 @@ function responseReceived(msg, initiator, helper) {
7883
type = 15; // User - fallback
7984
break;
8085
}
81-
ref = new org.parosproxy.paros.model.HistoryReference(
82-
model.getSession(),
83-
type,
84-
msg
85-
);
86+
ref = new HistoryReference(model.getSession(), type, msg);
8687
}
8788
alert.setMessage(msg);
8889
alert.setUri(msg.getRequestHeader().getURI().toString());
@@ -93,9 +94,7 @@ function responseReceived(msg, initiator, helper) {
9394
"This may indicate that the application is failing to handle unexpected input correctly.\n" +
9495
"Raised by the 'Alert on HTTP Response Code Error' script"
9596
);
96-
// Use a regex to extract the evidence from the response header
97-
var regex = new RegExp("^HTTP.*" + code);
98-
alert.setEvidence(msg.getResponseHeader().toString().match(regex));
97+
alert.setEvidence(code.toString());
9998
alert.setCweId(388); // CWE CATEGORY: Error Handling
10099
alert.setWascId(20); // WASC Improper Input Handling
101100
extensionAlert.alertFound(alert, ref);

httpsender/Alert on Unexpected Content Types.js

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,22 @@
22
// By default it will raise 'Low' level alerts for content types that are not expected to be returned by APIs.
33
// But it can be easily changed.
44

5-
var Pattern = Java.type("java.util.regex.Pattern");
5+
const Integer = Java.type("java.lang.Integer");
6+
const Pattern = Java.type("java.util.regex.Pattern");
67

7-
var pluginid = 100001; // https://github.com/zaproxy/zaproxy/blob/main/docs/scanners.md
8+
const Alert = Java.type("org.parosproxy.paros.core.scanner.Alert");
9+
const ExtensionAlert = Java.type(
10+
"org.zaproxy.zap.extension.alert.ExtensionAlert"
11+
);
12+
const HistoryReference = Java.type(
13+
"org.parosproxy.paros.model.HistoryReference"
14+
);
815

916
var extensionAlert = control
1017
.getExtensionLoader()
11-
.getExtension(org.zaproxy.zap.extension.alert.ExtensionAlert.NAME);
18+
.getExtension(ExtensionAlert.NAME);
19+
20+
var pluginid = 100001; // https://github.com/zaproxy/zaproxy/blob/main/docs/scanners.md
1221

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

@@ -23,6 +32,7 @@ function responseReceived(msg, initiator, helper) {
2332
// Not of interest.
2433
return;
2534
}
35+
2636
if (extensionAlert != null) {
2737
var ctype = msg.getResponseHeader().getHeader("Content-Type");
2838
if (ctype != null) {
@@ -38,17 +48,12 @@ function responseReceived(msg, initiator, helper) {
3848
var risk = 1; // Low
3949
var title = "Unexpected Content-Type was returned";
4050
// CONFIDENCE_HIGH = 3 (we can be pretty sure we're right)
41-
var alert = new org.parosproxy.paros.core.scanner.Alert(
42-
pluginid,
43-
risk,
44-
3,
45-
title
46-
);
51+
var alert = new Alert(pluginid, risk, 3, title);
4752
var ref = msg.getHistoryRef();
4853
if (
4954
ref != null &&
50-
org.parosproxy.paros.model.HistoryReference.getTemporaryTypes().contains(
51-
java.lang.Integer.valueOf(ref.getHistoryType())
55+
HistoryReference.getTemporaryTypes().contains(
56+
Integer.valueOf(ref.getHistoryType())
5257
)
5358
) {
5459
// Dont use temporary types as they will get deleted
@@ -86,11 +91,7 @@ function responseReceived(msg, initiator, helper) {
8691
type = 15; // User - fallback
8792
break;
8893
}
89-
ref = new org.parosproxy.paros.model.HistoryReference(
90-
model.getSession(),
91-
type,
92-
msg
93-
);
94+
ref = new HistoryReference(model.getSession(), type, msg);
9495
}
9596
alert.setMessage(msg);
9697
alert.setUri(msg.getRequestHeader().getURI().toString());

httpsender/Capture and Replace Anti CSRF Token.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99

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

12+
var ScriptVars = Java.type("org.zaproxy.zap.extension.script.ScriptVars");
13+
var HtmlParameterType = Java.type(
14+
"org.parosproxy.paros.network.HtmlParameter.Type"
15+
);
16+
var formParamType = HtmlParameterType.form;
17+
var urlParamType = HtmlParameterType.url;
18+
var cookieParamType = HtmlParameterType.cookie;
19+
1220
// Regular expression for the request URI that returns CSRF token in response.
1321
// 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.
1422
// REPLACE the value with RegEx for your application.
@@ -27,17 +35,13 @@ var matcherGroupNumber = 1;
2735
// REPLACE the value with csrf token name for your application.
2836
var antiCsrfTokenName = "secureToken";
2937

30-
var formParamType = org.parosproxy.paros.network.HtmlParameter.Type.form;
31-
var urlParamType = org.parosproxy.paros.network.HtmlParameter.Type.url;
32-
var cookieParamType = org.parosproxy.paros.network.HtmlParameter.Type.cookie;
33-
3438
// HTML parameter types to look for antiCsrfTokenName and replace with new anti CSRF Token value.
3539
// Comma separated list of HTML parameter types.
3640
// Supported values: formParamType, urlParamType, cookieParamType.
3741
// REPLACE the value with the params to scan for CSRF token and replace with latest vaule.
3842
var parameterTypesList = [formParamType, urlParamType, cookieParamType];
3943

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

4246
function sendingRequest(msg, initiator, helper) {
4347
// print('sendingRequest called for url=' + msg.getRequestHeader().getURI().toString())
@@ -83,7 +87,7 @@ function responseReceived(msg, initiator, helper) {
8387
.match(csrfTokenValueRegEx);
8488
if (csrfTokenValue != null && csrfTokenValue.length > matcherGroupNumber) {
8589
print("Latest CSRF Token value: " + csrfTokenValue[matcherGroupNumber]);
86-
org.zaproxy.zap.extension.script.ScriptVars.setGlobalVar(
90+
ScriptVars.setGlobalVar(
8791
"anti.csrf.token.value",
8892
csrfTokenValue[matcherGroupNumber]
8993
);
@@ -98,10 +102,7 @@ function modifyParams(params) {
98102
// Check if the url parameters has the antiCsrfTokenName in it.
99103
if (param.getName().equals(antiCsrfTokenName)) {
100104
var secureTokenValue = param.getValue();
101-
var antiCsrfTokenValue =
102-
org.zaproxy.zap.extension.script.ScriptVars.getGlobalVar(
103-
"anti.csrf.token.value"
104-
);
105+
var antiCsrfTokenValue = ScriptVars.getGlobalVar("anti.csrf.token.value");
105106
// Check for the value of AntiCsrfTokenName in the existing request with the latest value captured from previous requests.
106107
if (
107108
antiCsrfTokenValue != null &&

0 commit comments

Comments
 (0)