]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-17399 add owasp asvs 40 level support in security_report show API
authorMatteo Mara <matteo.mara@sonarsource.com>
Tue, 4 Oct 2022 14:11:07 +0000 (16:11 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 10 Oct 2022 20:03:09 +0000 (20:03 +0000)
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java
server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java
server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java
server/sonar-server-common/src/test/java/org/sonar/server/issue/index/SecurityStandardCategoryStatisticsTest.java
server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityStandardsTest.java
server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java
sonar-ws/src/main/protobuf/ws-security.proto

index 0eaccdeb01e5d8fb2cd5323329118d1fcf771b7e..2fa1f9f975170c93c174241babb8dd3d457f6431 100644 (file)
@@ -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();
index aca4b7ca159edf61e4d7287c14949d185a7dfba4..8c16e0064505fe454c6d93db86afa034841557cc 100644 (file)
@@ -37,6 +37,7 @@ public class SecurityStandardCategoryStatistics {
   private long totalRules;
   private boolean hasMoreRules;
   private final Optional<String> version;
+  private Optional<String> level = Optional.empty();
 
   public SecurityStandardCategoryStatistics(String category, long vulnerabilities, OptionalInt vulnerabiliyRating, long toReviewSecurityHotspots,
     long reviewedSecurityHotspots, Integer securityReviewRating, @Nullable List<SecurityStandardCategoryStatistics> children, @Nullable String version) {
@@ -96,6 +97,15 @@ public class SecurityStandardCategoryStatistics {
     return version;
   }
 
+  public Optional<String> 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;
index 171991db872d5d62c233c80c6bde712760856bd4..e450c323e928e7467d5deba63d7610b54dd90ae4 100644 (file)
@@ -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<String, Integer> OWASP_ASVS_40_LEVEL_BY_REQUIREMENT = Collections.unmodifiableMap(getLevelByRequirementMap());
-
   public static final Map<OwaspAsvsVersion, Map<Integer, List<String>>> 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<String, Integer> getLevelByRequirementMap() {
-    Map<String, Integer> 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<String> 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<String> getMatchingStandards(Set<String> securityStandards, String prefix) {
index 9f88638c7a7dc84c86eeaaf633f9aa6745d38a23..dc641aaf306ca22cb77fb4339d9131e509fcc08c 100644 (file)
@@ -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);
   }
 
index 2cf9e0a7f5a816c9757d368cd24793444b16ac21..b81b2c2ab08e565a03c5defbde2c11152aadfb45 100644 (file)
@@ -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();
   }
 
index a9d6a045923525c0fa2aebbc38ba858115b40def..31a32ebd48c85d6f73f5e7686468d3f952c8d8c9 100644 (file)
@@ -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());
   }
-
 }
index 093324796ad54e4f5c0068a74cb23f6e43bbdc89..7cffd0d083aa9b6d8a0b5fe566d50a76d4284e31 100644 (file)
@@ -68,7 +68,7 @@ import org.joda.time.Duration;
 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.OwaspAsvsVersion;
+import org.sonar.api.server.rule.RulesDefinition;
 import org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version;
 import org.sonar.api.server.rule.RulesDefinition.PciDssVersion;
 import org.sonar.api.utils.DateUtils;
@@ -91,7 +91,6 @@ import org.sonar.server.issue.index.IssueQuery.PeriodStart;
 import org.sonar.server.permission.index.AuthorizationDoc;
 import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
 import org.sonar.server.security.SecurityStandards;
-import org.sonar.server.security.SecurityStandards.OwaspAsvs;
 import org.sonar.server.security.SecurityStandards.PciDss;
 import org.sonar.server.security.SecurityStandards.SQCategory;
 import org.sonar.server.user.UserSession;
@@ -179,6 +178,7 @@ import static org.sonar.server.issue.index.IssueIndexDefinition.TYPE_ISSUE;
 import static org.sonar.server.security.SecurityReviewRating.computePercent;
 import static org.sonar.server.security.SecurityReviewRating.computeRating;
 import static org.sonar.server.security.SecurityStandards.CWES_BY_CWE_TOP_25;
