Skip to content

Commit 7c93b66

Browse files
committed
ascanrulesBeta: More example alerts
- CHANGELOG > Add notes. - Scan rules > Add example alert functionality (6119). - Unit tests > Assert the new example alerts. Signed-off-by: kingthorin <[email protected]>
1 parent 289e3af commit 7c93b66

File tree

6 files changed

+86
-15
lines changed

6 files changed

+86
-15
lines changed

addOns/ascanrulesBeta/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@ All notable changes to this add-on will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
55

66
## Unreleased
7+
### Changed
8+
- The following scan rules now include example alert functionality for documentation generation purposes (Issue 6119):
9+
- Expression Language Injection
10+
- Cookie Slack Detector
11+
712
### Fixed
813
- Potential false positives in the Source Code Disclosure - File Inclusion scan rule when responses are empty or the original message resulted in an error to start with (Issue 8517).
14+
- A spacing/punctuation issue in the Cookie Slack Detector scan rule, whereby the Other Info field would not have a space after colons and before lists of cookie names.
915

1016
## [54] - 2024-07-22
1117
### Changed

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

+15-7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.io.IOException;
2323
import java.net.UnknownHostException;
24+
import java.util.List;
2425
import java.util.Map;
2526
import java.util.Random;
2627
import org.apache.commons.httpclient.URIException;
@@ -167,13 +168,7 @@ public void scan(HttpMessage msg, String paramName, String value) {
167168
paramName,
168169
payload);
169170

170-
newAlert()
171-
.setConfidence(Alert.CONFIDENCE_MEDIUM)
172-
.setParam(paramName)
173-
.setAttack(payload)
174-
.setEvidence(addedString)
175-
.setMessage(msg)
176-
.raise();
171+
createAlert(paramName, payload, addedString).setMessage(msg).raise();
177172
}
178173

179174
} catch (IOException ex) {
@@ -186,4 +181,17 @@ public void scan(HttpMessage msg, String paramName, String value) {
186181
ex);
187182
}
188183
}
184+
185+
private AlertBuilder createAlert(String paramName, String attack, String evidence) {
186+
return newAlert()
187+
.setConfidence(Alert.CONFIDENCE_MEDIUM)
188+
.setParam(paramName)
189+
.setAttack(attack)
190+
.setEvidence(evidence);
191+
}
192+
193+
@Override
194+
public List<Alert> getExampleAlerts() {
195+
return List.of(createAlert("foo", "${719117+853088}", "1572205").build());
196+
}
189197
}

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

+20-6
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
import java.io.IOException;
2323
import java.util.HashSet;
2424
import java.util.Iterator;
25+
import java.util.List;
2526
import java.util.Locale;
2627
import java.util.Map;
2728
import java.util.Set;
29+
import java.util.SortedSet;
2830
import java.util.TreeSet;
2931
import org.apache.logging.log4j.LogManager;
3032
import org.apache.logging.log4j.Logger;
@@ -203,12 +205,11 @@ private void raiseAlert(
203205

204206
int riskLevel = calculateRisk(cookiesThatDoNOTMakeADifference, otherInfoBuff);
205207

206-
newAlert()
207-
.setRisk(riskLevel)
208-
.setConfidence(Alert.CONFIDENCE_LOW)
209-
.setOtherInfo(otherInfoBuff.toString())
210-
.setMessage(msg)
211-
.raise();
208+
createAlert(riskLevel, otherInfoBuff.toString()).setMessage(msg).raise();
209+
}
210+
211+
private AlertBuilder createAlert(int risk, String otherInfo) {
212+
return newAlert().setRisk(risk).setConfidence(Alert.CONFIDENCE_LOW).setOtherInfo(otherInfo);
212213
}
213214

