Skip to content

Commit

Permalink
Merge pull request #5186 from kingthorin/5184-followup
Browse files Browse the repository at this point in the history
pscanrules: Add example alerts, alert refs, and ref verification
  • Loading branch information
psiinon authored Jan 3, 2024
2 parents 00aa2d0 + 2bf21e2 commit a45ea07
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 15 deletions.
4 changes: 2 additions & 2 deletions addOns/pscanrules/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Unreleased
### Changed
- The Big Redirect scan rule will now also alert on responses that have multiple HREFs (idea from xnl-h4ck3r).
- It also now includes example alert and alert reference functionality for documentation generation purposes (Issues 6119, 7100, and 8189).
- It also now includes example alert and alert reference functionality for documentation generation and cross linking purposes (Issues 6119, 7100, and 8189).
- Update reference for X-Content-Type-Options Header Missing and Content-Type Header Missing (Issue 8262).
- They now also include example alerts for documentation generation and cross linking purposes (Issues 6119, 7100, and 8189).
- Update reference for Loosely Scoped Cookie (Issue 8262).


## [53] - 2023-11-30
### Changed
- The Application Error Disclosure rule no longer considers responses that contain ISO control characters (those which are likely to be binary file types).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,33 +49,34 @@ public void scanHttpResponseReceive(HttpMessage msg, int id, Source source) {
if (!contentType.isEmpty()) {
for (String contentTypeDirective : contentType) {
if (contentTypeDirective.isEmpty()) {
this.raiseAlert(msg, id, contentTypeDirective, false);
buildAlert(false).raise();
}
}
} else {
this.raiseAlert(msg, id, "", true);
buildAlert(true).raise();
}
}
}

private void raiseAlert(
HttpMessage msg, int id, String contentType, boolean isContentTypeMissing) {
private AlertBuilder buildAlert(boolean isContentTypeMissing) {
String issue = Constant.messages.getString(MESSAGE_PREFIX + "name.empty");
String alertRef = PLUGIN_ID + "-2";
if (isContentTypeMissing) {
issue = getName();
alertRef = PLUGIN_ID + "-1";
}

newAlert()
return newAlert()
.setName(issue)
.setRisk(getRisk())
.setConfidence(Alert.CONFIDENCE_MEDIUM)
.setDescription(getDescription())
.setParam(contentType)
.setParam(HttpHeader.CONTENT_TYPE)
.setSolution(getSolution())
.setReference(getReference())
.setCweId(getCweId())
.setWascId(getWascId())
.raise();
.setAlertRef(alertRef);
}

@Override
Expand Down Expand Up @@ -116,4 +117,9 @@ public int getRisk() {
public int getPluginId() {
return PLUGIN_ID;
}

@Override
public List<Alert> getExampleAlerts() {
return List.of(buildAlert(true).build(), buildAlert(false).build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,22 @@ public void scanHttpResponseReceive(HttpMessage msg, int id, Source source) {
List<String> xContentTypeOptions =
msg.getResponseHeader().getHeaderValues(HttpHeader.X_CONTENT_TYPE_OPTIONS);
if (xContentTypeOptions.isEmpty()) {
this.raiseAlert(msg, id, "");
buildAlert("").raise();
} else {
for (String xContentTypeOptionsDirective : xContentTypeOptions) {
// 'nosniff' is currently the only defined value for this header, so this logic
// is ok
if (xContentTypeOptionsDirective.toLowerCase(Locale.ROOT).indexOf("nosniff")
< 0) {
this.raiseAlert(msg, id, xContentTypeOptionsDirective);
buildAlert(xContentTypeOptionsDirective).raise();
}
}
}
}
}

private void raiseAlert(HttpMessage msg, int id, String xContentTypeOption) {
newAlert()
private AlertBuilder buildAlert(String xContentTypeOption) {
return newAlert()
.setRisk(getRisk())
.setConfidence(Alert.CONFIDENCE_MEDIUM)
.setDescription(getDescription())
Expand All @@ -92,8 +92,7 @@ private void raiseAlert(HttpMessage msg, int id, String xContentTypeOption) {
.setReference(getReference())
.setEvidence(xContentTypeOption)
.setCweId(getCweId())
.setWascId(getWascId())
.raise();
.setWascId(getWascId());
}

@Override
Expand Down Expand Up @@ -138,4 +137,9 @@ public int getCweId() {
public int getWascId() {
return 15; // WASC-15: Application Misconfiguration
}

@Override
public List<Alert> getExampleAlerts() {
return List.of(buildAlert("").build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
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.Constant;
import org.parosproxy.paros.core.scanner.Alert;
import org.parosproxy.paros.network.HttpMalformedHeaderException;
import org.parosproxy.paros.network.HttpMessage;
import org.parosproxy.paros.network.HttpResponseHeader;
Expand Down Expand Up @@ -79,6 +81,20 @@ void shouldReturnExpectedMappings() {
is(equalTo(CommonAlertTag.OWASP_2017_A06_SEC_MISCONFIG.getValue())));
}

@Test
void shouldHaveExpectedExampleAlerts() {
// Given / WHen
List<Alert> alerts = rule.getExampleAlerts();
// Then
assertThat(alerts.size(), is(equalTo(2)));
}

@Test
@Override
public void shouldHaveValidReferences() {
super.shouldHaveValidReferences();
}

@Test
void shouldNotAlertIfResponseBodyIsEmpty() throws HttpMalformedHeaderException {
// Given
Expand Down Expand Up @@ -115,6 +131,7 @@ void shouldAlertIfContentTypePresentButEmptyInResponse() throws HttpMalformedHea
assertThat(
alertsRaised.get(0).getName(),
equalTo(Constant.messages.getString("pscanrules.contenttypemissing.name.empty")));
assertThat(alertsRaised.get(0).getAlertRef(), is(equalTo("10019-2")));
}

@Test
Expand All @@ -128,5 +145,6 @@ void shouldAlertIfContentTypeNotPresentInResponse() throws HttpMalformedHeaderEx
assertThat(
alertsRaised.get(0).getName(),
equalTo(Constant.messages.getString("pscanrules.contenttypemissing.name")));
assertThat(alertsRaised.get(0).getAlertRef(), is(equalTo("10019-1")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;

import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.platform.commons.util.StringUtils;
import org.parosproxy.paros.core.scanner.Alert;
import org.parosproxy.paros.core.scanner.Plugin.AlertThreshold;
import org.parosproxy.paros.network.HttpHeader;
import org.parosproxy.paros.network.HttpMalformedHeaderException;
Expand Down Expand Up @@ -65,6 +69,25 @@ void shouldReturnExpectedMappings() {
is(equalTo(CommonAlertTag.OWASP_2017_A06_SEC_MISCONFIG.getValue())));
}

@Test
void shouldHaveExpectedExampleAlert() {
// Given / When
List<Alert> alerts = rule.getExampleAlerts();
// Then
assertThat(alerts.size(), is(equalTo(1)));
Alert alert = alerts.get(0);
assertTrue(StringUtils.isNotBlank(alert.getDescription()));
assertTrue(StringUtils.isNotBlank(alert.getSolution()));
assertTrue(StringUtils.isNotBlank(alert.getOtherInfo()));
assertTrue(StringUtils.isNotBlank(alert.getReference()));
}

@Test
@Override
public void shouldHaveValidReferences() {
super.shouldHaveValidReferences();
}

@Test
void xContentTypeOptionsPresent() throws HttpMalformedHeaderException {
// Given
Expand Down

0 comments on commit a45ea07

Please sign in to comment.