Skip to content

Commit

Permalink
Implement getMetadata for some more Passive scripts
Browse files Browse the repository at this point in the history
Update the following scripts to implement the `getMetadata()` function:
- passive/google_api_keys_finder.js
- passive/JavaDisclosure.js
- passive/Report non static sites.js
- passive/RPO.js
- passive/s3.js

Signed-off-by: ricekot <[email protected]>
  • Loading branch information
ricekot committed Jun 12, 2024
1 parent 4e19cd7 commit 16d2c67
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 140 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- passive/find_reflected_params.py
- passive/HUNT.py
- passive/Mutliple Security Header Check.js
- passive/google_api_keys_finder.js
- passive/JavaDisclosure.js
- passive/Report non static sites.js
- passive/RPO.js
- passive/s3.js

## [18] - 2024-01-29
### Added
Expand Down
55 changes: 30 additions & 25 deletions passive/JavaDisclosure.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
//Passive scan for Java error messages containing sensitive information (CWE-209)

function scan(ps, msg, src) {
var alertRisk = 2;
var alertConfidence = 3;
var alertTitle = "Java stack trace disclosure";
var alertDesc = "Java stack trace disclosure (or similar) was found";
var alertSolution =
"Investigate Java stack trace disclosures found in the response, remove or mask as required";
var cweId = 209;
var wascId = 0;
var ScanRuleMetadata = Java.type(
"org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata"
);

function getMetadata() {
return ScanRuleMetadata.fromYaml(`
id: 100035
name: Information Disclosure - Java Stack Trace
description: A Java stack trace was found in the HTTP response body.
solution: >
Catch and handle exceptions properly, avoiding the exposure of stack traces to users.
Configure the web server or application framework to log stack traces instead of displaying them.
risk: medium
confidence: high
cweId: 209 # CWE-209: Generation of Error Message Containing Sensitive Information
wascId: 13 # WASC-13: Information Leakage
status: alpha
codeLink: https://github.com/zaproxy/community-scripts/blob/main/passive/JavaDisclosure.js
helpLink: https://www.zaproxy.org/docs/desktop/addons/community-scripts/
`);
}

function scan(helper, msg, src) {
var re = /springframework|\.java|rootBeanClass/i;

var contentType = msg.getResponseHeader().getHeader("Content-Type");
Expand All @@ -27,21 +40,13 @@ function scan(ps, msg, src) {

var body = msg.getResponseBody().toString();
if (re.test(body)) {
let url = msg.getRequestHeader().getURI().toString();
ps.raiseAlert(
alertRisk,
alertConfidence,
alertTitle,
alertDesc,
url,
"",
"",
body,
alertSolution,
body,
cweId,
wascId,
msg
);
re.lastIndex = 0;
var match = re.exec(body)[0];
helper
.newAlert()
.setEvidence(match)
.setOtherInfo(body)
.setMessage(msg)
.raise();
}
}
56 changes: 31 additions & 25 deletions passive/RPO.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,32 @@
// for more info see http://www.thespanner.co.uk/2014/03/21/rpo/
// *WARNING* this is a Beta version of this detection and may give many false positives!

function scan(ps, msg, src) {
var url = msg.getRequestHeader().getURI().toString();
var alertRisk = 2;
var alertConfidence = 2;
var alertTitle = "Potential Relative Path Overwrite - RPO(beta script)";
var alertDesc = "Potential RPO (Relative Path Overwrite) found ";
var alertSolution =
"Make sure all style sheets are refered by full paths rather than relative paths.";
var ScanRuleMetadata = Java.type(
"org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata"
);

var cweId = 0;
var wascId = 0;
function getMetadata() {
return ScanRuleMetadata.fromYaml(`
id: 100018
name: Relative Path Overwrite
description: >
Potential RPO (Relative Path Overwrite) found.
RPO allows attackers to manipulate URLs to include unintended paths,
potentially leading to the execution of malicious scripts or the disclosure of sensitive information.
solution: >
Use absolute paths in URLs and resources to prevent manipulation.
Validate and sanitize all user inputs that are used to construct URLs.
risk: medium
confidence: medium
cweId: 20 # CWE-20: Improper Input Validation
wascId: 13 # WASC-13: Information Leakage
status: alpha
codeLink: https://github.com/zaproxy/community-scripts/blob/main/passive/RPO.js
helpLink: https://www.zaproxy.org/docs/desktop/addons/community-scripts/
`);
}

function scan(helper, msg, src) {
// regex must appear within /( and )/g
var re = /(href\=\"((?!\/|http|www)).*\.css\")/g;

Expand Down Expand Up @@ -41,21 +56,12 @@ function scan(ps, msg, src) {
while ((comm = re.exec(body))) {
foundRPO.push(comm[0]);
}
ps.raiseAlert(
alertRisk,
alertConfidence,
alertTitle,
alertDesc,
url,
"",
"",
foundRPO.toString(),
alertSolution,
"",
cweId,
wascId,
msg
);
helper
.newAlert()
.setEvidence(foundRPO[0])
.setOtherInfo(`Other instances: ${foundRPO.slice(1).toString()}`)
.setMessage(msg)
.raise();
}
}
}
79 changes: 41 additions & 38 deletions passive/Report non static sites.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,61 @@
// Note that new passive scripts will initially be disabled
// Right click the script in the Scripts tree and select "enable"

var ScanRuleMetadata = Java.type(
"org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata"
);

function getMetadata() {
return ScanRuleMetadata.fromYaml(`
id: 100017
name: Non Static Site Detected
description: >
A query string or form has been detected in the HTTP response body.
This indicates that this may not be a static site.
solution: >
If this is not a static site then ignore or disable this rule.
risk: high
confidence: medium
status: alpha
codeLink: https://github.com/zaproxy/community-scripts/blob/main/passive/Report%20non%20static%20sites.js
helpLink: https://www.zaproxy.org/docs/desktop/addons/community-scripts/
`);
}

/**
* Passively scans an HTTP message. The scan function will be called for
* request/response made via ZAP, actual messages depend on the function
* "appliesToHistoryType", defined below.
*
* @param ps - the PassiveScan parent object that will do all the core interface tasks
* @param helper - the PassiveScan parent object that will do all the core interface tasks
* (i.e.: providing access to Threshold settings, raising alerts, etc.).
* This is an ScriptsPassiveScanner object.
* @param msg - the HTTP Message being scanned. This is an HttpMessage object.
* @param src - the Jericho Source representation of the message being scanned.
*/
function scan(ps, msg, src) {
// Test the request and/or response here
function scan(helper, msg, src) {
if (msg.getRequestHeader().getURI().getEscapedQuery() != null) {
// raiseAlert(risk, int confidence, String name, String description, String uri,
// String param, String attack, String otherInfo, String solution, String evidence,
// int cweId, int wascId, HttpMessage msg)
// risk: 0: info, 1: low, 2: medium, 3: high
// confidence: 0: falsePositive, 1: low, 2: medium, 3: high, 4: confirmed
ps.raiseAlert(
3,
2,
"Non static site (query present)",
"A query string has been detected in one of the sites URLs. This indicates that this might well not be a static site",
msg.getRequestHeader().getURI().toString(),
"",
"",
"",
"If this is not a static site then ignore or disable this script",
msg.getRequestHeader().getURI().getEscapedQuery(),
0,
0,
msg
);
helper
.newAlert()
.setName("Non Static Site Detected (query present)")
.setDescription(
"A query string has been detected in the HTTP response body. This indicates that this may not be a static site."
)
.setEvidence(msg.getRequestHeader().getURI().getEscapedQuery())
.setMessage(msg)
.raise();
}
if (src != null && !src.getFormFields().isEmpty()) {
// There are form fields
ps.raiseAlert(
3,
2,
"Non static site (form present)",
"One or more forms have been detected in the response. This indicates that this might well not be a static site",
msg.getRequestHeader().getURI().toString(),
"",
"",
"",
"If this is not a static site then ignore or disable this script",
src.getFormFields().toString(),
0,
0,
msg
);
helper
.newAlert()
.setName("Non Static Site Detected (form present)")
.setDescription(
"One or more forms have been detected in the response. This indicates that this may not be a static site."
)
.setEvidence(src.getFormFields().toString())
.setMessage(msg)
.raise();
}
}

Expand Down
50 changes: 26 additions & 24 deletions passive/google_api_keys_finder.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,27 @@
* @SkypLabs
*/

function scan(ps, msg, src) {
var alertRisk = 0; // Informational
var alertConfidence = 3; // High
var alertTitle = "Information Disclosure - Google API Keys Found";
var alertDesc = "Google API keys have been found.";
var alertSolution = "Make sure the API key is not overly permissive.";
var cweId = 200; // "Exposure of Sensitive Information to an Unauthorized Actor"
var wascId = 13; // "Information Leakage"
var ScanRuleMetadata = Java.type(
"org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata"
);

function getMetadata() {
return ScanRuleMetadata.fromYaml(`
id: 100034
name: Information Disclosure - Google API Key
description: A Google API Key was found in the HTTP response body.
solution: Ensure the API key is not overly permissive.
risk: info
confidence: high
cweId: 200 # CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
wascId: 13 # WASC-13: Information Leakage
status: alpha
codeLink: https://github.com/zaproxy/community-scripts/blob/main/passive/google_api_keys_finder.js
helpLink: https://www.zaproxy.org/docs/desktop/addons/community-scripts/
`);
}

function scan(helper, msg, src) {
// Regex targeting Google API keys.
// Taken from Table III of "How Bad Can It Git? Characterizing Secret Leakage in Public GitHub Repositories".
// https://www.ndss-symposium.org/ndss-paper/how-bad-can-it-git-characterizing-secret-leakage-in-public-github-repositories/
Expand Down Expand Up @@ -45,21 +57,11 @@ function scan(ps, msg, src) {
foundKeys.push(key[0]);
}

ps.raiseAlert(
alertRisk,
alertConfidence,
alertTitle,
alertDesc,
url,
"",
"",
"The following Google API keys have been found in the page: " +
foundKeys.join(", "), // Other info
alertSolution,
foundKeys[0].toString(), // Evidence
cweId,
wascId,
msg
);
helper
.newAlert()
.setEvidence(foundKeys[0])
.setOtherInfo(`Other instances: ${foundKeys.slice(1).toString()}`)
.setMessage(msg)
.raise();
}
}
54 changes: 26 additions & 28 deletions passive/s3.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
// S3 bucket finder by alishasinghania09@gmail.com

function scan(ps, msg, src) {
// populate some parameters which will be needed if s3 bucket url is present
var alertRisk = 1;
var alertConfidence = 3;
var alertTitle = "s3 Bucket URL";
var alertDesc = "s3 Bucket URL found in response.";
var alertSolution =
"Remove s3 Buckets name from response or make sure the permissions in bucket are configured properly.";
var cweId = 200;
var wascId = 13;
var ScanRuleMetadata = Java.type(
"org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata"
);

function getMetadata() {
return ScanRuleMetadata.fromYaml(`
id: 100035
name: Information Disclosure - Amazon S3 Bucket URL
description: An Amazon S3 bucket URL was found in the HTTP response body.
solution: Remove S3 Bucket names from the response or ensure that the permissions in bucket are configured properly.
risk: low
confidence: high
cweId: 200 # CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
wascId: 13 # WASC-13: Information Leakage
status: alpha
codeLink: https://github.com/zaproxy/community-scripts/blob/main/passive/s3.js
helpLink: https://www.zaproxy.org/docs/desktop/addons/community-scripts/
`);
}

function scan(helper, msg, src) {
// the regex for s3 bucket url and it must appear within /( and )/g
var re = /((s3:\\[a-zA-Z0-9-\.\\_]+)|((s3-|s3\.)?(.*)\.amazonaws\.com))/g;

// we need to set the url variable to the request or we cant track the alert later
var url = msg.getRequestHeader().getURI().toString();

// If the file type is image jpeg/png , then the scan will be skipped
var contenttype = msg.getResponseHeader().getHeader("Content-Type");
var unwantedfiletypes = [
Expand All @@ -39,21 +46,12 @@ function scan(ps, msg, src) {
founds3bucket.push(buckets[0]);
}
//raise the alert
ps.raiseAlert(
alertRisk,
alertConfidence,
alertTitle,
alertDesc,
url,
"",
"",
founds3bucket.toString(),
alertSolution,
"",
cweId,
wascId,
msg
);
helper
.newAlert()
.setEvidence(founds3bucket[0])
.setOtherInfo(`Other instances: ${founds3bucket.slice(1).toString()}`)
.setMessage(msg)
.raise();
}
}
}

0 comments on commit 16d2c67

Please sign in to comment.