import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.sonar.api.server.rule.RulesDefinition.OwaspAsvsVersion;
+import static org.sonar.api.server.rule.RulesDefinition.PciDssVersion;
import static org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version.Y2017;
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.UNKNOWN_STANDARD;
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 {
ComponentDto project = newPrivateProjectDto();
ComponentDto another = newPrivateProjectDto();
- IssueDoc openVulDoc = newDocForProject("openvul1", project).setOwaspTop10(singletonList("a1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.MAJOR);
+ IssueDoc openVulDoc = newDocForProject("openvul1", project).setOwaspTop10(singletonList("a1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.MAJOR);
openVulDoc.setOwaspTop10For2021(singletonList("a2")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.MAJOR);
- IssueDoc otherProjectDoc = newDocForProject("anotherProject", another).setOwaspTop10(singletonList("a1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL);
+ IssueDoc otherProjectDoc = newDocForProject("anotherProject", another).setOwaspTop10(singletonList("a1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.CRITICAL);
otherProjectDoc.setOwaspTop10For2021(singletonList("a2")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL);
indexIssues(openVulDoc, otherProjectDoc);
newDocForProject("openvul12021", project).setOwaspTop10For2021(List.of("a2")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.MAJOR),
newDocForProject("notopenvul", project).setOwaspTop10(List.of("a1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED).setResolution(Issue.RESOLUTION_FIXED)
.setSeverity(Severity.BLOCKER),
- newDocForProject("notopenvul2021", project).setOwaspTop10For2021(List.of("a2")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED).setResolution(Issue.RESOLUTION_FIXED)
+ newDocForProject("notopenvul2021", project).setOwaspTop10For2021(List.of("a2")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED)
+ .setResolution(Issue.RESOLUTION_FIXED)
.setSeverity(Severity.BLOCKER));
List<SecurityStandardCategoryStatistics> owaspTop10Report = underTest.getOwaspTop10Report(project.uuid(), false, false, Y2017);
.collect(Collectors.toMap(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getChildren));
assertThat(cweByOwasp.get("a1")).extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getVulnerabilities,
- SecurityStandardCategoryStatistics::getVulnerabilityRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
- SecurityStandardCategoryStatistics::getReviewedSecurityHotspots, SecurityStandardCategoryStatistics::getSecurityReviewRating)
+ SecurityStandardCategoryStatistics::getVulnerabilityRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
+ SecurityStandardCategoryStatistics::getReviewedSecurityHotspots, SecurityStandardCategoryStatistics::getSecurityReviewRating)
.containsExactlyInAnyOrder(
tuple("123", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 1),
tuple("456", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 1),
tuple("unknown", 0L, OptionalInt.empty(), 1L /* openhotspot1 */, 0L, 5));
assertThat(cweByOwasp.get("a3")).extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getVulnerabilities,
- SecurityStandardCategoryStatistics::getVulnerabilityRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
- SecurityStandardCategoryStatistics::getReviewedSecurityHotspots, SecurityStandardCategoryStatistics::getSecurityReviewRating)
+ SecurityStandardCategoryStatistics::getVulnerabilityRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
+ SecurityStandardCategoryStatistics::getReviewedSecurityHotspots, SecurityStandardCategoryStatistics::getSecurityReviewRating)
.containsExactlyInAnyOrder(
tuple("123", 2L /* openvul1, openvul2 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 1),
tuple("456", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 1),
.collect(Collectors.toMap(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getChildren));
assertThat(cweByOwasp.get("a1")).extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getVulnerabilities,
- SecurityStandardCategoryStatistics::getVulnerabilityRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
- SecurityStandardCategoryStatistics::getReviewedSecurityHotspots, SecurityStandardCategoryStatistics::getSecurityReviewRating)
+ SecurityStandardCategoryStatistics::getVulnerabilityRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
+ SecurityStandardCategoryStatistics::getReviewedSecurityHotspots, SecurityStandardCategoryStatistics::getSecurityReviewRating)
.containsExactlyInAnyOrder(
tuple("123", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 1),
tuple("456", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 1),
tuple("unknown", 0L, OptionalInt.empty(), 1L /* openhotspot1 */, 0L, 5));
assertThat(cweByOwasp.get("a3")).extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getVulnerabilities,
- SecurityStandardCategoryStatistics::getVulnerabilityRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
- SecurityStandardCategoryStatistics::getReviewedSecurityHotspots, SecurityStandardCategoryStatistics::getSecurityReviewRating)
+ SecurityStandardCategoryStatistics::getVulnerabilityRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
+ SecurityStandardCategoryStatistics::getReviewedSecurityHotspots, SecurityStandardCategoryStatistics::getSecurityReviewRating)
.containsExactlyInAnyOrder(
tuple("123", 2L /* openvul1, openvul2 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 1),
tuple("456", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 1),
.setSeverity(Severity.MAJOR),
newDocForProject("openvul2", project).setOwaspTop10(asList("a3", "a6")).setCwe(List.of("123")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
.setSeverity(Severity.MINOR),
- newDocForProject("notowaspvul", project).setOwaspTop10(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
+ newDocForProject("notowaspvul", project).setOwaspTop10(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.CRITICAL),
newDocForProject("toreviewhotspot1", project).setOwaspTop10(asList("a1", "a3")).setCwe(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT)
.setStatus(Issue.STATUS_TO_REVIEW),
newDocForProject("toreviewhotspot2", project).setOwaspTop10(asList("a3", "a6")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
.setSeverity(Severity.MINOR),
newDocForProject("openvul3", project).setPciDss32(asList("10.1.2", "6.5")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
.setSeverity(Severity.MINOR),
- newDocForProject("notpcidssvul", project).setPciDss32(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
+ newDocForProject("notpcidssvul", project).setPciDss32(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.CRITICAL),
newDocForProject("toreviewhotspot1", project).setPciDss32(asList("1.3.0", "3.3.2")).setType(RuleType.SECURITY_HOTSPOT)
.setStatus(Issue.STATUS_TO_REVIEW),
newDocForProject("toreviewhotspot2", project).setPciDss32(asList("3.5.6", "6.4.5")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
.setSeverity(Severity.MINOR),
newDocForProject("openvul3", project).setOwaspAsvs40(asList("10.2.4", "6.2.8")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
.setSeverity(Severity.MINOR),
- newDocForProject("notowaspasvsvul", project).setOwaspAsvs40(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
+ newDocForProject("notowaspasvsvul", project).setOwaspAsvs40(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.CRITICAL),
newDocForProject("toreviewhotspot1", project).setOwaspAsvs40(asList("2.2.5", "3.2.4")).setType(RuleType.SECURITY_HOTSPOT)
.setStatus(Issue.STATUS_TO_REVIEW),
newDocForProject("toreviewhotspot2", project).setOwaspAsvs40(asList("3.6.1", "7.1.1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
.setSeverity(Severity.MAJOR),
newDocForProject("openvul2", project).setOwaspTop10For2021(asList("a3", "a6")).setCwe(List.of("123")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
.setSeverity(Severity.MINOR),
- newDocForProject("notowaspvul", project).setOwaspTop10For2021(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
+ newDocForProject("notowaspvul", project).setOwaspTop10For2021(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.CRITICAL),
newDocForProject("toreviewhotspot1", project).setOwaspTop10For2021(asList("a1", "a3")).setCwe(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT)
.setStatus(Issue.STATUS_TO_REVIEW),
newDocForProject("toreviewhotspot2", project).setOwaspTop10For2021(asList("a3", "a6")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
.setSeverity(Severity.MINOR),
newDocForProject("openvul3", project1).setPciDss32(asList("10.1.2", "6.5")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
.setSeverity(Severity.MINOR),
- newDocForProject("notpcidssvul", project1).setPciDss32(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
+ newDocForProject("notpcidssvul", project1).setPciDss32(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.CRITICAL),
newDocForProject("toreviewhotspot1", project2).setPciDss32(asList("1.3.0", "3.3.2")).setType(RuleType.SECURITY_HOTSPOT)
.setStatus(Issue.STATUS_TO_REVIEW),
newDocForProject("toreviewhotspot2", project1).setPciDss32(asList("3.5.6", "6.4.5")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
.setSeverity(Severity.MINOR),
newDocForProject("openvul3", project1).setOwaspAsvs40(asList("10.3.2", "6.2.1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
.setSeverity(Severity.MINOR),
- newDocForProject("notowaspasvsvul", project1).setOwaspAsvs40(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
+ newDocForProject("notowaspasvsvul", project1).setOwaspAsvs40(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.CRITICAL),
newDocForProject("toreviewhotspot1", project2).setOwaspAsvs40(asList("2.1.3", "3.3.2")).setType(RuleType.SECURITY_HOTSPOT)
.setStatus(Issue.STATUS_TO_REVIEW),
newDocForProject("toreviewhotspot2", project1).setOwaspAsvs40(asList("3.4.4", "6.2.1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
assertThat(findRuleInCweByYear(cwe2021, "295")).isNull();
assertThat(findRuleInCweByYear(cwe2021, "999")).isNull();
-
SecurityStandardCategoryStatistics cwe2022 = cweTop25Reports.stream()
.filter(s -> s.getCategory().equals("2022"))
.findAny().get();
}
@Test
- void getStigAsdV5R3_whenRequestingReportOnApplication_ShouldAggregateBasedOnStigRequirement() {
+ void getStigAsdV5R3_whenRequestingReportOnApplication_ShouldAggregateBasedOnStigReportRequirement() {
ComponentDto application = db.components().insertPrivateApplication().getMainBranchComponent();
ComponentDto project1 = db.components().insertPrivateProject().getMainBranchComponent();
ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent();
indexView(application.uuid(), asList(project1.uuid(), project2.uuid()));
- Map<String, SecurityStandardCategoryStatistics> statisticsToMap = underTest.getStig(application.uuid(), true, StigVersion.ASD_V5R3)
+ Map<String, SecurityStandardCategoryStatistics> statisticsToMap = underTest.getStigReport(application.uuid(), true, StigVersion.ASD_V5R3)
.stream().collect(Collectors.toMap(SecurityStandardCategoryStatistics::getCategory, e -> e));
assertThat(statisticsToMap).hasSize(41)
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)
+ Map<String, SecurityStandardCategoryStatistics> statisticsToMap = underTest.getStigReport(branch.uuid(), false, StigVersion.ASD_V5R3)
.stream().collect(Collectors.toMap(SecurityStandardCategoryStatistics::getCategory, e -> e));
assertThat(statisticsToMap).hasSize(41)
});
}
+ @Test
+ void getCasa_whenRequestingReportOnProject_ShouldAggregateBasedOnCasaReportRequirement() {
+ ComponentDto branch = newPrivateProjectDto();
+ indexIssues(
+ newDocForProject("openvul", branch).setCasa(List.of("2.6.1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.MAJOR),
+ newDocForProject("openvul2", branch).setCasa(List.of("2.6.1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.MAJOR),
+ newDocForProject("notopenvul", branch).setCasa(List.of("2.6.1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED)
+ .setResolution(Issue.RESOLUTION_FIXED)
+ .setSeverity(Severity.BLOCKER),
+ newDocForProject("toreviewhotspot", branch).setCasa(List.of("2.7.6")).setType(RuleType.SECURITY_HOTSPOT)
+ .setStatus(Issue.STATUS_TO_REVIEW),
+ newDocForProject("reviewedHostpot", branch).setCasa(List.of("2.7.6")).setType(RuleType.SECURITY_HOTSPOT)
+ .setStatus(Issue.STATUS_REVIEWED).setResolution(Issue.RESOLUTION_FIXED));
+
+ Map<String, SecurityStandardCategoryStatistics> statisticsToMap = toMap(underTest.getCasaReport(branch.uuid(), false));
+
+ assertThat(statisticsToMap).hasSize(14)
+ .hasEntrySatisfying("2", stat -> {
+ assertThat(stat.getVulnerabilities()).isEqualTo(2);
+ assertThat(stat.getToReviewSecurityHotspots()).isEqualTo(1);
+ assertThat(stat.getReviewedSecurityHotspots()).isEqualTo(1);
+ assertThat(stat.getVersion()).isEmpty();
+ assertThat(toMap(stat.getChildren()))
+ .hasSize(2)
+ .hasEntrySatisfying("2.6.1", cat -> {
+ assertThat(cat.getVulnerabilities()).isEqualTo(2);
+ assertThat(cat.getToReviewSecurityHotspots()).isZero();
+ assertThat(cat.getReviewedSecurityHotspots()).isZero();
+ assertThat(cat.getVulnerabilityRating()).as("MAJOR = C").isEqualTo(OptionalInt.of(3));
+ })
+ .hasEntrySatisfying("2.7.6", cat -> {
+ assertThat(cat.getVulnerabilities()).isZero();
+ assertThat(cat.getToReviewSecurityHotspots()).isEqualTo(1);
+ assertThat(cat.getReviewedSecurityHotspots()).isEqualTo(1);
+ assertThat(stat.getSecurityReviewRating()).as("50% of hotspots are reviewed, so rating is C").isEqualTo(3);
+ });
+ });
+ }
+
+ @Test
+ void getCasa_whenRequestingReportOnApplication_ShouldAggregateBasedOnCasaReportRequirement() {
+ ComponentDto application = db.components().insertPrivateApplication().getMainBranchComponent();
+ ComponentDto project1 = db.components().insertPrivateProject().getMainBranchComponent();
+ ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent();
+
+ indexIssues(
+ newDocForProject("openvul1", project1).setCasa(List.of("2.6.1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+ .setSeverity(Severity.MAJOR),
+ newDocForProject("openvul2", project2).setCasa(List.of("2.6.1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+ .setSeverity(Severity.MINOR),
+ newDocForProject("toreviewhotspot", project1).setCasa(List.of("2.6.1")).setType(RuleType.SECURITY_HOTSPOT)
+ .setStatus(Issue.STATUS_TO_REVIEW),
+
+ newDocForProject("unknown", project2).setCasa(List.of("2.7.6")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+ .setSeverity(Severity.MINOR));
+
+ indexView(application.uuid(), asList(project1.uuid(), project2.uuid()));
+
+ Map<String, SecurityStandardCategoryStatistics> statisticsToMap = underTest.getCasaReport(application.uuid(), true)
+ .stream().collect(Collectors.toMap(SecurityStandardCategoryStatistics::getCategory, e -> e));
+
+ assertThat(statisticsToMap).hasSize(14)
+ .hasEntrySatisfying("2", stat -> {
+ assertThat(toMap(stat.getChildren()))
+ .hasSize(2)
+ .hasEntrySatisfying("2.6.1", cat -> {
+ assertThat(cat.getVulnerabilities()).isEqualTo(2);
+ assertThat(cat.getToReviewSecurityHotspots()).isEqualTo(1);
+ assertThat(cat.getReviewedSecurityHotspots()).isZero();
+ })
+ .hasEntrySatisfying("2.7.6", cat -> {
+ assertThat(cat.getVulnerabilities()).isEqualTo(1);
+ assertThat(cat.getToReviewSecurityHotspots()).isZero();
+ assertThat(cat.getReviewedSecurityHotspots()).isZero();
+ });
+ });
+ }
+
+ private static Map<String, SecurityStandardCategoryStatistics> toMap(List<SecurityStandardCategoryStatistics> statistics) {
+ return statistics.stream().collect(Collectors.toMap(SecurityStandardCategoryStatistics::getCategory, e -> e));
+ }
+
private SecurityStandardCategoryStatistics findRuleInCweByYear(SecurityStandardCategoryStatistics statistics, String cweId) {
return statistics.getChildren().stream().filter(stat -> stat.getCategory().equals(cweId)).findAny().orElse(null);
}