aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java55
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java11
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java72
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java1
4 files changed, 139 insertions, 0 deletions
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java b/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java
index 7058a1a3063..b5c9be8a409 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java
@@ -215,6 +215,61 @@ public final class SecurityStandards {
}
}
+ public enum StigSupportedRequirement {
+ V222612("V-222612"),
+ V222578("V-222578"),
+ V222577("V-222577"),
+ V222609("V-222609"),
+ V222608("V-222608"),
+ V222602("V-222602"),
+ V222607("V-222607"),
+ V222604("V-222604"),
+ V222550("V-222550"),
+ V222596("V-222596"),
+ V222620("V-222620"),
+ V222542("V-222542"),
+ V222642("V-222642"),
+ V222567("V-222567"),
+ V222618("V-222618"),
+ V222610("V-222610"),
+ V222579("V-222579"),
+ V222615("V-222615"),
+ V222575("V-222575"),
+ V222576("V-222576"),
+ V222562("V-222562"),
+ V222563("V-222563"),
+ V222603("V-222603"),
+ V222606("V-222606"),
+ V222605("V-222605"),
+ V222391("V-222391"),
+ V222588("V-222588"),
+ V222582("V-222582"),
+ V222519("V-222519"),
+ V222599("V-222599"),
+ V222593("V-222593"),
+ V222597("V-222597"),
+ V222594("V-222594"),
+ V222397("V-222397"),
+ V222534("V-222534"),
+ V222641("V-222641"),
+ V222598("V-222598"),
+ V254803("V-254803"),
+ V222667("V-222667"),
+ V222653("V-222653"),
+ V222649("V-222649");
+
+ private final String requirement;
+
+ StigSupportedRequirement(String requirement) {
+
+ this.requirement = requirement;
+ }
+
+ public String getRequirement() {
+ return requirement;
+ }
+ }
+
public enum PciDss {
R1("1"), R2("2"), R3("3"), R4("4"), R5("5"), R6("6"), R7("7"), R8("8"), R9("9"), R10("10"), R11("11"), R12("12");
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
index 5e4f67e5deb..61f39ec36d0 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
@@ -97,6 +97,7 @@ import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
import org.sonar.server.security.SecurityStandards;
import org.sonar.server.security.SecurityStandards.PciDss;
import org.sonar.server.security.SecurityStandards.SQCategory;
+import org.sonar.server.security.SecurityStandards.StigSupportedRequirement;
import org.sonar.server.user.UserSession;
import org.sonar.server.view.index.ViewIndexDefinition;
import org.springframework.util.CollectionUtils;
@@ -1322,6 +1323,16 @@ public class IssueIndex {
return search(request, includeCwe, version.label());
}
+ public List<SecurityStandardCategoryStatistics> getStig(String projectUuid, boolean isViewOrApp, RulesDefinition.StigVersion stigVersion) {
+ SearchSourceBuilder request = prepareNonClosedVulnerabilitiesAndHotspotSearch(projectUuid, isViewOrApp);
+ Arrays.stream(StigSupportedRequirement.values())
+ .forEach(stigSupportedRequirement -> request.aggregation(
+ newSecurityReportSubAggregations(
+ AggregationBuilders.filter(stigSupportedRequirement.getRequirement(), boolQuery().filter(termQuery(stigVersion.prefix(), stigSupportedRequirement.getRequirement()))),
+ false, null)));
+ return search(request, false, stigVersion.label());
+ }
+
private List<SecurityStandardCategoryStatistics> searchWithLevelDistribution(SearchSourceBuilder sourceBuilder, String version, @Nullable String level) {
return getSearchResponse(sourceBuilder)
.getAggregations().asList().stream()
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java
index 59b3abc0dc3..38b17ff5f3e 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java
@@ -29,6 +29,7 @@ import org.junit.jupiter.api.Test;
import org.sonar.api.issue.Issue;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
+import org.sonar.api.server.rule.RulesDefinition.StigVersion;
import org.sonar.db.component.ComponentDto;
import org.sonar.server.view.index.ViewDoc;
@@ -45,6 +46,8 @@ import static org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version.Y2021;
import static org.sonar.api.server.rule.RulesDefinition.PciDssVersion;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.server.issue.IssueDocTesting.newDocForProject;
+import static org.sonar.server.security.SecurityStandards.StigSupportedRequirement.V222391;
+import static org.sonar.server.security.SecurityStandards.StigSupportedRequirement.V222397;
import static org.sonar.server.security.SecurityStandards.UNKNOWN_STANDARD;
class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
@@ -729,6 +732,75 @@ class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
assertThat(findRuleInCweByYear(cwe2023, "999")).isNull();
}
+ @Test
+ void getStigAsdV5R3_whenRequestingReportOnApplication_ShouldAggregateBasedOnStigRequirement() {
+ ComponentDto application = db.components().insertPrivateApplication().getMainBranchComponent();
+ ComponentDto project1 = db.components().insertPrivateProject().getMainBranchComponent();
+ ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent();
+
+ indexIssues(
+ newDocForProject("openvul1", project1).setStigAsdV5R3(List.of(V222391.getRequirement())).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.MAJOR),
+ newDocForProject("openvul2", project2).setStigAsdV5R3(List.of(V222391.getRequirement())).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+ .setSeverity(Severity.MINOR),
+ newDocForProject("toreviewhotspot", project1).setStigAsdV5R3(List.of(V222397.getRequirement())).setType(RuleType.SECURITY_HOTSPOT)
+ .setStatus(Issue.STATUS_TO_REVIEW),
+
+ newDocForProject("unknown", project2).setStigAsdV5R3(List.of("V-999999")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+ .setSeverity(Severity.MINOR));
+
+ indexView(application.uuid(), asList(project1.uuid(), project2.uuid()));
+
+ Map<String, SecurityStandardCategoryStatistics> statisticsToMap = underTest.getStig(application.uuid(), true, StigVersion.ASD_V5R3)
+ .stream().collect(Collectors.toMap(SecurityStandardCategoryStatistics::getCategory, e -> e));
+
+ assertThat(statisticsToMap).hasSize(41)
+ .hasEntrySatisfying(V222391.getRequirement(), stat -> {
+ assertThat(stat.getVulnerabilities()).isEqualTo(2);
+ assertThat(stat.getToReviewSecurityHotspots()).isZero();
+ assertThat(stat.getReviewedSecurityHotspots()).isZero();
+ })
+ .hasEntrySatisfying(V222397.getRequirement(), stat -> {
+ assertThat(stat.getVulnerabilities()).isZero();
+ assertThat(stat.getToReviewSecurityHotspots()).isEqualTo(1);
+ assertThat(stat.getReviewedSecurityHotspots()).isZero();
+ });
+ }
+
+ @Test
+ void getStigAsdV5R3_whenRequestingReportOnProject_ShouldAggregateBasedOnStigRequirement() {
+ ComponentDto branch = newPrivateProjectDto();
+ indexIssues(
+ newDocForProject("openvul", branch).setStigAsdV5R3(List.of(V222391.getRequirement())).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.MAJOR),
+ newDocForProject("openvul2", branch).setStigAsdV5R3(List.of(V222391.getRequirement())).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.MAJOR),
+ newDocForProject("notopenvul", branch).setStigAsdV5R3(List.of(V222391.getRequirement())).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED)
+ .setResolution(Issue.RESOLUTION_FIXED)
+ .setSeverity(Severity.BLOCKER),
+ newDocForProject("toreviewhotspot", branch).setStigAsdV5R3(List.of(V222397.getRequirement())).setType(RuleType.SECURITY_HOTSPOT)
+ .setStatus(Issue.STATUS_TO_REVIEW),
+ newDocForProject("reviewedHostpot", branch).setStigAsdV5R3(List.of(V222397.getRequirement())).setType(RuleType.SECURITY_HOTSPOT)
+ .setStatus(Issue.STATUS_REVIEWED).setResolution(Issue.RESOLUTION_FIXED));
+
+ Map<String, SecurityStandardCategoryStatistics> statisticsToMap = underTest.getStig(branch.uuid(), false, StigVersion.ASD_V5R3)
+ .stream().collect(Collectors.toMap(SecurityStandardCategoryStatistics::getCategory, e -> e));
+
+ assertThat(statisticsToMap).hasSize(41)
+ .hasEntrySatisfying(V222391.getRequirement(), stat -> {
+ assertThat(stat.getVulnerabilities()).isEqualTo(2);
+ assertThat(stat.getToReviewSecurityHotspots()).isZero();
+ assertThat(stat.getReviewedSecurityHotspots()).isZero();
+ assertThat(stat.getVulnerabilityRating()).as("MAJOR = C").isEqualTo(OptionalInt.of(3));
+ })
+ .hasEntrySatisfying(V222397.getRequirement(), stat -> {
+ assertThat(stat.getVulnerabilities()).isZero();
+ assertThat(stat.getToReviewSecurityHotspots()).isEqualTo(1);
+ assertThat(stat.getReviewedSecurityHotspots()).isEqualTo(1);
+ assertThat(stat.getSecurityReviewRating()).as("50% of hotspots are reviewed, so rating is C").isEqualTo(3);
+ });
+ }
+
private SecurityStandardCategoryStatistics findRuleInCweByYear(SecurityStandardCategoryStatistics statistics, String cweId) {
return statistics.getChildren().stream().filter(stat -> stat.getCategory().equals(cweId)).findAny().orElse(null);
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java
index 29d6d06cccc..aa9d6305f92 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java
@@ -95,6 +95,7 @@ public class IssuesWsParameters {
public static final String PARAM_OWASP_TOP_10 = "owaspTop10";
public static final String PARAM_OWASP_TOP_10_2021 = "owaspTop10-2021";
public static final String PARAM_STIG_ASD_V5R3 = "stig-ASD_V5R3";
+ public static final String PARAM_STIG = "stig";
@Deprecated
public static final String PARAM_SANS_TOP_25 = "sansTop25";
public static final String PARAM_CWE_TOP_25 = "cweTop25";