From 89e0b829278573111edc3d0ac50347e5a7f9ccf6 Mon Sep 17 00:00:00 2001 From: Matteo Mara Date: Tue, 4 Oct 2022 16:11:07 +0200 Subject: SONAR-17399 add owasp asvs 40 level support in security_report show API --- .../server/issue/index/IssueIndexDefinition.java | 2 ++ .../index/SecurityStandardCategoryStatistics.java | 10 +++++++++ .../sonar/server/security/SecurityStandards.java | 13 ++++------- .../sonar/server/issue/index/IssueIndexerTest.java | 3 ++- .../SecurityStandardCategoryStatisticsTest.java | 3 ++- .../server/security/SecurityStandardsTest.java | 26 +++++++++++++--------- 6 files changed, 36 insertions(+), 21 deletions(-) (limited to 'server/sonar-server-common') diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java index 0eaccdeb01e..2fa1f9f9751 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java @@ -99,6 +99,7 @@ public class IssueIndexDefinition implements IndexDefinition { public static final String FIELD_ISSUE_PCI_DSS_32 = "pciDss-3.2"; public static final String FIELD_ISSUE_PCI_DSS_40 = "pciDss-4.0"; public static final String FIELD_ISSUE_OWASP_ASVS_40 = "owaspAsvs-4.0"; + public static final String FIELD_ISSUE_OWASP_ASVS_40_LEVEL = "owaspAsvs-4.0-level"; public static final String FIELD_ISSUE_OWASP_TOP_10 = "owaspTop10"; public static final String FIELD_ISSUE_OWASP_TOP_10_2021 = "owaspTop10-2021"; public static final String FIELD_ISSUE_SANS_TOP_25 = "sansTop25"; @@ -170,6 +171,7 @@ public class IssueIndexDefinition implements IndexDefinition { mapping.keywordFieldBuilder(FIELD_ISSUE_PCI_DSS_32).disableNorms().build(); mapping.keywordFieldBuilder(FIELD_ISSUE_PCI_DSS_40).disableNorms().build(); mapping.keywordFieldBuilder(FIELD_ISSUE_OWASP_ASVS_40).disableNorms().build(); + mapping.keywordFieldBuilder(FIELD_ISSUE_OWASP_ASVS_40_LEVEL).disableNorms().build(); mapping.keywordFieldBuilder(FIELD_ISSUE_OWASP_TOP_10).disableNorms().build(); mapping.keywordFieldBuilder(FIELD_ISSUE_OWASP_TOP_10_2021).disableNorms().build(); mapping.keywordFieldBuilder(FIELD_ISSUE_SANS_TOP_25).disableNorms().build(); diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java index aca4b7ca159..8c16e006450 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java @@ -37,6 +37,7 @@ public class SecurityStandardCategoryStatistics { private long totalRules; private boolean hasMoreRules; private final Optional version; + private Optional level = Optional.empty(); public SecurityStandardCategoryStatistics(String category, long vulnerabilities, OptionalInt vulnerabiliyRating, long toReviewSecurityHotspots, long reviewedSecurityHotspots, Integer securityReviewRating, @Nullable List children, @Nullable String version) { @@ -96,6 +97,15 @@ public class SecurityStandardCategoryStatistics { return version; } + public Optional getLevel() { + return level; + } + + public SecurityStandardCategoryStatistics setLevel(String level) { + this.level = Optional.of(level); + return this; + } + public SecurityStandardCategoryStatistics setTotalRules(long totalRules) { this.totalRules = totalRules; return this; 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 171991db872..e450c323e92 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 @@ -24,7 +24,6 @@ import com.google.common.collect.Ordering; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -124,8 +123,6 @@ public final class SecurityStandards { 2, OWASP_ASVS_40_LEVEL_2, 3, OWASP_ASVS_40_LEVEL_3); - public static final Map OWASP_ASVS_40_LEVEL_BY_REQUIREMENT = Collections.unmodifiableMap(getLevelByRequirementMap()); - public static final Map>> OWASP_ASVS_REQUIREMENTS_BY_LEVEL = Map.of( OwaspAsvsVersion.V4_0, OWASP_ASVS_40_REQUIREMENTS_BY_LEVEL); @@ -333,12 +330,10 @@ public final class SecurityStandards { return new SecurityStandards(standards, cwe, sqCategory, ignoredSQCategories); } - private static Map getLevelByRequirementMap() { - Map levelByRequirement = new HashMap<>(); - OWASP_ASVS_40_LEVEL_3.forEach(req -> levelByRequirement.put(req, 3)); - OWASP_ASVS_40_LEVEL_2.forEach(req -> levelByRequirement.put(req, 2)); - OWASP_ASVS_40_LEVEL_1.forEach(req -> levelByRequirement.put(req, 1)); - return levelByRequirement; + public static Set getRequirementsForCategoryAndLevel(OwaspAsvs category, int level) { + return OWASP_ASVS_40_REQUIREMENTS_BY_LEVEL.get(level).stream() + .filter(req -> req.startsWith(category.category() + ".")) + .collect(Collectors.toSet()); } private static Set getMatchingStandards(Set securityStandards, String prefix) { diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java index 9f88638c7a7..dc641aaf306 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java @@ -138,7 +138,7 @@ public class IssueIndexerTest { @Test public void verify_security_standards_indexation() { - RuleDto rule = db.rules().insert(r -> r.setSecurityStandards(new HashSet<>(Arrays.asList("cwe:123", "owaspTop10:a3", "cwe:863")))); + RuleDto rule = db.rules().insert(r -> r.setSecurityStandards(new HashSet<>(Arrays.asList("cwe:123", "owaspTop10:a3", "cwe:863","owaspAsvs-4.0:2.1.1")))); ComponentDto project = db.components().insertPrivateProject(); ComponentDto dir = db.components().insertComponent(ComponentTesting.newDirectory(project, "src/main/java/foo")); ComponentDto file = db.components().insertComponent(newFileDto(project, dir, "F1")); @@ -149,6 +149,7 @@ public class IssueIndexerTest { IssueDoc doc = es.getDocuments(TYPE_ISSUE, IssueDoc.class).get(0); assertThat(doc.getCwe()).containsExactlyInAnyOrder("123", "863"); assertThat(doc.getOwaspTop10()).containsExactlyInAnyOrder("a3"); + assertThat(doc.getOwaspAsvs40()).containsExactlyInAnyOrder("2.1.1"); assertThat(doc.getSansTop25()).containsExactlyInAnyOrder(SANS_TOP_25_POROUS_DEFENSES); } diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/SecurityStandardCategoryStatisticsTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/SecurityStandardCategoryStatisticsTest.java index 2cf9e0a7f5a..b81b2c2ab08 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/SecurityStandardCategoryStatisticsTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/SecurityStandardCategoryStatisticsTest.java @@ -51,7 +51,7 @@ public class SecurityStandardCategoryStatisticsTest { SecurityStandardCategoryStatistics standardCategoryStatistics = new SecurityStandardCategoryStatistics( "cat", 1, empty(), 0, 0, 5, new ArrayList<>(), "version" - ); + ).setLevel("1"); standardCategoryStatistics.setActiveRules(3); standardCategoryStatistics.setTotalRules(3); @@ -67,6 +67,7 @@ public class SecurityStandardCategoryStatisticsTest { assertThat(standardCategoryStatistics.getTotalRules()).isEqualTo(3); assertThat(standardCategoryStatistics.getVersion()).isPresent(); assertThat(standardCategoryStatistics.getVersion().get()).contains("version"); + assertThat(standardCategoryStatistics.getLevel().get()).contains("1"); assertThat(standardCategoryStatistics.hasMoreRules()).isFalse(); } diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityStandardsTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityStandardsTest.java index a9d6a045923..31a32ebd48c 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityStandardsTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityStandardsTest.java @@ -37,10 +37,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.sonar.server.security.SecurityStandards.CWES_BY_SQ_CATEGORY; -import static org.sonar.server.security.SecurityStandards.OWASP_ASVS_40_LEVEL_BY_REQUIREMENT; import static org.sonar.server.security.SecurityStandards.OWASP_ASVS_REQUIREMENTS_BY_LEVEL; import static org.sonar.server.security.SecurityStandards.SQ_CATEGORY_KEYS_ORDERING; import static org.sonar.server.security.SecurityStandards.fromSecurityStandards; +import static org.sonar.server.security.SecurityStandards.getRequirementsForCategoryAndLevel; public class SecurityStandardsTest { @Test @@ -151,14 +151,20 @@ public class SecurityStandardsTest { } @Test - public void owaspAsvs40_level_by_requirements_check() { - assertEquals(286, OWASP_ASVS_40_LEVEL_BY_REQUIREMENT.keySet().size()); - assertEquals(Integer.valueOf(1), OWASP_ASVS_40_LEVEL_BY_REQUIREMENT.get("2.1.1")); - assertEquals(Integer.valueOf(1), OWASP_ASVS_40_LEVEL_BY_REQUIREMENT.get("14.5.3")); - assertEquals(Integer.valueOf(2), OWASP_ASVS_40_LEVEL_BY_REQUIREMENT.get("1.1.1")); - assertEquals(Integer.valueOf(2), OWASP_ASVS_40_LEVEL_BY_REQUIREMENT.get("14.5.4")); - assertEquals(Integer.valueOf(3), OWASP_ASVS_40_LEVEL_BY_REQUIREMENT.get("1.11.3")); - assertEquals(Integer.valueOf(3), OWASP_ASVS_40_LEVEL_BY_REQUIREMENT.get("14.1.5")); + public void owaspAsvs40_requirements_by_category_and_level_check() { + assertEquals(0, getRequirementsForCategoryAndLevel(OwaspAsvs.C1, 1).size()); + assertEquals(31, getRequirementsForCategoryAndLevel(OwaspAsvs.C2, 1).size()); + assertEquals(12, getRequirementsForCategoryAndLevel(OwaspAsvs.C3, 1).size()); + assertEquals(9, getRequirementsForCategoryAndLevel(OwaspAsvs.C4, 1).size()); + assertEquals(27, getRequirementsForCategoryAndLevel(OwaspAsvs.C5, 1).size()); + assertEquals(1, getRequirementsForCategoryAndLevel(OwaspAsvs.C6, 1).size()); + assertEquals(3, getRequirementsForCategoryAndLevel(OwaspAsvs.C7, 1).size()); + assertEquals(7, getRequirementsForCategoryAndLevel(OwaspAsvs.C8, 1).size()); + assertEquals(3, getRequirementsForCategoryAndLevel(OwaspAsvs.C9, 1).size()); + assertEquals(3, getRequirementsForCategoryAndLevel(OwaspAsvs.C10, 1).size()); + assertEquals(5, getRequirementsForCategoryAndLevel(OwaspAsvs.C11, 1).size()); + assertEquals(11, getRequirementsForCategoryAndLevel(OwaspAsvs.C12, 1).size()); + assertEquals(7, getRequirementsForCategoryAndLevel(OwaspAsvs.C13, 1).size()); + assertEquals(16, getRequirementsForCategoryAndLevel(OwaspAsvs.C14, 1).size()); } - } -- cgit v1.2.3