Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TEST_TIMING alert tag #6015

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion addOns/ascanrules/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ All notable changes to this add-on will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## Unreleased

### Changed
- Scan rules which execute time based attacks now include the "TEST_TIMING" alert tag.

## [70] - 2025-01-09
### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ public class CommandInjectionScanRule extends AbstractAppParamPlugin
CommonAlertTag.toMap(
CommonAlertTag.OWASP_2021_A03_INJECTION,
CommonAlertTag.OWASP_2017_A01_INJECTION,
CommonAlertTag.WSTG_V42_INPV_12_COMMAND_INJ));
CommonAlertTag.WSTG_V42_INPV_12_COMMAND_INJ,
CommonAlertTag.TEST_TIMING));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be included in all alerts raised by the rule which IMHO is misleading.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well it looked like we had decided one example alert was sufficient

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can look at adding it differently.

It kinda needs to be on the rule for docs/site stuff (maybe I can remove it when it isn't a timing alert). Also kinda why I'd asked about rule vs alert tags way back.

I think the same applies for the shell shock rule.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to tweak a few others but how's that look for CMDi now?

alertTags.put(PolicyTag.API.getTag(), "");
alertTags.put(PolicyTag.DEV_CICD.getTag(), "");
alertTags.put(PolicyTag.DEV_STD.getTag(), "");
Expand Down Expand Up @@ -367,6 +368,15 @@ public Map<String, String> getAlertTags() {
return ALERT_TAGS;
}

private Map<String, String> getNeededAlertTags(TestType type) {
Map<String, String> alertTags = new HashMap<>();
alertTags.putAll(getAlertTags());
if (TestType.FEEDBACK.equals(type)) {
alertTags.remove(CommonAlertTag.TEST_TIMING.getTag());
}
return alertTags;
}

@Override
public int getCweId() {
return 78;
Expand Down Expand Up @@ -584,7 +594,14 @@ private boolean testCommandInjection(
paramValue);
String otherInfo = getOtherInfo(TestType.FEEDBACK, paramValue);

buildAlert(paramName, paramValue, matcher.group(), otherInfo, msg).raise();
buildAlert(
paramName,
paramValue,
matcher.group(),
otherInfo,
TestType.FEEDBACK,
msg)
.raise();

// All done. No need to look for vulnerabilities on subsequent
// payloads on the same request (to reduce performance impact)
Expand Down Expand Up @@ -670,7 +687,8 @@ private boolean testCommandInjection(
String otherInfo = getOtherInfo(TestType.TIME, paramValue);

// just attach this alert to the last sent message
buildAlert(paramName, paramValue, "", otherInfo, message.get()).raise();
buildAlert(paramName, paramValue, "", otherInfo, TestType.TIME, message.get())
.raise();

// All done. No need to look for vulnerabilities on subsequent
// payloads on the same request (to reduce performance impact)
Expand Down Expand Up @@ -719,14 +737,20 @@ private static String insertUninitVar(String cmd) {
}

private AlertBuilder buildAlert(
String param, String attack, String evidence, String otherInfo, HttpMessage msg) {
String param,
String attack,
String evidence,
String otherInfo,
TestType type,
HttpMessage msg) {
return newAlert()
.setConfidence(Alert.CONFIDENCE_MEDIUM)
.setParam(param)
.setAttack(attack)
.setEvidence(evidence)
.setMessage(msg)
.setOtherInfo(otherInfo);
.setOtherInfo(otherInfo)
.setTags(getNeededAlertTags(type));
}

@Override
Expand All @@ -737,6 +761,7 @@ public List<Alert> getExampleAlerts() {
"a;cat /etc/passwd ",
"root:x:0:0",
getOtherInfo(TestType.FEEDBACK, "a;cat /etc/passwd "),
TestType.FEEDBACK,
null)
.build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ public class SqlInjectionHypersonicScanRule extends AbstractAppParamPlugin
CommonAlertTag.toMap(
CommonAlertTag.OWASP_2021_A03_INJECTION,
CommonAlertTag.OWASP_2017_A01_INJECTION,
CommonAlertTag.WSTG_V42_INPV_05_SQLI));
CommonAlertTag.WSTG_V42_INPV_05_SQLI,
CommonAlertTag.TEST_TIMING));
alertTags.put(PolicyTag.DEV_FULL.getTag(), "");
alertTags.put(PolicyTag.QA_STD.getTag(), "");
alertTags.put(PolicyTag.QA_FULL.getTag(), "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ public class SqlInjectionMsSqlScanRule extends AbstractAppParamPlugin
CommonAlertTag.toMap(
CommonAlertTag.OWASP_2021_A03_INJECTION,
CommonAlertTag.OWASP_2017_A01_INJECTION,
CommonAlertTag.WSTG_V42_INPV_05_SQLI));
CommonAlertTag.WSTG_V42_INPV_05_SQLI,
CommonAlertTag.TEST_TIMING));
alertTags.put(PolicyTag.DEV_FULL.getTag(), "");
alertTags.put(PolicyTag.QA_STD.getTag(), "");
alertTags.put(PolicyTag.QA_FULL.getTag(), "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ public class SqlInjectionMySqlScanRule extends AbstractAppParamPlugin
CommonAlertTag.toMap(
CommonAlertTag.OWASP_2021_A03_INJECTION,
CommonAlertTag.OWASP_2017_A01_INJECTION,
CommonAlertTag.WSTG_V42_INPV_05_SQLI));
CommonAlertTag.WSTG_V42_INPV_05_SQLI,
CommonAlertTag.TEST_TIMING));
alertTags.put(PolicyTag.DEV_FULL.getTag(), "");
alertTags.put(PolicyTag.QA_STD.getTag(), "");
alertTags.put(PolicyTag.QA_FULL.getTag(), "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ public class SqlInjectionOracleScanRule extends AbstractAppParamPlugin
CommonAlertTag.toMap(
CommonAlertTag.OWASP_2021_A03_INJECTION,
CommonAlertTag.OWASP_2017_A01_INJECTION,
CommonAlertTag.WSTG_V42_INPV_05_SQLI));
CommonAlertTag.WSTG_V42_INPV_05_SQLI,
CommonAlertTag.TEST_TIMING));
alertTags.put(PolicyTag.DEV_FULL.getTag(), "");
alertTags.put(PolicyTag.QA_STD.getTag(), "");
alertTags.put(PolicyTag.QA_FULL.getTag(), "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ public class SqlInjectionPostgreScanRule extends AbstractAppParamPlugin
CommonAlertTag.toMap(
CommonAlertTag.OWASP_2021_A03_INJECTION,
CommonAlertTag.OWASP_2017_A01_INJECTION,
CommonAlertTag.WSTG_V42_INPV_05_SQLI));
CommonAlertTag.WSTG_V42_INPV_05_SQLI,
CommonAlertTag.TEST_TIMING));
alertTags.put(PolicyTag.DEV_FULL.getTag(), "");
alertTags.put(PolicyTag.QA_STD.getTag(), "");
alertTags.put(PolicyTag.QA_FULL.getTag(), "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ public class SqlInjectionSqLiteScanRule extends AbstractAppParamPlugin
CommonAlertTag.toMap(
CommonAlertTag.OWASP_2021_A03_INJECTION,
CommonAlertTag.OWASP_2017_A01_INJECTION,
CommonAlertTag.WSTG_V42_INPV_05_SQLI));
CommonAlertTag.WSTG_V42_INPV_05_SQLI,
CommonAlertTag.TEST_TIMING));
alertTags.put(PolicyTag.QA_FULL.getTag(), "");
ALERT_TAGS = Collections.unmodifiableMap(alertTags);
}
Expand Down Expand Up @@ -458,6 +459,7 @@ public void scan(HttpMessage originalMessage, String paramName, String originalP
.setOtherInfo(extraInfo)
.setEvidence(matcher.group())
.setMessage(msgDelay)
.setTags(getNeededAlertTags(true))
.raise();

LOGGER.debug(
Expand Down Expand Up @@ -600,6 +602,7 @@ public void scan(HttpMessage originalMessage, String paramName, String originalP
.setOtherInfo(extraInfo)
.setEvidence(extraInfo)
.setMessage(detectableDelayMessage)
.setTags(getNeededAlertTags(false))
.raise();

if (detectableDelayMessage != null)
Expand Down Expand Up @@ -752,6 +755,7 @@ public void scan(HttpMessage originalMessage, String paramName, String originalP
.setOtherInfo(extraInfo)
.setEvidence(versionNumber)
.setMessage(unionAttackMessage)
.setTags(getNeededAlertTags(true))
.raise();
break unionLoops;
}
Expand Down Expand Up @@ -804,4 +808,13 @@ public int getWascId() {
public Map<String, String> getAlertTags() {
return ALERT_TAGS;
}

private Map<String, String> getNeededAlertTags(boolean isFeedbackbased) {
Map<String, String> alertTags = new HashMap<>();
alertTags.putAll(getAlertTags());
if (isFeedbackbased) {
alertTags.remove(CommonAlertTag.TEST_TIMING.getTag());
}
return alertTags;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ public class SstiBlindScanRule extends AbstractAppParamPlugin implements CommonA
CommonAlertTag.toMap(
CommonAlertTag.OWASP_2021_A03_INJECTION,
CommonAlertTag.OWASP_2017_A01_INJECTION,
CommonAlertTag.WSTG_V42_INPV_18_SSTI));
CommonAlertTag.WSTG_V42_INPV_18_SSTI,
CommonAlertTag.TEST_TIMING));
alertTags.put(ExtensionOast.OAST_ALERT_TAG_KEY, ExtensionOast.OAST_ALERT_TAG_VALUE);
alertTags.put(PolicyTag.API.getTag(), "");
alertTags.put(PolicyTag.DEV_FULL.getTag(), "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
Expand Down Expand Up @@ -95,7 +96,7 @@ void shouldReturnExpectedMappings() {
// Then
assertThat(cwe, is(equalTo(78)));
assertThat(wasc, is(equalTo(31)));
assertThat(tags.size(), is(equalTo(10)));
assertThat(tags.size(), is(equalTo(11)));
assertThat(
tags.containsKey(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(true)));
Expand Down Expand Up @@ -378,6 +379,8 @@ void shouldHaveExpectedExampleAlert() {
"The scan rule was able to retrieve the content of a file or "
+ "command by sending [a;cat /etc/passwd ] to the operating "
+ "system running this application.")));
Map<String, String> tags = alert.getTags();
assertThat(tags, not(hasKey(CommonAlertTag.TEST_TIMING.getTag())));
}

private static class PayloadCollectorHandler extends NanoServerHandler {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ void shouldReturnExpectedMappings() {
// Then
assertThat(cwe, is(equalTo(89)));
assertThat(wasc, is(equalTo(19)));
assertThat(tags.size(), is(equalTo(7)));
assertThat(tags.size(), is(equalTo(8)));
assertThat(
tags.containsKey(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(true)));
Expand All @@ -168,6 +168,7 @@ void shouldReturnExpectedMappings() {
assertThat(tags.containsKey(PolicyTag.QA_STD.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.QA_FULL.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.SEQUENCE.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(CommonAlertTag.TEST_TIMING.getTag()), is(equalTo(true)));
assertThat(
tags.get(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(CommonAlertTag.OWASP_2021_A03_INJECTION.getValue())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ void shouldReturnExpectedMappings() {
// Then
assertThat(cwe, is(equalTo(89)));
assertThat(wasc, is(equalTo(19)));
assertThat(tags.size(), is(equalTo(7)));
assertThat(tags.size(), is(equalTo(8)));
assertThat(
tags.containsKey(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(true)));
Expand All @@ -163,6 +163,7 @@ void shouldReturnExpectedMappings() {
assertThat(tags.containsKey(PolicyTag.QA_STD.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.QA_FULL.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.SEQUENCE.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(CommonAlertTag.TEST_TIMING.getTag()), is(equalTo(true)));
assertThat(
tags.get(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(CommonAlertTag.OWASP_2021_A03_INJECTION.getValue())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ void shouldReturnExpectedMappings() {
// Then
assertThat(cwe, is(equalTo(89)));
assertThat(wasc, is(equalTo(19)));
assertThat(tags.size(), is(equalTo(7)));
assertThat(tags.size(), is(equalTo(8)));
assertThat(
tags.containsKey(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(true)));
Expand All @@ -162,6 +162,7 @@ void shouldReturnExpectedMappings() {
assertThat(tags.containsKey(PolicyTag.QA_STD.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.QA_FULL.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.SEQUENCE.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(CommonAlertTag.TEST_TIMING.getTag()), is(equalTo(true)));
assertThat(
tags.get(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(CommonAlertTag.OWASP_2021_A03_INJECTION.getValue())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ void shouldReturnExpectedMappings() {
// Then
assertThat(cwe, is(equalTo(89)));
assertThat(wasc, is(equalTo(19)));
assertThat(tags.size(), is(equalTo(7)));
assertThat(tags.size(), is(equalTo(8)));
assertThat(
tags.containsKey(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(true)));
Expand All @@ -158,6 +158,7 @@ void shouldReturnExpectedMappings() {
assertThat(tags.containsKey(PolicyTag.QA_STD.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.QA_FULL.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.SEQUENCE.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(CommonAlertTag.TEST_TIMING.getTag()), is(equalTo(true)));
assertThat(
tags.get(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(CommonAlertTag.OWASP_2021_A03_INJECTION.getValue())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void shouldReturnExpectedMappings() {
// Then
assertThat(cwe, is(equalTo(89)));
assertThat(wasc, is(equalTo(19)));
assertThat(tags.size(), is(equalTo(7)));
assertThat(tags.size(), is(equalTo(8)));
assertThat(
tags.containsKey(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(true)));
Expand All @@ -171,6 +171,7 @@ void shouldReturnExpectedMappings() {
assertThat(tags.containsKey(PolicyTag.QA_STD.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.QA_FULL.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.SEQUENCE.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(CommonAlertTag.TEST_TIMING.getTag()), is(equalTo(true)));
assertThat(
tags.get(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(CommonAlertTag.OWASP_2021_A03_INJECTION.getValue())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;

import fi.iki.elonen.NanoHTTPD.IHTTPSession;
Expand Down Expand Up @@ -114,6 +116,7 @@ protected Response serve(IHTTPSession session) {
equalTo("case randomblob(100000) when not null then 1 else 1 end "));
assertThat(alertsRaised.get(0).getRisk(), equalTo(Alert.RISK_HIGH));
assertThat(alertsRaised.get(0).getConfidence(), equalTo(Alert.CONFIDENCE_MEDIUM));
assertThat(alertsRaised.get(0).getTags(), not(hasKey(CommonAlertTag.TEST_TIMING.getTag())));
}

@Test
Expand Down Expand Up @@ -155,6 +158,7 @@ protected Response serve(IHTTPSession session) {
assertThat(alertsRaised.get(0).getAttack(), startsWith("case randomblob(100"));
assertThat(alertsRaised.get(0).getRisk(), equalTo(Alert.RISK_HIGH));
assertThat(alertsRaised.get(0).getConfidence(), equalTo(Alert.CONFIDENCE_MEDIUM));
assertThat(alertsRaised.get(0).getTags(), is(hasKey(CommonAlertTag.TEST_TIMING.getTag())));
}

@Test
Expand Down Expand Up @@ -197,7 +201,7 @@ void shouldReturnExpectedMappings() {
// Then
assertThat(cwe, is(equalTo(89)));
assertThat(wasc, is(equalTo(19)));
assertThat(tags.size(), is(equalTo(4)));
assertThat(tags.size(), is(equalTo(5)));
assertThat(
tags.containsKey(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(true)));
Expand All @@ -207,6 +211,7 @@ void shouldReturnExpectedMappings() {
assertThat(
tags.containsKey(CommonAlertTag.WSTG_V42_INPV_05_SQLI.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.QA_FULL.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(CommonAlertTag.TEST_TIMING.getTag()), is(equalTo(true)));
assertThat(
tags.get(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(CommonAlertTag.OWASP_2021_A03_INJECTION.getValue())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void shouldReturnExpectedMappings() {
// Then
assertThat(cwe, is(equalTo(1336)));
assertThat(wasc, is(equalTo(20)));
assertThat(tags.size(), is(equalTo(8)));
assertThat(tags.size(), is(equalTo(9)));
assertThat(
tags.containsKey(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(true)));
Expand All @@ -157,6 +157,7 @@ void shouldReturnExpectedMappings() {
assertThat(tags.containsKey(PolicyTag.DEV_FULL.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.QA_FULL.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(PolicyTag.SEQUENCE.getTag()), is(equalTo(true)));
assertThat(tags.containsKey(CommonAlertTag.TEST_TIMING.getTag()), is(equalTo(true)));
assertThat(
tags.get(CommonAlertTag.OWASP_2021_A03_INJECTION.getTag()),
is(equalTo(CommonAlertTag.OWASP_2021_A03_INJECTION.getValue())));
Expand Down
Loading
Loading