+import static org.sonar.server.security.SecurityStandards.OWASP_ASVS_40_REQUIREMENTS_BY_LEVEL;
 import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_INSECURE_INTERACTION;
 import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_POROUS_DEFENSES;
 import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_RISKY_RESOURCE;
@@ -507,9 +507,9 @@ public class IssueIndex {
    *   </ul>
    * </p>
    *
-   * @param fieldName The PCI DSS version, e.g. pciDss-3.2
-   * @param facet The facet used for the filter
-   * @param values The PCI DSS categories to search for
+   * @param fieldName  The PCI DSS version, e.g. pciDss-3.2
+   * @param facet      The facet used for the filter
+   * @param values     The PCI DSS categories to search for
    * @param allFilters Object that holds all the filters for the Elastic search call
    */
   private static void addSecurityCategoryPrefixFilter(String fieldName, Facet facet, Collection<String> values, AllFilters allFilters) {
@@ -627,11 +627,11 @@ public class IssueIndex {
   private static RequestFiltersComputer newFilterComputer(SearchOptions options, AllFilters allFilters) {
     Collection<String> facetNames = options.getFacets();
     Set<TopAggregationDefinition<?>> facets = Stream.concat(
-        Stream.of(EFFORT_TOP_AGGREGATION),
-        facetNames.stream()
-          .map(FACETS_BY_NAME::get)
-          .filter(Objects::nonNull)
-          .map(Facet::getTopAggregationDef))
+      Stream.of(EFFORT_TOP_AGGREGATION),
+      facetNames.stream()
+        .map(FACETS_BY_NAME::get)
+        .filter(Objects::nonNull)
+        .map(Facet::getTopAggregationDef))
       .collect(MoreCollectors.toSet(facetNames.size()));
 
     return new RequestFiltersComputer(allFilters, facets);
@@ -836,11 +836,11 @@ public class IssueIndex {
       RESOLUTIONS.getName(), RESOLUTIONS.getTopAggregationDef(), RESOLUTIONS.getNumberOfTerms(),
       NO_EXTRA_FILTER,
       t ->
-        // add aggregation of type "missing" to return count of unresolved issues in the facet
-        t.subAggregation(
-          addEffortAggregationIfNeeded(query, AggregationBuilders
-            .missing(RESOLUTIONS.getName() + FACET_SUFFIX_MISSING)
-            .field(RESOLUTIONS.getFieldName()))));
+      // add aggregation of type "missing" to return count of unresolved issues in the facet
+      t.subAggregation(
+        addEffortAggregationIfNeeded(query, AggregationBuilders
+          .missing(RESOLUTIONS.getName() + FACET_SUFFIX_MISSING)
+          .field(RESOLUTIONS.getFieldName()))));
     esRequest.aggregation(aggregation);
   }
 
@@ -960,10 +960,10 @@ public class IssueIndex {
         ASSIGNED_TO_ME.getNumberOfTerms(),
         NO_EXTRA_FILTER,
         t ->
-          // add sub-aggregation to return issue count for current user
-          aggregationHelper.getSubAggregationHelper()
-            .buildSelectedItemsAggregation(ASSIGNED_TO_ME.getName(), ASSIGNED_TO_ME.getTopAggregationDef(), new String[] {uuid})
-            .ifPresent(t::subAggregation));
+        // add sub-aggregation to return issue count for current user
+        aggregationHelper.getSubAggregationHelper()
+          .buildSelectedItemsAggregation(ASSIGNED_TO_ME.getName(), ASSIGNED_TO_ME.getTopAggregationDef(), new String[] {uuid})
+          .ifPresent(t::subAggregation));
       esRequest.aggregation(aggregation);
     }
   }
