diff --git a/CHANGELOG.md b/CHANGELOG.md index d2c8b3ff..ac8e7b94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - active/gof_lite.js - active/JWT None Exploit.js - active/SSTI.js + - passive/clacks.js + - passive/CookieHTTPOnly.js + - passive/detect_csp_notif_and_reportonly.js + - passive/detect_samesite_protection.js + - passive/f5_bigip_cookie_internal_ip.js ## [18] - 2024-01-29 ### Added diff --git a/active/Cross Site WebSocket Hijacking.js b/active/Cross Site WebSocket Hijacking.js index aaf8bb40..c5bfd063 100644 --- a/active/Cross Site WebSocket Hijacking.js +++ b/active/Cross Site WebSocket Hijacking.js @@ -61,8 +61,8 @@ references: category: server risk: high confidence: medium -cweId: 346 # CWE-346: Origin Validation Error, http://cwe.mitre.org/data/definitions/346.html -wascId: 9 # WASC-9 Cross Site Request Forgery, http://projects.webappsec.org/w/page/13246919/Cross%20Site%20Request%20Forgery +cweId: 346 # CWE-346: Origin Validation Error +wascId: 9 # WASC-9 Cross Site Request Forgery alertTags: ${CommonAlertTag.OWASP_2021_A01_BROKEN_AC.getTag()}: ${CommonAlertTag.OWASP_2021_A01_BROKEN_AC.getValue()} ${CommonAlertTag.OWASP_2017_A05_BROKEN_AC.getTag()}: ${CommonAlertTag.OWASP_2017_A05_BROKEN_AC.getValue()} diff --git a/active/JWT None Exploit.js b/active/JWT None Exploit.js index 0e42c49e..841a91ab 100644 --- a/active/JWT None Exploit.js +++ b/active/JWT None Exploit.js @@ -23,7 +23,7 @@ references: category: server risk: high confidence: medium -cweId: 347 # CWE-347: Improper Verification of Cryptographic Signature, http://cwe.mitre.org/data/definitions/347.html +cweId: 347 # CWE-347: Improper Verification of Cryptographic Signature wascId: 15 # WASC-15: Application Misconfiguration alertTags: ${CommonAlertTag.OWASP_2021_A01_BROKEN_AC.getTag()}: ${CommonAlertTag.OWASP_2021_A01_BROKEN_AC.getValue()} diff --git a/passive/CookieHTTPOnly.js b/passive/CookieHTTPOnly.js index c9f2a257..0bc88e61 100644 --- a/passive/CookieHTTPOnly.js +++ b/passive/CookieHTTPOnly.js @@ -1,37 +1,32 @@ // Cookie HttpOnly Check by freakyclown@gmail.com -function scan(ps, msg, src) { - var alertRisk = 1; - var alertConfidence = 2; - var alertTitle = "Cookie set without HTTPOnly Flag(script)"; - var alertDesc = - "A cookie has been set without the HttpOnly flag, which means that the cookie can be accessed by JavaScript. If a malicious script can be run on this page then the cookie will be accessible and can be transmitted to another site. If this is a session cookie then session hijacking may be possible."; - var alertSolution = "Ensure that the HttpOnly flag is set for all cookies."; +var ScanRuleMetadata = Java.type( + "org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata" +); - var cweId = 0; - var wascId = 13; - - var url = msg.getRequestHeader().getURI().toString(); - var headers = msg.getResponseHeader().getHeaders("Set-Cookie"); +function getMetadata() { + return ScanRuleMetadata.fromYaml(` +id: 100003 +name: Cookie Set Without HttpOnly Flag +description: > + A cookie has been set without the HttpOnly flag, which means that the cookie can be accessed by JavaScript. + If a malicious script can be run on this page then the cookie will be accessible and can be transmitted to another site. + If this is a session cookie then session hijacking may be possible. +solution: Ensure that the HttpOnly flag is set for all cookies. +risk: low +confidence: medium +cweId: 0 +wascId: 13 # WASC-13: Information Leakage +status: alpha +`); +} - if (headers != null) { +function scan(helper, msg, src) { + var cookies = msg.getResponseHeader().getHeaders("Set-Cookie"); + if (cookies != null) { var re_noflag = /([Hh][Tt][Tt][Pp][Oo][Nn][Ll][Yy])/g; - if (!re_noflag.test(headers)) { - ps.raiseAlert( - alertRisk, - alertConfidence, - alertTitle, - alertDesc, - url, - "", - "", - "", - alertSolution, - headers, - cweId, - wascId, - msg - ); + if (!re_noflag.test(cookies)) { + helper.newAlert().setMessage(msg).setEvidence(cookies).raise(); } } } diff --git a/passive/clacks.js b/passive/clacks.js index 92a6565c..d180fea7 100644 --- a/passive/clacks.js +++ b/passive/clacks.js @@ -1,35 +1,30 @@ // Clacks Header Check by freakyclown@gmail.com -function scan(ps, msg, src) { - var alertRisk = 0; - var alertConfidence = 3; - var alertTitle = "Server is running on CLACKS - GNU Terry Pratchett"; - var alertDesc = - "The web/application server is running over the CLACKS network, some say its turtles/IP, some says its turtles all the way down the layer stack."; - var alertSolution = - "Give the sys admin a high five and rejoice in the disc world."; +var ScanRuleMetadata = Java.type( + "org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata" +); - var cweId = 200; - var wascId = 13; +function getMetadata() { + return ScanRuleMetadata.fromYaml(` +id: 100002 +name: Server is running on Clacks - GNU Terry Pratchett +description: > + The web/application server is running over the Clacks network, some say it's turtles/IP, + some say it's turtles all the way down the layer stack. +solution: Give the sysadmin a high five and rejoice in the disc world. +references: + - https://xclacksoverhead.org/home/about +risk: info +confidence: high +cweId: 200 # CWE-200: Exposure of Sensitive Information to an Unauthorized Actor +wascId: 13 # WASC-13: Information Leakage +status: alpha +`); +} - var url = msg.getRequestHeader().getURI().toString(); +function scan(helper, msg, src) { var headers = msg.getResponseHeader().getHeaders("X-Clacks-Overhead"); - if (headers != null) { - ps.raiseAlert( - alertRisk, - alertConfidence, - alertTitle, - alertDesc, - url, - "", - "", - "", - alertSolution, - headers, - cweId, - wascId, - msg - ); + helper.newAlert().setMessage(msg).setEvidence(headers).raise(); } } diff --git a/passive/detect_csp_notif_and_reportonly.js b/passive/detect_csp_notif_and_reportonly.js index 18df165f..dcdd6cec 100644 --- a/passive/detect_csp_notif_and_reportonly.js +++ b/passive/detect_csp_notif_and_reportonly.js @@ -18,6 +18,26 @@ dominique.righetto@gmail.com */ var Locale = Java.type("java.util.Locale"); +var ScanRuleMetadata = Java.type( + "org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata" +); + +function getMetadata() { + return ScanRuleMetadata.fromYaml(` +id: 100004 +name: Content Security Policy Violations Reporting Enabled +solution: > + Site owner will be notified at each policies violations, so, start by analyzing if a real monitoring of the + notifications is in place before to use fuzzing or to be more aggressive. +references: + - https://developer.mozilla.org/en-US/docs/Web/Security/CSP/Using_CSP_violation_reports +risk: info +confidence: high +cweId: 200 # CWE-200: Exposure of Sensitive Information to an Unauthorized Actor +wascId: 13 # WASC-13: Information Leakage +status: alpha +`); +} function extractUrl(cspPolicies, cspReportInstruction) { //Extract the URL to which any CSP violations are reported @@ -37,18 +57,7 @@ function extractUrl(cspPolicies, cspReportInstruction) { } } -function scan(ps, msg, src) { - //Docs on alert raising function: - // 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 - - //Common variables - var cweId = 200; - var wascId = 13; - var url = msg.getRequestHeader().getURI().toString(); +function scan(helper, msg, src) { var cspHeaderNames = [ "Content-Security-Policy", "X-Content-Security-Policy", @@ -57,7 +66,6 @@ function scan(ps, msg, src) { ]; var cspReportInstruction = "report-uri"; - //Response headers collection var responseHeaders = msg.getResponseHeader(); //Detect and analyze presence of the CSP headers @@ -84,25 +92,13 @@ function scan(ps, msg, src) { " mode) report violation to '" + reportUrl + "'."; - var infoLinkRef = - "https://developer.mozilla.org/en-US/docs/Web/Security/CSP/Using_CSP_violation_reports"; - var solution = - "Site owner will be notified at each policies violations, so, start by analyzing if a real monitoring of the notifications is in place before to use fuzzing or to be more aggressive."; - ps.raiseAlert( - 0, - 3, - "Content Security Policy violations reporting enabled", - description, - url, - "HTTP response header '" + headerName + "'", - "", - infoLinkRef, - solution, - headerValues[j], - cweId, - wascId, - msg - ); + helper + .newAlert() + .setDescription(description) + .setParam("HTTP response header '" + headerName + "'") + .setEvidence(headerValues[j]) + .setMessage(msg) + .raise(); } } } diff --git a/passive/detect_samesite_protection.js b/passive/detect_samesite_protection.js index 3894a647..35850dc7 100644 --- a/passive/detect_samesite_protection.js +++ b/passive/detect_samesite_protection.js @@ -13,19 +13,29 @@ dominique.righetto@gmail.com */ var Locale = Java.type("java.util.Locale"); +var ScanRuleMetadata = Java.type( + "org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata" +); -function scan(ps, msg, src) { - //Docs on alert raising function: - // 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 +function getMetadata() { + return ScanRuleMetadata.fromYaml(` +id: 100005 +name: SameSite Cookie Attribute Protection Used +solution: > + CSRF possible vulnerabilities presents on the site will be mitigated depending on the browser used by the user + (browser defines the support level for this cookie attribute). +references: + - https://tools.ietf.org/html/draft-west-first-party-cookies + - https://chloe.re/2016/04/13/goodbye-csrf-samesite-to-the-rescue +risk: info +confidence: high +cweId: 352 # CWE-352: Cross-Site Request Forgery (CSRF) +wascId: 9 # WASC-9: Cross Site Request Forgery +status: alpha +`); +} - //Common variables - var cweId = 352; - var wascId = 9; - var url = msg.getRequestHeader().getURI().toString(); +function scan(helper, msg, src) { var cookieHeaderNames = ["Set-Cookie", "Set-Cookie2"]; var cookieSameSiteAttributeNameLower = "samesite"; @@ -57,25 +67,13 @@ function scan(ps, msg, src) { "', value is set to '" + sameSiteAttrValue + "' protection level."; - var infoLinkRef = - "https://tools.ietf.org/html/draft-west-first-party-cookies\nhttps://chloe.re/2016/04/13/goodbye-csrf-samesite-to-the-rescue"; - var solution = - "CSRF possible vulnerabilities presents on the site will be mitigated depending on the browser used by the user (browser defines the support level for this cookie attribute)."; - ps.raiseAlert( - 0, - 3, - "SameSite cookie attribute protection used", - description, - url, - "Cookie named: '" + cookieName + "'", - "", - infoLinkRef, - solution, - sameSiteAttrValue, - cweId, - wascId, - msg - ); + helper + .newAlert() + .setDescription(description) + .setParam("Cookie named: '" + cookieName + "'") + .setEvidence(sameSiteAttrValue) + .setMessage(msg) + .raise(); break; } } diff --git a/passive/f5_bigip_cookie_internal_ip.js b/passive/f5_bigip_cookie_internal_ip.js index 667f39db..efff7435 100755 --- a/passive/f5_bigip_cookie_internal_ip.js +++ b/passive/f5_bigip_cookie_internal_ip.js @@ -12,25 +12,29 @@ // 20160117 - Updated to include ipv6 variants - jkbowser[at]gmail[dot]com var Locale = Java.type("java.util.Locale"); +var ScanRuleMetadata = Java.type( + "org.zaproxy.addon.commonlib.scanrules.ScanRuleMetadata" +); + +function getMetadata() { + return ScanRuleMetadata.fromYaml(` +id: 100006 +name: Information Disclosure - IP Exposed via F5 BIG-IP Persistence Cookie +description: > + The F5 BIG-IP Persistence cookie set for this website can be decoded to a specific IP and port. + An attacker may leverage this information to conduct Social Engineering attacks or other exploits. +solution: Configure BIG-IP cookie encryption. +references: + - https://support.f5.com/kb/en-us/solutions/public/6000/900/sol6917.html +risk: info +confidence: high +cweId: 311 # CWE-311: Missing Encryption of Sensitive Data +wascId: 13 # WASC-13: Information Leakage +status: alpha +`); +} -function scan(ps, msg, src) { - //Setup some details we will need for alerts later if we find something - var alertRisk = [1, 0]; - var alertConfidence = 3; - var alertTitle = [ - "Internal IP Exposed via F5 BigIP Persistence Cookie", - "IP Exposed via F5 BigIP Presistence Cookie", - ]; - var alertDesc = [ - "The F5 Big-IP Persistence cookie set for this website can be decoded to a specific internal IP and port. An attacker may leverage this information to conduct Social Engineering attacks or other exploits.", - "The F5 Big-IP Persistence cookie set for this website can be decoded to a specific IP and port. An attacker may leverage this information to conduct Social Engineering attacks or other exploits.", - ]; - var alertSolution = "Configure BIG-IP cookie encryption."; - var alertRefs = - "https://support.f5.com/kb/en-us/solutions/public/6000/900/sol6917.html"; - var cweId = 311; - var wascId = 13; - +function scan(helper, msg, src) { var url = msg.getRequestHeader().getURI().toString(); //Only check when a cookie is set if (msg.getResponseHeader().getHeaders("Set-Cookie")) { @@ -65,22 +69,21 @@ function scan(ps, msg, src) { decodedValue = theIP + ":" + thePort; } var alertOtherInfo = cookieValue + " decoded to " + decodedValue; - //ps.raiseAlert(risk, confidence, title, description, url, param, attack, otherinfo, solution, evidence, cweId, wascId, msg); - ps.raiseAlert( - alertRisk[0], - alertConfidence, - alertTitle[0], - alertDesc[0], - url, - cookieName, - "", - alertOtherInfo, - alertSolution + "\n" + alertRefs, - cookieValue, - cweId, - wascId, - msg - ); + helper + .newAlert() + .setRisk(1) + .setName( + "Information Disclosure - Internal IP Exposed via F5 BIG-IP Persistence Cookie" + ) + .setDescription( + "The F5 Big-IP Persistence cookie set for this website can be decoded to a specific internal IP and port. " + + "An attacker may leverage this information to conduct Social Engineering attacks or other exploits." + ) + .setParam(cookieName) + .setOtherInfo(alertOtherInfo) + .setEvidence(cookieValue) + .setMessage(msg) + .raise(); } else if (isExternal(theIP)) { if (theIP.match(/:/g)) { //matching again just so I can format it correctly with [] @@ -89,22 +92,13 @@ function scan(ps, msg, src) { decodedValue = theIP + ":" + thePort; } alertOtherInfo = cookieValue + " decoded to " + decodedValue; - //ps.raiseAlert(risk, confidence, title, description, url, param, attack, otherinfo, solution, evidence, cweId, wascId, msg); - ps.raiseAlert( - alertRisk[1], - alertConfidence, - alertTitle[1], - alertDesc[1], - url, - cookieName, - "", - alertOtherInfo, - alertSolution + "\n" + alertRefs, - cookieValue, - cweId, - wascId, - msg - ); + helper + .newAlert() + .setParam(cookieName) + .setOtherInfo(alertOtherInfo) + .setEvidence(cookieValue) + .setMessage(msg) + .raise(); } else { //Not what we're looking for continue;