214215
private StringBuilder createOtherInfoText(
@@ -334,4 +335,17 @@ public int getWascId() {
334335
public Map<String, String> getAlertTags() {
335336
return ALERT_TAGS;
336337
}
338+
339+
@Override
340+
public List<Alert> getExampleAlerts() {
341+
SortedSet<String> impacting = new TreeSet<>();
342+
impacting.add("foo");
343+
impacting.add("bar");
344+
345+
return List.of(
346+
createAlert(
347+
Alert.RISK_INFO,
348+
createOtherInfoText(Set.of("oops"), impacting).toString())
349+
.build());
350+
}
337351
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ ascanbeta.backupfiledisclosure.otherinfo = A backup of [{0}] is available at [{1
99
ascanbeta.backupfiledisclosure.refs = https://cwe.mitre.org/data/definitions/530.html\nhttps://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/02-Configuration_and_Deployment_Management_Testing/04-Review_Old_Backup_and_Unreferenced_Files_for_Sensitive_Information.html
1010
ascanbeta.backupfiledisclosure.soln = Do not edit files in-situ on the web server, and ensure that un-necessary files (including hidden files) are removed from the web server.
1111

12-
ascanbeta.cookieslack.affect.response.no = These cookies did NOT affect the response:
13-
ascanbeta.cookieslack.affect.response.yes = These cookies affected the response:
12+
ascanbeta.cookieslack.affect.response.no = These cookies did NOT affect the response:
13+
ascanbeta.cookieslack.affect.response.yes = These cookies affected the response:
1414
ascanbeta.cookieslack.desc = Repeated GET requests: drop a different cookie each time, followed by normal request with all cookies to stabilize session, compare responses against original baseline GET. This can reveal areas where cookie based authentication/attributes are not actually enforced.
1515
ascanbeta.cookieslack.endline = \n
1616
ascanbeta.cookieslack.name = Cookie Slack Detector

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

+19
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,16 @@
2020
package org.zaproxy.zap.extension.ascanrulesBeta;
2121

2222
import static org.hamcrest.MatcherAssert.assertThat;
23+
import static org.hamcrest.Matchers.emptyString;
2324
import static org.hamcrest.Matchers.equalTo;
25+
import static org.hamcrest.Matchers.hasSize;
2426
import static org.hamcrest.Matchers.is;
27+
import static org.hamcrest.Matchers.not;
2528

29+
import java.util.List;
2630
import java.util.Map;
2731
import org.junit.jupiter.api.Test;
32+
import org.parosproxy.paros.core.scanner.Alert;
2833
import org.zaproxy.addon.commonlib.CommonAlertTag;
2934

3035
class ExpressionLanguageInjectionScanRuleUnitTest
@@ -64,4 +69,18 @@ void shouldReturnExpectedMappings() {
6469
tags.get(CommonAlertTag.WSTG_V42_INPV_11_CODE_INJ.getTag()),
6570
is(equalTo(CommonAlertTag.WSTG_V42_INPV_11_CODE_INJ.getValue())));
6671
}
72+
73+
@Test
74+
void shouldHaveExpectedExampleAlert() {
75+
// Given / When
76+
List<Alert> alerts = rule.getExampleAlerts();
77+
// Then
78+
assertThat(alerts, hasSize(1));
79+
Alert alert = alerts.get(0);
80+
assertThat(alert.getRisk(), is(equalTo(rule.getRisk())));
81+
assertThat(alert.getConfidence(), is(equalTo(Alert.CONFIDENCE_MEDIUM)));
82+
assertThat(alert.getParam(), is(equalTo("foo")));
83+
assertThat(alert.getAttack(), is(not(emptyString())));
84+
assertThat(alert.getEvidence(), is(not(emptyString())));
85+
}
6786
}

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

+24
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@
2121

2222
import static org.hamcrest.MatcherAssert.assertThat;
2323
import static org.hamcrest.Matchers.equalTo;
24+
import static org.hamcrest.Matchers.hasSize;
2425
import static org.hamcrest.Matchers.is;
2526

27+
import java.util.List;
2628
import java.util.Map;
2729
import org.junit.jupiter.api.Test;
30+
import org.parosproxy.paros.core.scanner.Alert;
2831
import org.zaproxy.addon.commonlib.CommonAlertTag;
2932

3033
class SlackerCookieScanRuleUnitTest extends ActiveScannerTest<SlackerCookieScanRule> {
@@ -63,4 +66,25 @@ void shouldReturnExpectedMappings() {
6366
tags.get(CommonAlertTag.WSTG_V42_SESS_02_COOKIE_ATTRS.getTag()),
6467
is(equalTo(CommonAlertTag.WSTG_V42_SESS_02_COOKIE_ATTRS.getValue())));
6568
}
69+
70+
@Test
71+
void shouldHaveExpectedExampleAlert() {
72+
// Given / When
73+
List<Alert> alerts = rule.getExampleAlerts();
74+
// Then
75+
assertThat(alerts, hasSize(1));
76+
Alert alert = alerts.get(0);
77+
assertThat(alert.getRisk(), is(equalTo(Alert.RISK_INFO)));
78+
assertThat(alert.getConfidence(), is(equalTo(Alert.CONFIDENCE_LOW)));
79+
assertThat(
80+
alert.getOtherInfo(),
81+
is(
82+
equalTo(
83+
"Cookies that don't have "
84+
+ "expected effects can reveal flaws in application logic. In "
85+
+ "the worst case, this can reveal where authentication via cookie "
86+
+ "token(s) is not actually enforced.\n"
87+
+ "These cookies affected the response: oops\n"
88+
+ "These cookies did NOT affect the response: bar,foo\n")));
89+
}
6690
}

0 commit comments

Comments
 (0)