Skip to content

Commit ed90ba4

Browse files
committed
ascanrulesBeta: Address possible FP in proxy detection rule
- CHANGELOG > Added change note. - ProxyDisclosureScanRule > Added condition to skip messages if they have evidence content to start with. Removed misleading Attack text from the Alert. - ProxyDisclosureScanRuleUnitTest > Added a test to assert the new behavior. Signed-off-by: kingthorin <[email protected]>
1 parent d34392d commit ed90ba4

File tree

4 files changed

+48
-7
lines changed

4 files changed

+48
-7
lines changed

addOns/ascanrulesBeta/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66
## Unreleased
77
### Changed
88
- Log exception details in Out of Band XSS scan rule.
9+
- The Proxy Disclosure scan rule will no longer alert on HTTP messages that have evidence to start with, in order to reduce possible false positives (Issue 8556). The misleading Attack string for the Alerts was also removed.
910

1011
## [55] - 2024-09-02
1112
### Changed

addOns/ascanrulesBeta/src/main/java/org/zaproxy/zap/extension/ascanrulesBeta/ProxyDisclosureScanRule.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,12 @@ public void scan() {
331331
String proxyServer = PROXY_REQUEST_HEADERS.get(proxyHeaderPattern);
332332
Matcher proxyHeaderMatcher =
333333
proxyHeaderPattern.matcher(traceResponseBody);
334-
if (proxyHeaderMatcher.find()) {
334+
Matcher originalBodyMatcher =
335+
proxyHeaderPattern.matcher(
336+
getBaseMsg().getResponseBody().toString());
337+
// Ensure the original message didn't already have evidence type
338+
// content
339+
if (!originalBodyMatcher.find() && proxyHeaderMatcher.find()) {
335340
String proxyHeaderName = proxyHeaderMatcher.group(1);
336341
proxyActuallyFound = true;
337342
LOGGER.debug(
@@ -752,7 +757,6 @@ public void scan() {
752757
Constant.messages.getString(
753758
MESSAGE_PREFIX + "desc",
754759
step2numberOfNodes - 1 + silentProxySet.size()))
755-
.setAttack(getAttack())
756760
.setOtherInfo(extraInfo)
757761
.setMessage(getBaseMsg())
758762
.raise();
@@ -773,10 +777,6 @@ private String getPath(URI uri) {
773777
return "/";
774778
}
775779

776-
private String getAttack() {
777-
return Constant.messages.getString(MESSAGE_PREFIX + "attack");
778-
}
779-
780780
@Override
781781
public int getRisk() {
782782
return Alert.RISK_MEDIUM;

addOns/ascanrulesBeta/src/main/resources/org/zaproxy/zap/extension/ascanrulesBeta/resources/Messages.properties

-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ ascanbeta.noanticsrftokens.name = Absence of Anti-CSRF Tokens
125125
ascanbeta.oobxss.name = Out of Band XSS
126126
ascanbeta.oobxss.skipped = no Active Scan OAST service is selected.
127127

128-
ascanbeta.proxydisclosure.attack = TRACE, OPTIONS methods with 'Max-Forwards' header. TRACK method.
129128
ascanbeta.proxydisclosure.desc = {0} proxy server(s) were detected or fingerprinted. This information helps a potential attacker to determine\n- A list of targets for an attack against the application.\n - Potential vulnerabilities on the proxy servers that service the application.\n - The presence or absence of any proxy-based components that might cause attacks against the application to be detected, prevented, or mitigated.
130129
ascanbeta.proxydisclosure.extrainfo.proxyserver = - {0}
131130
ascanbeta.proxydisclosure.extrainfo.proxyserver.header = Using the TRACE, OPTIONS, and TRACK methods, the following proxy servers have been identified between ZAP and the application/web server:

addOns/ascanrulesBeta/src/test/java/org/zaproxy/zap/extension/ascanrulesBeta/ProxyDisclosureScanRuleUnitTest.java

+41
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,24 @@
1919
*/
2020
package org.zaproxy.zap.extension.ascanrulesBeta;
2121

22+
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
2223
import static org.hamcrest.MatcherAssert.assertThat;
2324
import static org.hamcrest.Matchers.equalTo;
25+
import static org.hamcrest.Matchers.hasSize;
2426
import static org.hamcrest.Matchers.is;
2527

28+
import fi.iki.elonen.NanoHTTPD;
29+
import fi.iki.elonen.NanoHTTPD.IHTTPSession;
30+
import fi.iki.elonen.NanoHTTPD.Response;
2631
import java.util.Map;
32+
import org.apache.commons.httpclient.URIException;
2733
import org.junit.jupiter.api.Test;
34+
import org.junit.jupiter.params.ParameterizedTest;
35+
import org.junit.jupiter.params.provider.ValueSource;
36+
import org.parosproxy.paros.network.HttpMalformedHeaderException;
37+
import org.parosproxy.paros.network.HttpMessage;
2838
import org.zaproxy.addon.commonlib.CommonAlertTag;
39+
import org.zaproxy.zap.testutils.NanoServerHandler;
2940

3041
class ProxyDisclosureScanRuleUnitTest extends ActiveScannerTest<ProxyDisclosureScanRule> {
3142

@@ -57,4 +68,34 @@ void shouldReturnExpectedMappings() {
5768
tags.get(CommonAlertTag.OWASP_2017_A06_SEC_MISCONFIG.getTag()),
5869
is(equalTo(CommonAlertTag.OWASP_2017_A06_SEC_MISCONFIG.getValue())));
5970
}
71+
72+
@ParameterizedTest
73+
@ValueSource(
74+
strings = {
75+
"X-Forwarded-For: 127.0.0.1",
76+
"X-Forwarded-Port: 443",
77+
"X-Forwarded-Proto: https",
78+
"Via: 1.1 vegur"
79+
})
80+
void shouldNotAlertIfOriginalHasEvidence(String header)
81+
throws HttpMalformedHeaderException, URIException {
82+
// Given
83+
String test = "/";
84+
nano.addHandler(
85+
new NanoServerHandler(test) {
86+
87+
@Override
88+
protected Response serve(IHTTPSession session) {
89+
String content = "<html>" + header + "</html>";
90+
return newFixedLengthResponse(
91+
Response.Status.OK, NanoHTTPD.MIME_HTML, content);
92+
}
93+
});
94+
HttpMessage msg = getHttpMessage(test);
95+
rule.init(msg, parent);
96+
// When
97+
rule.scan();
98+
// Then
99+
assertThat(alertsRaised, hasSize(equalTo(0))); // No messages sent
100+
}
60101
}

0 commit comments

Comments
 (0)