@@ -1159,16 +1159,19 @@ public class IssueIndex {
       .forEach(pciDss -> request.aggregation(
         newSecurityReportSubAggregations(
           AggregationBuilders.filter(pciDss.category(), boolQuery().filter(prefixQuery(version.prefix(), pciDss.category() + "."))), version.prefix())));
-    return searchWithDistribution(request, version.label());
+    return searchWithDistribution(request, version.label(), null);
   }
 
-  public List<SecurityStandardCategoryStatistics> getOwaspAsvsReport(String projectUuid, boolean isViewOrApp, OwaspAsvsVersion version) {
+  public List<SecurityStandardCategoryStatistics> getOwaspAsvsReport(String projectUuid, boolean isViewOrApp, RulesDefinition.OwaspAsvsVersion version, Integer level) {
     SearchSourceBuilder request = prepareNonClosedVulnerabilitiesAndHotspotSearch(projectUuid, isViewOrApp);
-    Arrays.stream(OwaspAsvs.values())
+    Arrays.stream(SecurityStandards.OwaspAsvs.values())
       .forEach(owaspAsvs -> request.aggregation(
         newSecurityReportSubAggregations(
-          AggregationBuilders.filter(owaspAsvs.category(), boolQuery().filter(prefixQuery(version.prefix(), owaspAsvs.category() + "."))), version.prefix())));
-    return searchWithDistribution(request, version.label());
+          AggregationBuilders.filter(
+            owaspAsvs.category(),
+            boolQuery().filter(termsQuery(version.prefix(), SecurityStandards.getRequirementsForCategoryAndLevel(owaspAsvs, level)))),
+          version.prefix())));
+    return searchWithDistribution(request, version.label(), level);
   }
 
   public List<SecurityStandardCategoryStatistics> getOwaspTop10Report(String projectUuid, boolean isViewOrApp, boolean includeCwe, OwaspTop10Version version) {
@@ -1182,12 +1185,12 @@ public class IssueIndex {
     return search(request, includeCwe, version.label());
   }
 
-  private List<SecurityStandardCategoryStatistics> searchWithDistribution(SearchSourceBuilder sourceBuilder, String version) {
+  private List<SecurityStandardCategoryStatistics> searchWithDistribution(SearchSourceBuilder sourceBuilder, String version, @Nullable Integer level) {
     SearchRequest request = EsClient.prepareSearch(TYPE_ISSUE.getMainType())
       .source(sourceBuilder);
     SearchResponse response = client.search(request);
     return response.getAggregations().asList().stream()
-      .map(c -> processSecurityReportIssueSearchResultsWithDistribution((ParsedFilter) c, version))
+      .map(c -> processSecurityReportIssueSearchResultsWithDistribution((ParsedFilter) c, version, level))
       .collect(MoreCollectors.toList());
   }
 
@@ -1200,10 +1203,13 @@ public class IssueIndex {
       .collect(MoreCollectors.toList());
   }
 
-  private static SecurityStandardCategoryStatistics processSecurityReportIssueSearchResultsWithDistribution(ParsedFilter categoryFilter, String version) {
-    Stream<? extends Terms.Bucket> stream = ((ParsedStringTerms) categoryFilter.getAggregations().get(AGG_DISTRIBUTION)).getBuckets().stream();
-    var children = stream.filter(categoryBucket -> StringUtils.startsWith(categoryBucket.getKeyAsString(), categoryFilter.getName() + "."))
-      .map(categoryBucket -> processSecurityReportCategorySearchResults(categoryBucket, categoryBucket.getKeyAsString(), null, null)).collect(toList());
+  private static SecurityStandardCategoryStatistics processSecurityReportIssueSearchResultsWithDistribution(ParsedFilter categoryFilter, String version, @Nullable Integer level) {
+    var list = ((ParsedStringTerms) categoryFilter.getAggregations().get(AGG_DISTRIBUTION)).getBuckets();
+    List<SecurityStandardCategoryStatistics> children = list.stream()
+      .filter(categoryBucket -> StringUtils.startsWith(categoryBucket.getKeyAsString(), categoryFilter.getName() + "."))
+      .filter(categoryBucket -> level == null || OWASP_ASVS_40_REQUIREMENTS_BY_LEVEL.get(level).contains(categoryBucket.getKeyAsString()))
+      .map(categoryBucket -> processSecurityReportCategorySearchResults(categoryBucket, categoryBucket.getKeyAsString(), null, null))
+      .collect(toList());
 
     return processSecurityReportCategorySearchResults(categoryFilter, categoryFilter.getName(), children, version);
   }
index ba26775b3e971e70d0928428f5da290549848711..44ddc775f4af0c4f474dbf1879abf3ac3e259782 100644 (file)
@@ -38,9 +38,9 @@ import static java.util.stream.Collectors.toList;
 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.newDoc;
 import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_INSECURE_INTERACTION;
@@ -83,11 +83,11 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
   public void getOwaspTop10Report_dont_count_closed_vulnerabilities() {
     ComponentDto project = newPrivateProjectDto();
     indexIssues(
-      newDoc("openvul1", project).setOwaspTop10(asList("a1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.MAJOR),
-      newDoc("openvul12021", project).setOwaspTop10For2021(asList("a2")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.MAJOR),
-      newDoc("notopenvul", project).setOwaspTop10(asList("a1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED).setResolution(Issue.RESOLUTION_FIXED)
+      newDoc("openvul1", project).setOwaspTop10(List.of("a1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.MAJOR),
+      newDoc("openvul12021", project).setOwaspTop10For2021(List.of("a2")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.MAJOR),
+      newDoc("notopenvul", project).setOwaspTop10(List.of("a1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED).setResolution(Issue.RESOLUTION_FIXED)
         .setSeverity(Severity.BLOCKER),
-      newDoc("notopenvul2021", project).setOwaspTop10For2021(asList("a2")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED).setResolution(Issue.RESOLUTION_FIXED)
+      newDoc("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);
@@ -132,10 +132,10 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
     ComponentDto project = newPrivateProjectDto();
     ComponentDto another = newPrivateProjectDto();
     indexIssues(
-      newDoc("openhotspot1", project).setOwaspTop10(asList("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("openhotspot2021", project).setOwaspTop10For2021(asList("a2")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("anotherProject", another).setOwaspTop10(asList("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("anotherProject2021", another).setOwaspTop10For2021(asList("a2")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW));
+      newDoc("openhotspot1", project).setOwaspTop10(List.of("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+      newDoc("openhotspot2021", project).setOwaspTop10For2021(List.of("a2")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+      newDoc("anotherProject", another).setOwaspTop10(List.of("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+      newDoc("anotherProject2021", another).setOwaspTop10For2021(List.of("a2")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW));
 
     List<SecurityStandardCategoryStatistics> owaspTop10Report = underTest.getOwaspTop10Report(project.uuid(), false, false, Y2017);
     assertThat(owaspTop10Report)
@@ -154,12 +154,12 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
   public void getOwaspTop10Report_dont_count_closed_hotspots() {
     ComponentDto project = newPrivateProjectDto();
     indexIssues(
-      newDoc("openhotspot1", project).setOwaspTop10(asList("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("openhotspot2021", project).setOwaspTop10For2021(asList("a2")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("closedHotspot", project).setOwaspTop10(asList("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_CLOSED)
+      newDoc("openhotspot1", project).setOwaspTop10(List.of("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+      newDoc("openhotspot2021", project).setOwaspTop10For2021(List.of("a2")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+      newDoc("closedHotspot", project).setOwaspTop10(List.of("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_CLOSED)
         .setResolution(Issue.RESOLUTION_FIXED),
-    newDoc("closedHotspot2021", project).setOwaspTop10For2021(asList("a2")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_CLOSED)
-      .setResolution(Issue.RESOLUTION_FIXED));
+      newDoc("closedHotspot2021", project).setOwaspTop10For2021(List.of("a2")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_CLOSED)
+        .setResolution(Issue.RESOLUTION_FIXED));
 
     List<SecurityStandardCategoryStatistics> owaspTop10Report = underTest.getOwaspTop10Report(project.uuid(), false, false, Y2017);
     assertThat(owaspTop10Report)
@@ -211,13 +211,13 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
     assertThat(owaspAsvsReport)
       .isNotEmpty();
 
-    assertThat(owaspAsvsReport.get(0).getChildren()).hasSize(2);
-    assertThat(owaspAsvsReport.get(1).getChildren()).isEmpty();
-    assertThat(owaspAsvsReport.get(2).getChildren()).hasSize(4);
+    assertThat(owaspAsvsReport.get(0).getChildren()).isEmpty();
+    assertThat(owaspAsvsReport.get(1).getChildren()).hasSize(2);
+    assertThat(owaspAsvsReport.get(2).getChildren()).hasSize(3);
     assertThat(owaspAsvsReport.get(3).getChildren()).isEmpty();
     assertThat(owaspAsvsReport.get(4).getChildren()).isEmpty();
-    assertThat(owaspAsvsReport.get(5).getChildren()).hasSize(2);
-    assertThat(owaspAsvsReport.get(6).getChildren()).isEmpty();
+    assertThat(owaspAsvsReport.get(5).getChildren()).hasSize(1);
+    assertThat(owaspAsvsReport.get(6).getChildren()).hasSize(1);
     assertThat(owaspAsvsReport.get(7).getChildren()).hasSize(1);
     assertThat(owaspAsvsReport.get(8).getChildren()).isEmpty();
     assertThat(owaspAsvsReport.get(9).getChildren()).hasSize(1);
@@ -278,7 +278,7 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
     indexIssues(
       newDoc("openvul1", project).setOwaspTop10(asList("a1", "a3")).setCwe(asList("123", "456")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
         .setSeverity(Severity.MAJOR),
-      newDoc("openvul2", project).setOwaspTop10(asList("a3", "a6")).setCwe(asList("123")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+      newDoc("openvul2", project).setOwaspTop10(asList("a3", "a6")).setCwe(List.of("123")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
         .setSeverity(Severity.MINOR),
       newDoc("notowaspvul", project).setOwaspTop10(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
       newDoc("toreviewhotspot1", project).setOwaspTop10(asList("a1", "a3")).setCwe(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT)
@@ -351,21 +351,21 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
   private List<SecurityStandardCategoryStatistics> indexIssuesAndAssertOwaspAsvsReport() {
     ComponentDto project = newPrivateProjectDto();
     indexIssues(
-      newDoc("openvul1", project).setOwaspAsvs40(asList("1.2.0", "3.4.5")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+      newDoc("openvul1", project).setOwaspAsvs40(asList("2.1.1", "3.4.5")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
         .setSeverity(Severity.MAJOR),
-      newDoc("openvul2", project).setOwaspAsvs40(asList("3.3.2", "6.5")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+      newDoc("openvul2", project).setOwaspAsvs40(asList("3.2.2", "6.2.1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
         .setSeverity(Severity.MINOR),
-      newDoc("openvul3", project).setOwaspAsvs40(asList("10.1.2", "6.5")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+      newDoc("openvul3", project).setOwaspAsvs40(asList("10.3.1", "6.2.1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
         .setSeverity(Severity.MINOR),
       newDoc("notowaspasvsvul", project).setOwaspAsvs40(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
-      newDoc("toreviewhotspot1", project).setOwaspAsvs40(asList("1.3.0", "3.3.2")).setType(RuleType.SECURITY_HOTSPOT)
+      newDoc("toreviewhotspot1", project).setOwaspAsvs40(asList("2.1.2", "3.2.2")).setType(RuleType.SECURITY_HOTSPOT)
         .setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("toreviewhotspot2", project).setOwaspAsvs40(asList("3.5.6", "6.4.5")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("reviewedHotspot", project).setOwaspAsvs40(asList("3.1.1", "8.6")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED)
+      newDoc("toreviewhotspot2", project).setOwaspAsvs40(asList("3.4.5", "7.1.1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+      newDoc("reviewedHotspot", project).setOwaspAsvs40(asList("3.1.1", "8.3.4")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED)
         .setResolution(Issue.RESOLUTION_FIXED),
       newDoc("notowaspasvshotspot", project).setOwaspAsvs40(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW));
 
-    List<SecurityStandardCategoryStatistics> owaspAsvsReport = underTest.getOwaspAsvsReport(project.uuid(), false, OwaspAsvsVersion.V4_0).stream()
+    List<SecurityStandardCategoryStatistics> owaspAsvsReport = underTest.getOwaspAsvsReport(project.uuid(), false, OwaspAsvsVersion.V4_0, 1).stream()
       .sorted(comparing(s -> parseInt(s.getCategory())))
       .collect(toList());
     assertThat(owaspAsvsReport)
@@ -373,13 +373,13 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
         SecurityStandardCategoryStatistics::getVulnerabilityRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
         SecurityStandardCategoryStatistics::getReviewedSecurityHotspots, SecurityStandardCategoryStatistics::getSecurityReviewRating)
       .containsExactlyInAnyOrder(
-        tuple("1", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 1L /* toreviewhotspot1 */, 0L, 5),
-        tuple("2", 0L, OptionalInt.empty(), 0L, 0L, 1),
+        tuple("1", 0L, OptionalInt.empty(), 0L, 0L, 1),
+        tuple("2", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 1L /* toreviewhotspot1 */, 0L, 5),
         tuple("3", 2L /* openvul1,openvul2 */, OptionalInt.of(3)/* MAJOR = C */, 2L/* toreviewhotspot1,toreviewhotspot2 */, 1L /* reviewedHotspot */, 4),
         tuple("4", 0L, OptionalInt.empty(), 0L, 0L, 1),
         tuple("5", 0L, OptionalInt.empty(), 0L, 0L, 1),
-        tuple("6", 2L /* openvul2 */, OptionalInt.of(2) /* MINOR = B */, 1L /* toreviewhotspot2 */, 0L, 5),
-        tuple("7", 0L, OptionalInt.empty(), 0L, 0L, 1),
+        tuple("6", 2L /* openvul2 */, OptionalInt.of(2) /* MINOR = B */, 0L , 0L, 1),
+        tuple("7", 0L /* openvul2 */, OptionalInt.empty() /* MINOR = B */, 1L /* toreviewhotspot2 */, 0L, 5),
         tuple("8", 0L, OptionalInt.empty(), 0L, 1L /* reviewedHotspot */, 1),
         tuple("9", 0L, OptionalInt.empty(), 0L, 0L, 1),
         tuple("10", 1L, OptionalInt.of(2), 0L, 0L, 1),
@@ -396,7 +396,7 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
     indexIssues(
       newDoc("openvul1", project).setOwaspTop10For2021(asList("a1", "a3")).setCwe(asList("123", "456")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
         .setSeverity(Severity.MAJOR),
-      newDoc("openvul2", project).setOwaspTop10For2021(asList("a3", "a6")).setCwe(asList("123")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+      newDoc("openvul2", project).setOwaspTop10For2021(asList("a3", "a6")).setCwe(List.of("123")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
         .setSeverity(Severity.MINOR),
       newDoc("notowaspvul", project).setOwaspTop10For2021(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
       newDoc("toreviewhotspot1", project).setOwaspTop10For2021(asList("a1", "a3")).setCwe(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT)
@@ -441,8 +441,8 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
         .setStatus(Issue.STATUS_TO_REVIEW),
       newDoc("toreviewhotspot2", project).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE, SANS_TOP_25_POROUS_DEFENSES)).setType(RuleType.SECURITY_HOTSPOT)
         .setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("inReviewHotspot", project).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_IN_REVIEW),
-      newDoc("reviewedHotspot", project).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED)
+      newDoc("inReviewHotspot", project).setSansTop25(List.of(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_IN_REVIEW),
+      newDoc("reviewedHotspot", project).setSansTop25(List.of(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED)
         .setResolution(Issue.RESOLUTION_FIXED),
       newDoc("notowasphotspot", project).setSansTop25(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW));
 
@@ -480,7 +480,7 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
         .setStatus(Issue.STATUS_TO_REVIEW),
       newDoc("toreviewhotspot2", project2).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE, SANS_TOP_25_POROUS_DEFENSES)).setType(RuleType.SECURITY_HOTSPOT)
         .setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("reviewedHotspot", project2).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED)
+      newDoc("reviewedHotspot", project2).setSansTop25(List.of(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED)
         .setResolution(Issue.RESOLUTION_FIXED),
       newDoc("notowasphotspot", project1).setSansTop25(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW));
 
@@ -555,24 +555,24 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
     ComponentDto project2 = db.components().insertPrivateProject();
 
     indexIssues(
-      newDoc("openvul1", project1).setOwaspAsvs40(asList("1.2.0", "3.4.5")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+      newDoc("openvul1", project1).setOwaspAsvs40(asList("2.1.1", "3.4.5")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
         .setSeverity(Severity.MAJOR),
-      newDoc("openvul2", project2).setOwaspAsvs40(asList("3.3.2", "6.5")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+      newDoc("openvul2", project2).setOwaspAsvs40(asList("3.3.2", "6.2.1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
         .setSeverity(Severity.MINOR),
-      newDoc("openvul3", project1).setOwaspAsvs40(asList("10.1.2", "6.5")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+      newDoc("openvul3", project1).setOwaspAsvs40(asList("10.3.2", "6.2.1")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
         .setSeverity(Severity.MINOR),
-      newDoc("notowaspvul", project1).setOwaspAsvs40(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
-      newDoc("toreviewhotspot1", project2).setOwaspAsvs40(asList("1.3.0", "3.3.2")).setType(RuleType.SECURITY_HOTSPOT)
+      newDoc("notowaspasvsvul", project1).setOwaspAsvs40(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
+      newDoc("toreviewhotspot1", project2).setOwaspAsvs40(asList("2.1.3", "3.3.2")).setType(RuleType.SECURITY_HOTSPOT)
         .setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("toreviewhotspot2", project1).setOwaspAsvs40(asList("3.5.6", "6.4.5")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("reviewedHotspot", project2).setOwaspAsvs40(asList("3.1.1", "8.6")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED)
+      newDoc("toreviewhotspot2", project1).setOwaspAsvs40(asList("3.4.4", "6.2.1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+      newDoc("reviewedHotspot", project2).setOwaspAsvs40(asList("3.1.1", "8.3.1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED)
         .setResolution(Issue.RESOLUTION_FIXED),
-      newDoc("notowasphotspot", project1).setOwaspAsvs40(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW));
+      newDoc("notowaspasvshotspot", project1).setOwaspAsvs40(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW));
 
     indexView(portfolio1.uuid(), singletonList(project1.uuid()));
     indexView(portfolio2.uuid(), singletonList(project2.uuid()));
 
-    List<SecurityStandardCategoryStatistics> owaspAsvsReport = underTest.getOwaspAsvsReport(portfolio1.uuid(), true, OwaspAsvsVersion.V4_0).stream()
+    List<SecurityStandardCategoryStatistics> owaspAsvsReport = underTest.getOwaspAsvsReport(portfolio1.uuid(), true, OwaspAsvsVersion.V4_0, 1).stream()
       .sorted(comparing(s -> parseInt(s.getCategory())))
       .collect(toList());
     assertThat(owaspAsvsReport)
@@ -580,8 +580,8 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
         SecurityStandardCategoryStatistics::getVulnerabilityRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
         SecurityStandardCategoryStatistics::getReviewedSecurityHotspots, SecurityStandardCategoryStatistics::getSecurityReviewRating)
       .containsExactlyInAnyOrder(
-        tuple("1", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 1),
-        tuple("2", 0L, OptionalInt.empty(), 0L, 0L, 1),
+        tuple("1", 0L, OptionalInt.empty(), 0L, 0L, 1),
+        tuple("2", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 1),
         tuple("3", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 1L/* toreviewhotspot2 */, 0L, 5),
         tuple("4", 0L, OptionalInt.empty(), 0L, 0L, 1),
         tuple("5", 0L, OptionalInt.empty(), 0L, 0L, 1),
@@ -600,16 +600,16 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
   public void getCWETop25Report_aggregation() {
     ComponentDto project = newPrivateProjectDto();
     indexIssues(
-      newDoc("openvul", project).setCwe(asList("119")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+      newDoc("openvul", project).setCwe(List.of("119")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
         .setSeverity(Severity.MAJOR),
-      newDoc("notopenvul", project).setCwe(asList("119")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED)
+      newDoc("notopenvul", project).setCwe(List.of("119")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED)
         .setResolution(Issue.RESOLUTION_FIXED)
         .setSeverity(Severity.BLOCKER),
-      newDoc("toreviewhotspot", project).setCwe(asList("89")).setType(RuleType.SECURITY_HOTSPOT)
+      newDoc("toreviewhotspot", project).setCwe(List.of("89")).setType(RuleType.SECURITY_HOTSPOT)
         .setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("only2020", project).setCwe(asList("862")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+      newDoc("only2020", project).setCwe(List.of("862")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
         .setSeverity(Severity.MINOR),
-      newDoc("unknown", project).setCwe(asList("999")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+      newDoc("unknown", project).setCwe(List.of("999")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
         .setSeverity(Severity.MINOR));
 
     List<SecurityStandardCategoryStatistics> cweTop25Reports = underTest.getCweTop25Reports(project.uuid(), false);
@@ -683,15 +683,15 @@ public class IssueIndexSecurityReportsTest extends IssueIndexTestCommon {
     ComponentDto project2 = db.components().insertPrivateProject();
 
     indexIssues(
-      newDoc("openvul1", project1).setCwe(asList("119")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
+      newDoc("openvul1", project1).setCwe(List.of("119")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
         .setSeverity(Severity.MAJOR),
-      newDoc("openvul2", project2).setCwe(asList("119")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+      newDoc("openvul2", project2).setCwe(List.of("119")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
         .setSeverity(Severity.MINOR),
-      newDoc("toreviewhotspot", project1).setCwe(asList("89")).setType(RuleType.SECURITY_HOTSPOT)
+      newDoc("toreviewhotspot", project1).setCwe(List.of("89")).setType(RuleType.SECURITY_HOTSPOT)
         .setStatus(Issue.STATUS_TO_REVIEW),
-      newDoc("only2020", project2).setCwe(asList("862")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+      newDoc("only2020", project2).setCwe(List.of("862")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
         .setSeverity(Severity.MINOR),
-      newDoc("unknown", project2).setCwe(asList("999")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
+      newDoc("unknown", project2).setCwe(List.of("999")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
         .setSeverity(Severity.MINOR));
 
     indexView(application.uuid(), asList(project1.uuid(), project2.uuid()));
index da6870b886ecb524cd3529e3dc342ff11a50e5c4..6f5b7dd9dba85066ba529d010eaf34869e3c495a 100644 (file)
@@ -43,6 +43,7 @@ message SecurityStandardCategoryStatistics {
   optional int64 totalRules = 10;
   optional bool hasMoreRules = 11;
   optional string version = 12;
+  optional string level = 13;
 }
 
 message CweStatistics {