diff --git a/addOns/ascanrulesBeta/CHANGELOG.md b/addOns/ascanrulesBeta/CHANGELOG.md index d3b77e26c1d..a60dc72e46e 100644 --- a/addOns/ascanrulesBeta/CHANGELOG.md +++ b/addOns/ascanrulesBeta/CHANGELOG.md @@ -5,8 +5,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## Unreleased ### Changed -- The Backup File Disclosure scan rule now includes example alert functionality for documentation generation purposes (Issue 6119). -- Updated reference for scan rule: Session Fixation (Issue 8262) +- The following scan rules now include example alert functionality for documentation generation purposes (Issue 6119): + - Backup File Disclosure + - Httpoxy - Proxy Header Misuse + - Anti-CSRF Tokens Check + - HTTP Parameter Pollution + - Cross-Domain Misconfiguration +- Alerts from the HTTP Parameter Pollution scan rule are now raised with Low confidence. +- Updated reference for scan rules (Issue 8262): + - Session Fixation + - Cross-Domain Misconfiguration - Add website alert links to the help page (Issue 8189). ## [50] - 2024-01-26 diff --git a/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/CrossDomainScanRule.java b/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/CrossDomainScanRule.java index 9888737ff7c..7c587a348b9 100644 --- a/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/CrossDomainScanRule.java +++ b/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/CrossDomainScanRule.java @@ -21,6 +21,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; +import java.util.List; import java.util.Map; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -192,21 +193,7 @@ private void scanAdobeCrossdomainPolicyFile(URI originalURI) String domain = exprAllowAccessFromDomainNodes.item(i).getNodeValue(); if (domain.equals("*")) { // oh dear me. - newAlert() - .setConfidence(Alert.CONFIDENCE_MEDIUM) - .setName( - Constant.messages.getString(MESSAGE_PREFIX_ADOBE_READ + "name")) - .setDescription( - Constant.messages.getString(MESSAGE_PREFIX_ADOBE + "desc")) - .setOtherInfo( - Constant.messages.getString( - MESSAGE_PREFIX_ADOBE_READ + "extrainfo", - "/" + ADOBE_CROSS_DOMAIN_POLICY_FILE)) - .setSolution( - Constant.messages.getString(MESSAGE_PREFIX_ADOBE_READ + "soln")) - .setEvidence(" getAlertTags() { return ALERT_TAGS; } + + @Override + public List getExampleAlerts() { + return List.of( + buildAdobeReadAlert().build(), + buildAdobeSendAlert().build(), + buildSilverlightAlert().build()); + } } diff --git a/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/CsrfTokenScanRule.java b/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/CsrfTokenScanRule.java index eb6f0aa2f85..14fe7980e43 100644 --- a/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/CsrfTokenScanRule.java +++ b/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/CsrfTokenScanRule.java @@ -220,13 +220,7 @@ public void scan() { Constant.messages.getString( MESSAGE_PREFIX + "extrainfo.annotation"); } - newAlert() - .setRisk(risk) - .setConfidence(Alert.CONFIDENCE_MEDIUM) - .setOtherInfo(otherInfo) - .setEvidence(evidence) - .setMessage(getBaseMsg()) - .raise(); + buildAlert(risk, otherInfo, evidence).setMessage(getBaseMsg()).raise(); } } @@ -237,6 +231,14 @@ public void scan() { } } + private AlertBuilder buildAlert(int risk, String otherInfo, String evidence) { + return newAlert() + .setRisk(risk) + .setConfidence(Alert.CONFIDENCE_MEDIUM) + .setOtherInfo(otherInfo) + .setEvidence(evidence); + } + private boolean formOnIgnoreList(Element formElement) { String id = formElement.getAttributeValue("id"); String name = formElement.getAttributeValue("name"); @@ -301,4 +303,14 @@ public int getWascId() { public Map getAlertTags() { return ALERT_TAGS; } + + @Override + public List getExampleAlerts() { + return List.of( + buildAlert( + Alert.RISK_MEDIUM, + "", + "") + .build()); + } } diff --git a/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/HttPoxyScanRule.java b/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/HttPoxyScanRule.java index b9d3924ea06..42daf220a43 100644 --- a/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/HttPoxyScanRule.java +++ b/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/HttPoxyScanRule.java @@ -22,6 +22,7 @@ import java.net.InetAddress; import java.net.NetworkInterface; import java.util.Enumeration; +import java.util.List; import java.util.Map; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -142,13 +143,10 @@ public void scan() { if (listener.isMsgReceived()) { // the server is vulnerable - newAlert() - .setConfidence(Alert.CONFIDENCE_HIGH) - .setUri(getBaseMsg().getRequestHeader().getURI().toString()) - .setAttack(HttpFieldsNames.PROXY + ": " + hostPort) - .setOtherInfo( - Constant.messages.getString( - MESSAGE_PREFIX + "otherinfo", listener.getMsgUrl())) + buildAlert( + hostPort, + getBaseMsg().getRequestHeader().getURI().toString(), + listener.getMsgUrl()) .setMessage(newRequest) .raise(); @@ -162,6 +160,21 @@ public void scan() { } } + private AlertBuilder buildAlert(String hostPort, String baseUrl, String url) { + return newAlert() + .setConfidence(Alert.CONFIDENCE_HIGH) + .setUri(baseUrl) + .setAttack(HttpFieldsNames.PROXY + ": " + hostPort) + .setOtherInfo(Constant.messages.getString(MESSAGE_PREFIX + "otherinfo", url)); + } + + @Override + public List getExampleAlerts() { + return List.of( + buildAlert("192.168.0.11:1080", "http://example.com/", "http://192.168.0.11:1080/") + .build()); + } + private class HttpoxyListener implements HttpMessageHandler { private boolean msgReceived; diff --git a/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/HttpParameterPollutionScanRule.java b/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/HttpParameterPollutionScanRule.java index 4e962d37002..80e72d88054 100644 --- a/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/HttpParameterPollutionScanRule.java +++ b/addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/HttpParameterPollutionScanRule.java @@ -278,20 +278,16 @@ public void generateReport(List vulnLinks) { vulnParams = vulnParams + ", " + s; } LOGGER.debug("Page vulnerable to HPP attacks"); - String attack = Constant.messages.getString("ascanbeta.HTTPParamPoll.alert.attack"); - newAlert() - .setConfidence(Alert.CONFIDENCE_MEDIUM) - .setName(attack) - .setParam(vulnParams) - .setAttack(attack) - .setMessage(getBaseMsg()) - .raise(); + buildAlert(vulnParams).setMessage(getBaseMsg()).raise(); + } + + private AlertBuilder buildAlert(String vulnParams) { + return newAlert().setConfidence(Alert.CONFIDENCE_LOW).setParam(vulnParams); } @Override public int getRisk() { - // TODO Auto-generated method stub - return 0; + return Alert.RISK_INFO; } @Override @@ -308,4 +304,9 @@ public int getWascId() { public Map getAlertTags() { return ALERT_TAGS; } + + @Override + public List getExampleAlerts() { + return List.of(buildAlert("Id").build()); + } } diff --git a/addOns/ascanrulesBeta/src/main/resources/org/zaproxy/zap/extension/ascanrulesBeta/resources/Messages.properties b/addOns/ascanrulesBeta/src/main/resources/org/zaproxy/zap/extension/ascanrulesBeta/resources/Messages.properties index bfb0186e6b7..727dc8fdca9 100644 --- a/addOns/ascanrulesBeta/src/main/resources/org/zaproxy/zap/extension/ascanrulesBeta/resources/Messages.properties +++ b/addOns/ascanrulesBeta/src/main/resources/org/zaproxy/zap/extension/ascanrulesBeta/resources/Messages.properties @@ -1,4 +1,3 @@ -ascanbeta.HTTPParamPoll.alert.attack = HTTP Parameter Pollution ascanbeta.HTTPParamPoll.desc = HTTP Parameter Pollution (HPP) attacks consist of injecting encoded query string delimiters into other existing parameters. If a web application does not properly sanitize the user input, a malicious user can compromise the logic of the application to perform either client-side or server-side attacks. One consequence of HPP attacks is that the attacker can potentially override existing hard-coded HTTP parameters to modify the behavior of an application, bypass input validation checkpoints, and access and possibly exploit variables that may be out of direct reach. ascanbeta.HTTPParamPoll.extrainfo = https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/04-Testing_for_HTTP_Parameter_Pollution ascanbeta.HTTPParamPoll.name = HTTP Parameter Pollution @@ -35,8 +34,7 @@ ascanbeta.crossdomain.adobe.send.extrainfo = The web server permits malicious cr ascanbeta.crossdomain.adobe.send.name = Cross-Domain Misconfiguration - Adobe - Send ascanbeta.crossdomain.adobe.send.soln = Configure the crossdomain.xml file to restrict the list of domains that are allowed to make cross-domain send (but not necessarily read) requests to this web server, using . You should only grant access to "*" (all domains) if you are certain that this service is not vulnerable to Cross Site Request Forgery (CSRF) attacks. ascanbeta.crossdomain.name = Cross-Domain Misconfiguration -#the refs cannot be customised for each sub-category (Adobe, Silverlight, etc.) -ascanbeta.crossdomain.refs = http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html\nhttp://www.adobe.com/devnet-docs/acrobatetk/tools/AppSec/CrossDomain_PolicyFile_Specification.pdf\nhttp://msdn.microsoft.com/en-US/library/cc197955%28v=vs.95%29.aspx\nhttp://msdn.microsoft.com/en-us/library/cc838250%28v=vs.95%29.aspx +ascanbeta.crossdomain.refs = https://www.adobe.com/devnet-docs/acrobatetk/tools/AppSec/CrossDomain_PolicyFile_Specification.pdf\nhttps://learn.microsoft.com/en-us/previous-versions/windows/silverlight/dotnet-windows-silverlight/cc197955(v=vs.95)\nhttps://learn.microsoft.com/en-us/previous-versions/windows/silverlight/dotnet-windows-silverlight/cc838250(v=vs.95) ascanbeta.crossdomain.silverlight.desc = Silverlight based cross-site request forgery may be possible, due to a misconfiguration on the web server. ascanbeta.crossdomain.silverlight.extrainfo = The web server permits malicious cross-domain requests originating from Silverlight components served from any third party domain, to this domain. If the victim user is logged into this service, the malicious requests are processed using the privileges of the victim, and can result in data from this service being compromised by an unauthorised third party web site, via the victim's web browsers. It can also result in Cross Site Request Forgery (CSRF) type attacks. This is particularly likely to be an issue if a Cookie based session implementation is in use. ascanbeta.crossdomain.silverlight.name = Cross-Domain Misconfiguration - Silverlight diff --git a/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/CrossDomainScanRuleUnitTest.java b/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/CrossDomainScanRuleUnitTest.java index 06e1fe1d258..35ab70fff0d 100644 --- a/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/CrossDomainScanRuleUnitTest.java +++ b/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/CrossDomainScanRuleUnitTest.java @@ -23,8 +23,10 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; +import org.parosproxy.paros.core.scanner.Alert; import org.zaproxy.addon.commonlib.CommonAlertTag; class CrossDomainScanRuleUnitTest extends ActiveScannerTest { @@ -63,4 +65,24 @@ void shouldReturnExpectedMappings() { tags.get(CommonAlertTag.WSTG_V42_CONF_08_RIA_CROSS_DOMAIN.getTag()), is(equalTo(CommonAlertTag.WSTG_V42_CONF_08_RIA_CROSS_DOMAIN.getValue()))); } + + @Test + void shouldHaveExpectedExampleAlert() { + // Given / When + List alerts = rule.getExampleAlerts(); + // Then + assertThat(alerts.size(), is(equalTo(3))); + Alert adobeRead = alerts.get(0); + assertThat(adobeRead.getAlertRef(), is(equalTo("20016-1"))); + Alert adobeSend = alerts.get(1); + assertThat(adobeSend.getAlertRef(), is(equalTo("20016-2"))); + Alert silverlight = alerts.get(2); + assertThat(silverlight.getAlertRef(), is(equalTo("20016-3"))); + } + + @Test + @Override + public void shouldHaveValidReferences() { + super.shouldHaveValidReferences(); + } } diff --git a/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/CsrfTokenScanRuleUnitTest.java b/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/CsrfTokenScanRuleUnitTest.java index 73ea1bc7d1c..a8ae32fb1a5 100644 --- a/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/CsrfTokenScanRuleUnitTest.java +++ b/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/CsrfTokenScanRuleUnitTest.java @@ -35,6 +35,7 @@ import java.util.TreeSet; import org.apache.commons.httpclient.URIException; import org.junit.jupiter.api.Test; +import org.parosproxy.paros.core.scanner.Alert; import org.parosproxy.paros.core.scanner.Plugin.AlertThreshold; import org.parosproxy.paros.model.Model; import org.parosproxy.paros.model.OptionsParam; @@ -316,6 +317,20 @@ void shouldReturnExpectedMappings() { is(equalTo(CommonAlertTag.WSTG_V42_SESS_05_CSRF.getValue()))); } + @Test + void shouldHaveExpectedExampleAlert() { + // Given / When + List alerts = rule.getExampleAlerts(); + // Then + assertThat(alerts.size(), is(equalTo(1))); + } + + @Test + @Override + public void shouldHaveValidReferences() { + super.shouldHaveValidReferences(); + } + private HttpMessage createMessage(boolean isInScope) throws URIException, HttpMalformedHeaderException { HttpMessage msg = diff --git a/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/HttPoxyScanRuleUnitTest.java b/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/HttPoxyScanRuleUnitTest.java index 9b7d12e9d47..06808e6a6fe 100644 --- a/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/HttPoxyScanRuleUnitTest.java +++ b/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/HttPoxyScanRuleUnitTest.java @@ -23,8 +23,10 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; +import org.parosproxy.paros.core.scanner.Alert; import org.zaproxy.addon.commonlib.CommonAlertTag; class HttPoxyScanRuleUnitTest extends ActiveScannerTest { @@ -57,4 +59,18 @@ void shouldReturnExpectedMappings() { tags.get(CommonAlertTag.OWASP_2017_A09_VULN_COMP.getTag()), is(equalTo(CommonAlertTag.OWASP_2017_A09_VULN_COMP.getValue()))); } + + @Test + void shouldHaveExpectedExampleAlert() { + // Given / When + List alerts = rule.getExampleAlerts(); + // Then + assertThat(alerts.size(), is(equalTo(1))); + } + + @Test + @Override + public void shouldHaveValidReferences() { + super.shouldHaveValidReferences(); + } } diff --git a/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/HttpParameterPollutionScanRuleUnitTest.java b/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/HttpParameterPollutionScanRuleUnitTest.java index 08cbdc019ad..5ec135a676e 100644 --- a/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/HttpParameterPollutionScanRuleUnitTest.java +++ b/addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/HttpParameterPollutionScanRuleUnitTest.java @@ -23,8 +23,10 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; +import org.parosproxy.paros.core.scanner.Alert; import org.zaproxy.addon.commonlib.CommonAlertTag; class HttpParameterPollutionScanRuleUnitTest @@ -64,4 +66,18 @@ void shouldReturnExpectedMappings() { tags.get(CommonAlertTag.WSTG_V42_INPV_04_PARAM_POLLUTION.getTag()), is(equalTo(CommonAlertTag.WSTG_V42_INPV_04_PARAM_POLLUTION.getValue()))); } + + @Test + void shouldHaveExpectedExampleAlert() { + // Given / When + List alerts = rule.getExampleAlerts(); + // Then + assertThat(alerts.size(), is(equalTo(1))); + } + + @Test + @Override + public void shouldHaveValidReferences() { + super.shouldHaveValidReferences(); + } }