From dcdb0f14b776a8e65ea20dab77ba2486d932b30f Mon Sep 17 00:00:00 2001 From: =?utf8?q?L=C3=A9o=20Geoffroy?= Date: Thu, 18 Jul 2024 10:08:04 +0200 Subject: [PATCH] SONAR-22542 Index new STIG security standard --- gradle.properties | 3 +- .../server/issue/index/IssueIndexerIT.java | 4 +- .../org/sonar/server/issue/SearchRequest.java | 11 +++++ .../sonar/server/issue/index/IssueDoc.java | 10 ++++ .../issue/index/IssueIndexDefinition.java | 2 + .../index/IssueIteratorForSingleChunk.java | 2 + .../server/security/SecurityStandards.java | 5 ++ .../sonar/server/issue/SearchRequestTest.java | 2 + .../security/SecurityStandardsTest.java | 46 +++++++++++++------ .../sonar/server/issue/index/IssueIndex.java | 6 +++ .../sonar/server/issue/index/IssueQuery.java | 12 +++++ .../server/issue/index/IssueQueryFactory.java | 1 + .../server/issue/index/IssueQueryTest.java | 9 ++++ .../server/hotspot/ws/SearchActionIT.java | 36 +++++++++++++-- .../sonar/server/issue/ws/SearchActionIT.java | 27 ++++++++++- .../sonar/server/hotspot/ws/SearchAction.java | 19 +++++++- .../sonar/server/issue/ws/SearchAction.java | 14 ++++-- .../sensor/internal/SensorContextTester.java | 5 ++ .../scanner/sensor/ProjectSensorContext.java | 5 ++ .../ws/client/issue/IssuesWsParameters.java | 1 + 20 files changed, 193 insertions(+), 27 deletions(-) diff --git a/gradle.properties b/gradle.properties index cd4b8601926..435bf57a80c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,8 +6,7 @@ version=10.7 # 30 months from the release date for LTA versions # No change required for patch versions versionEOL=2025-03-27 - -pluginApiVersion=10.8.0.2329 +pluginApiVersion=10.10.0.2391 description=Open source platform for continuous inspection of code quality projectTitle=SonarQube org.gradle.jvmargs=-Xmx2048m diff --git a/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java b/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java index f4e20951b5e..d011f225171 100644 --- a/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java +++ b/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java @@ -197,6 +197,7 @@ public class IssueIndexerIT { assertThat(doc.updateDate()).isEqualToIgnoringMillis(new Date(issue.getIssueUpdateTime())); assertThat(doc.getCwe()).containsExactlyInAnyOrder(SecurityStandards.UNKNOWN_STANDARD); assertThat(doc.getOwaspTop10()).isEmpty(); + assertThat(doc.getStigAsdV5R3()).isEmpty(); assertThat(doc.getSansTop25()).isEmpty(); assertThat(doc.getSonarSourceSecurityCategory()).isEqualTo(SQCategory.OTHERS); assertThat(doc.getVulnerabilityProbability()).isEqualTo(VulnerabilityProbability.LOW); @@ -209,7 +210,7 @@ public class IssueIndexerIT { @Test public void indexAllIssues_shouldIndexSecurityStandards() { - RuleDto rule = db.rules().insert(r -> r.setSecurityStandards(new HashSet<>(Arrays.asList("cwe:123", "owaspTop10:a3", "cwe:863", "owaspAsvs-4.0:2.1.1")))); + RuleDto rule = db.rules().insert(r -> r.setSecurityStandards(new HashSet<>(Arrays.asList("stig-ASD_V5R3:V-222400", "cwe:123", "owaspTop10:a3", "cwe:863", "owaspAsvs-4.0:2.1.1")))); ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto dir = db.components().insertComponent(ComponentTesting.newDirectory(project, "src/main/java/foo")); ComponentDto file = db.components().insertComponent(newFileDto(project, dir, "F1")); @@ -222,6 +223,7 @@ public class IssueIndexerIT { assertThat(doc.getOwaspTop10()).containsExactlyInAnyOrder("a3"); assertThat(doc.getOwaspAsvs40()).containsExactlyInAnyOrder("2.1.1"); assertThat(doc.getSansTop25()).containsExactlyInAnyOrder(SANS_TOP_25_POROUS_DEFENSES); + assertThat(doc.getStigAsdV5R3()).containsExactlyInAnyOrder("V-222400"); } @Test diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java index 543e2f225d6..309799b18a5 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java @@ -73,6 +73,7 @@ public class SearchRequest { private List owaspTop10; private List owaspAsvs40; private List owaspTop10For2021; + private List stigAsdV5R3; private List sansTop25; private List sonarsourceSecurity; private List cwe; @@ -436,6 +437,16 @@ public class SearchRequest { return this; } + @CheckForNull + public List getStigAsdV5R3() { + return stigAsdV5R3; + } + + public SearchRequest setStigAsdV5R3(@Nullable List stigAsdV5R3) { + this.stigAsdV5R3 = stigAsdV5R3; + return this; + } + @CheckForNull public List getSansTop25() { return sansTop25; diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java index 90c1bc3f016..21888af7366 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java @@ -364,6 +364,16 @@ public class IssueDoc extends BaseDoc { return this; } + @CheckForNull + public Collection getStigAsdV5R3() { + return getNullableField(IssueIndexDefinition.FIELD_ISSUE_STIG_ASD_V5R3); + } + + public IssueDoc setStigAsdV5R3(@Nullable Collection o) { + setField(IssueIndexDefinition.FIELD_ISSUE_STIG_ASD_V5R3, o); + return this; + } + @CheckForNull public Collection getSansTop25() { return getNullableField(IssueIndexDefinition.FIELD_ISSUE_SANS_TOP_25); 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 088f435eb59..ad815ed9e7d 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 @@ -97,6 +97,7 @@ public class IssueIndexDefinition implements IndexDefinition { public static final String FIELD_ISSUE_OWASP_TOP_10_2021 = "owaspTop10-2021"; public static final String FIELD_ISSUE_SANS_TOP_25 = "sansTop25"; public static final String FIELD_ISSUE_CWE = "cwe"; + public static final String FIELD_ISSUE_STIG_ASD_V5R3 = "stig-ASD_V5R3"; public static final String FIELD_ISSUE_SQ_SECURITY_CATEGORY = "sonarsourceSecurity"; public static final String FIELD_ISSUE_VULNERABILITY_PROBABILITY = "vulnerabilityProbability"; public static final String FIELD_ISSUE_CODE_VARIANTS = "codeVariants"; @@ -184,6 +185,7 @@ public class IssueIndexDefinition implements IndexDefinition { mapping.keywordFieldBuilder(FIELD_ISSUE_CWE).disableNorms().build(); mapping.keywordFieldBuilder(FIELD_ISSUE_SQ_SECURITY_CATEGORY).disableNorms().build(); mapping.keywordFieldBuilder(FIELD_ISSUE_VULNERABILITY_PROBABILITY).disableNorms().build(); + mapping.keywordFieldBuilder(FIELD_ISSUE_STIG_ASD_V5R3).disableNorms().build(); mapping.createBooleanField(FIELD_ISSUE_NEW_CODE_REFERENCE); mapping.keywordFieldBuilder(FIELD_ISSUE_CODE_VARIANTS).disableNorms().build(); mapping.createBooleanField(FIELD_PRIORITIZED_RULE); diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java index d17baac5679..c71ba67ad29 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java @@ -35,6 +35,7 @@ import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Scopes; import org.sonar.api.rules.CleanCodeAttribute; import org.sonar.api.rules.RuleType; +import org.sonar.api.server.rule.RulesDefinition.StigVersion; import org.sonar.db.DatabaseUtils; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -131,6 +132,7 @@ class IssueIteratorForSingleChunk implements IssueIterator { SecurityStandards.SQCategory sqCategory = securityStandards.getSqCategory(); doc.setOwaspTop10(securityStandards.getOwaspTop10()); doc.setOwaspTop10For2021(securityStandards.getOwaspTop10For2021()); + doc.setStigAsdV5R3(securityStandards.getStig(StigVersion.ASD_V5R3)); doc.setPciDss32(securityStandards.getPciDss32()); doc.setPciDss40(securityStandards.getPciDss40()); doc.setOwaspAsvs40(securityStandards.getOwaspAsvs40()); 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 090d2f217d1..7058a1a3063 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 @@ -36,6 +36,7 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import org.sonar.api.server.rule.RulesDefinition.OwaspAsvsVersion; import org.sonar.api.server.rule.RulesDefinition.PciDssVersion; +import org.sonar.api.server.rule.RulesDefinition.StigVersion; import static java.util.Arrays.asList; import static java.util.Arrays.stream; @@ -310,6 +311,10 @@ public final class SecurityStandards { return getMatchingStandards(standards, OWASP_TOP10_2021_PREFIX); } + public Set getStig(StigVersion version) { + return getMatchingStandards(standards, version.prefix() + ":"); + } + /** * @deprecated SansTop25 report is outdated, it has been completely deprecated in version 10.0 and will be removed from version 11.0 */ diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java index be5b755ffb1..1779e509993 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java @@ -54,6 +54,7 @@ public class SearchRequestTest { .setOwaspTop10For2021(asList("a2", "a3")) .setOwaspAsvs40(asList("1.1.1", "4.2.2")) .setOwaspAsvsLevel(2) + .setStigAsdV5R3(List.of("V-222400", "V-222401")) .setPciDss32(asList("1", "4")) .setPciDss40(asList("3", "5")) .setCodeVariants(asList("variant1", "variant2")) @@ -81,6 +82,7 @@ public class SearchRequestTest { assertThat(underTest.getAsc()).isTrue(); assertThat(underTest.getInNewCodePeriod()).isTrue(); assertOwasp(underTest); + assertThat(underTest.getStigAsdV5R3()).containsExactly("V-222400", "V-222401"); assertThat(underTest.getPciDss32()).containsExactly("1", "4"); assertThat(underTest.getPciDss40()).containsExactly("3", "5"); assertThat(underTest.getCodeVariants()).containsExactly("variant1", "variant2"); 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 7f4e85f4cbb..09d2f53ceb2 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 @@ -24,11 +24,13 @@ import java.util.EnumSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.server.rule.RulesDefinition.OwaspAsvsVersion; 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.security.SecurityStandards.StigSupportedRequirement; import static java.util.Collections.emptySet; import static java.util.Collections.singleton; @@ -42,9 +44,9 @@ import static org.sonar.server.security.SecurityStandards.SQ_CATEGORY_KEYS_ORDER import static org.sonar.server.security.SecurityStandards.fromSecurityStandards; import static org.sonar.server.security.SecurityStandards.getRequirementsForCategoryAndLevel; -public class SecurityStandardsTest { +class SecurityStandardsTest { @Test - public void fromSecurityStandards_from_empty_set_has_SQCategory_OTHERS() { + void fromSecurityStandards_from_empty_set_has_SQCategory_OTHERS() { SecurityStandards securityStandards = fromSecurityStandards(emptySet()); assertThat(securityStandards.getStandards()).isEmpty(); @@ -53,7 +55,7 @@ public class SecurityStandardsTest { } @Test - public void fromSecurityStandards_from_empty_set_has_unkwown_cwe_standard() { + void fromSecurityStandards_from_empty_set_has_unkwown_cwe_standard() { SecurityStandards securityStandards = fromSecurityStandards(emptySet()); assertThat(securityStandards.getStandards()).isEmpty(); @@ -61,7 +63,7 @@ public class SecurityStandardsTest { } @Test - public void fromSecurityStandards_from_empty_set_has_no_OwaspTop10_standard() { + void fromSecurityStandards_from_empty_set_has_no_OwaspTop10_standard() { SecurityStandards securityStandards = fromSecurityStandards(emptySet()); assertThat(securityStandards.getStandards()).isEmpty(); @@ -69,7 +71,7 @@ public class SecurityStandardsTest { } @Test - public void fromSecurityStandards_from_empty_set_has_no_SansTop25_standard() { + void fromSecurityStandards_from_empty_set_has_no_SansTop25_standard() { SecurityStandards securityStandards = fromSecurityStandards(emptySet()); assertThat(securityStandards.getStandards()).isEmpty(); @@ -77,7 +79,7 @@ public class SecurityStandardsTest { } @Test - public void fromSecurityStandards_from_empty_set_has_no_CweTop25_standard() { + void fromSecurityStandards_from_empty_set_has_no_CweTop25_standard() { SecurityStandards securityStandards = fromSecurityStandards(emptySet()); assertThat(securityStandards.getStandards()).isEmpty(); @@ -85,7 +87,7 @@ public class SecurityStandardsTest { } @Test - public void fromSecurityStandards_finds_SQCategory_from_any_if_the_mapped_CWE_standard() { + void fromSecurityStandards_finds_SQCategory_from_any_if_the_mapped_CWE_standard() { CWES_BY_SQ_CATEGORY.forEach((sqCategory, cwes) -> { cwes.forEach(cwe -> { SecurityStandards securityStandards = fromSecurityStandards(singleton("cwe:" + cwe)); @@ -96,7 +98,7 @@ public class SecurityStandardsTest { } @Test - public void fromSecurityStandards_finds_SQCategory_from_multiple_of_the_mapped_CWE_standard() { + void fromSecurityStandards_finds_SQCategory_from_multiple_of_the_mapped_CWE_standard() { CWES_BY_SQ_CATEGORY.forEach((sqCategory, cwes) -> { SecurityStandards securityStandards = fromSecurityStandards(cwes.stream().map(t -> "cwe:" + t).collect(toSet())); @@ -105,7 +107,13 @@ public class SecurityStandardsTest { } @Test - public void fromSecurityStandards_finds_SQCategory_first_in_order_when_CWEs_map_to_multiple_SQCategories() { + void fromSecurityStandards_whenStigStandardIsSet_shouldReturnExpectedCategories() { + SecurityStandards securityStandards = fromSecurityStandards(singleton("stig-ASD_V5R3:V-222400")); + assertThat(securityStandards.getStig(RulesDefinition.StigVersion.ASD_V5R3)).containsExactly("V-222400"); + } + + @Test + void fromSecurityStandards_finds_SQCategory_first_in_order_when_CWEs_map_to_multiple_SQCategories() { EnumSet sqCategories = EnumSet.allOf(SQCategory.class); sqCategories.remove(SQCategory.OTHERS); @@ -126,21 +134,21 @@ public class SecurityStandardsTest { } @Test - public void pciDss_categories_check() { + void pciDss_categories_check() { List pciDssCategories = Arrays.stream(PciDss.values()).map(PciDss::category).toList(); assertThat(pciDssCategories).hasSize(12).containsExactly("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); } @Test - public void owaspAsvs_categories_check() { + void owaspAsvs_categories_check() { List owaspAsvsCategories = Arrays.stream(OwaspAsvs.values()).map(OwaspAsvs::category).toList(); assertThat(owaspAsvsCategories).hasSize(14).containsExactly("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14"); } @Test - public void owaspAsvs40_requirements_distribution_by_level_check() { + void owaspAsvs40_requirements_distribution_by_level_check() { assertTrue(OWASP_ASVS_REQUIREMENTS_BY_LEVEL.containsKey(OwaspAsvsVersion.V4_0)); assertTrue(OWASP_ASVS_REQUIREMENTS_BY_LEVEL.get(OwaspAsvsVersion.V4_0).containsKey(1)); assertTrue(OWASP_ASVS_REQUIREMENTS_BY_LEVEL.get(OwaspAsvsVersion.V4_0).containsKey(2)); @@ -151,7 +159,7 @@ public class SecurityStandardsTest { } @Test - public void owaspAsvs40_requirements_by_category_and_level_check() { + 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()); @@ -167,4 +175,14 @@ public class SecurityStandardsTest { assertEquals(7, getRequirementsForCategoryAndLevel(OwaspAsvs.C13, 1).size()); assertEquals(16, getRequirementsForCategoryAndLevel(OwaspAsvs.C14, 1).size()); } + + + @Test + void StigSupportedRequirement_values_shouldReturnAllValues() { + Set requirements = Arrays.stream(StigSupportedRequirement.values()) + .map(StigSupportedRequirement::getRequirement) + .collect(toSet()); + + assertThat(requirements).isNotEmpty().allSatisfy(e -> assertThat(e).startsWith("V-")); + } } 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 e2230d914c0..5e4f67e5deb 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 @@ -150,6 +150,7 @@ import static org.sonar.server.issue.index.IssueIndex.Facet.SCOPES; import static org.sonar.server.issue.index.IssueIndex.Facet.SEVERITIES; import static org.sonar.server.issue.index.IssueIndex.Facet.SONARSOURCE_SECURITY; import static org.sonar.server.issue.index.IssueIndex.Facet.STATUSES; +import static org.sonar.server.issue.index.IssueIndex.Facet.STIG_ASD_V5R3; import static org.sonar.server.issue.index.IssueIndex.Facet.TAGS; import static org.sonar.server.issue.index.IssueIndex.Facet.TYPES; import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID; @@ -188,6 +189,7 @@ import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_SEVE import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_SEVERITY_VALUE; import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_SQ_SECURITY_CATEGORY; import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_STATUS; +import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_STIG_ASD_V5R3; import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_TAGS; import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_TYPE; import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_VULNERABILITY_PROBABILITY; @@ -224,6 +226,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SCOPES; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SEVERITIES; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SONARSOURCE_SECURITY; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STATUSES; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STIG_ASD_V5R3; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TAGS; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TYPES; @@ -288,6 +291,7 @@ public class IssueIndex { OWASP_ASVS_40(PARAM_OWASP_ASVS_40, FIELD_ISSUE_OWASP_ASVS_40, STICKY, DEFAULT_FACET_SIZE), OWASP_TOP_10(PARAM_OWASP_TOP_10, FIELD_ISSUE_OWASP_TOP_10, STICKY, DEFAULT_FACET_SIZE), OWASP_TOP_10_2021(PARAM_OWASP_TOP_10_2021, FIELD_ISSUE_OWASP_TOP_10_2021, STICKY, DEFAULT_FACET_SIZE), + STIG_ASD_V5R3(PARAM_STIG_ASD_V5R3, FIELD_ISSUE_STIG_ASD_V5R3, STICKY, DEFAULT_FACET_SIZE), SANS_TOP_25(PARAM_SANS_TOP_25, FIELD_ISSUE_SANS_TOP_25, STICKY, DEFAULT_FACET_SIZE), CWE(PARAM_CWE, FIELD_ISSUE_CWE, STICKY, DEFAULT_FACET_SIZE), CREATED_AT(PARAM_CREATED_AT, FIELD_ISSUE_FUNC_CREATED_AT, NON_STICKY), @@ -501,6 +505,7 @@ public class IssueIndex { addOwaspAsvsFilter(FIELD_ISSUE_OWASP_ASVS_40, OWASP_ASVS_40, query, filters); addSecurityCategoryFilter(FIELD_ISSUE_OWASP_TOP_10, OWASP_TOP_10, query.owaspTop10(), filters); addSecurityCategoryFilter(FIELD_ISSUE_OWASP_TOP_10_2021, OWASP_TOP_10_2021, query.owaspTop10For2021(), filters); + addSecurityCategoryFilter(FIELD_ISSUE_STIG_ASD_V5R3, STIG_ASD_V5R3, query.stigAsdV5R3(), filters); addSecurityCategoryFilter(FIELD_ISSUE_SANS_TOP_25, SANS_TOP_25, query.sansTop25(), filters); addSecurityCategoryFilter(FIELD_ISSUE_CWE, CWE, query.cwe(), filters); addSecurityCategoryFilter(FIELD_ISSUE_SQ_SECURITY_CATEGORY, SONARSOURCE_SECURITY, query.sonarsourceSecurity(), filters); @@ -888,6 +893,7 @@ public class IssueIndex { addSecurityCategoryFacetIfNeeded(PARAM_OWASP_ASVS_40, OWASP_ASVS_40, options, aggregationHelper, esRequest, query.owaspAsvs40().toArray()); addSecurityCategoryFacetIfNeeded(PARAM_OWASP_TOP_10, OWASP_TOP_10, options, aggregationHelper, esRequest, query.owaspTop10().toArray()); addSecurityCategoryFacetIfNeeded(PARAM_OWASP_TOP_10_2021, OWASP_TOP_10_2021, options, aggregationHelper, esRequest, query.owaspTop10For2021().toArray()); + addSecurityCategoryFacetIfNeeded(PARAM_STIG_ASD_V5R3, STIG_ASD_V5R3, options, aggregationHelper, esRequest, query.stigAsdV5R3().toArray()); addSecurityCategoryFacetIfNeeded(PARAM_SANS_TOP_25, SANS_TOP_25, options, aggregationHelper, esRequest, query.sansTop25().toArray()); addSecurityCategoryFacetIfNeeded(PARAM_CWE, CWE, options, aggregationHelper, esRequest, query.cwe().toArray()); addSecurityCategoryFacetIfNeeded(PARAM_SONARSOURCE_SECURITY, SONARSOURCE_SECURITY, options, aggregationHelper, esRequest, query.sonarsourceSecurity().toArray()); diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java index 233aa77bdd0..bcaa26373a9 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java @@ -80,6 +80,7 @@ public class IssueQuery { private final Collection owaspAsvs40; private final Integer owaspAsvsLevel; private final Collection owaspTop10For2021; + private final Collection stigAsdV5R3; private final Collection sansTop25; private final Collection cwe; private final Collection sonarsourceSecurity; @@ -129,6 +130,7 @@ public class IssueQuery { this.owaspAsvsLevel = builder.owaspAsvsLevel; this.owaspTop10 = defaultCollection(builder.owaspTop10); this.owaspTop10For2021 = defaultCollection(builder.owaspTop10For2021); + this.stigAsdV5R3 = defaultCollection(builder.stigAsdV5R3); this.sansTop25 = defaultCollection(builder.sansTop25); this.cwe = defaultCollection(builder.cwe); this.sonarsourceSecurity = defaultCollection(builder.sonarsourceSecurity); @@ -260,6 +262,10 @@ public class IssueQuery { return owaspTop10For2021; } + public Collection stigAsdV5R3() { + return stigAsdV5R3; + } + public Collection sansTop25() { return sansTop25; } @@ -392,6 +398,7 @@ public class IssueQuery { private Integer owaspAsvsLevel; private Collection owaspTop10; private Collection owaspTop10For2021; + private Collection stigAsdV5R3; private Collection sansTop25; private Collection cwe; private Collection sonarsourceSecurity; @@ -552,6 +559,11 @@ public class IssueQuery { return this; } + public Builder stigAsdR5V3(@Nullable Collection o) { + this.stigAsdV5R3 = o; + return this; + } + public Builder sansTop25(@Nullable Collection s) { this.sansTop25 = s; return this; diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java index 7e4a69a5ea3..43fb8a0cb26 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java @@ -152,6 +152,7 @@ public class IssueQueryFactory { .owaspAsvsLevel(request.getOwaspAsvsLevel()) .owaspTop10(request.getOwaspTop10()) .owaspTop10For2021(request.getOwaspTop10For2021()) + .stigAsdR5V3(request.getStigAsdV5R3()) .sansTop25(request.getSansTop25()) .cwe(request.getCwe()) .sonarsourceSecurity(request.getSonarsourceSecurity()) diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryTest.java index 5b33aae4067..003a1db746d 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryTest.java @@ -127,6 +127,15 @@ class IssueQueryTest { assertThat(query.owaspTop10For2021()).containsOnly("a3", "a4"); } + @Test + void build_stig_query() { + IssueQuery query = IssueQuery.builder() + .stigAsdR5V3(List.of("V-222400", "V-222401")) + .build(); + + assertThat(query.stigAsdV5R3()).containsOnly("V-222400", "V-222401"); + } + @Test void build_query_without_dates() { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java index ff29ff985fa..a6cbbd43ef2 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java @@ -114,6 +114,7 @@ import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.issue.IssueTesting.newCodeReferenceIssue; import static org.sonar.db.issue.IssueTesting.newIssue; import static org.sonar.db.newcodeperiod.NewCodePeriodType.REFERENCE_BRANCH; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STIG_ASD_V5R3; @SuppressWarnings("ALL") @RunWith(DataProviderRunner.class) @@ -169,6 +170,7 @@ public class SearchActionIT { WebService.Param pciDss40Param = actionTester.getDef().param(PARAM_PCI_DSS_40); WebService.Param owasAsvs40Param = actionTester.getDef().param(PARAM_OWASP_ASVS_40); WebService.Param owaspTop10Param = actionTester.getDef().param(PARAM_OWASP_TOP_10_2017); + WebService.Param stigAsdV5R3 = actionTester.getDef().param(PARAM_STIG_ASD_V5R3); WebService.Param sansTop25Param = actionTester.getDef().param(PARAM_SANS_TOP_25); WebService.Param sonarsourceSecurityParam = actionTester.getDef().param(PARAM_SONARSOURCE_SECURITY); WebService.Param filesParam = actionTester.getDef().param(PARAM_FILES); @@ -187,6 +189,8 @@ public class SearchActionIT { assertThat(owasAsvs40Param.isRequired()).isFalse(); assertThat(owaspTop10Param).isNotNull(); assertThat(owaspTop10Param.isRequired()).isFalse(); + assertThat(stigAsdV5R3).isNotNull(); + assertThat(stigAsdV5R3.isRequired()).isFalse(); assertThat(sansTop25Param).isNotNull(); assertThat(sansTop25Param.isRequired()).isFalse(); assertThat(sonarsourceSecurityParam).isNotNull(); @@ -1542,6 +1546,30 @@ public class SearchActionIT { .containsExactly(hotspot3.getKey()); } + @Test + public void returns_hotspots_with_specified_stig_category() { + ProjectData projectData = dbTester.components().insertPublicProject(); + ComponentDto project = projectData.getMainBranchComponent(); + + userSessionRule.registerProjects(projectData.getProjectDto()); + indexPermissions(); + ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); + RuleDto rule1 = newRule(SECURITY_HOTSPOT); + RuleDto rule2 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(Set.of("cwe:117", "cwe:190"))); + RuleDto rule3 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(Set.of("stig-ASD_V5R3:V-222400", "cwe:601"))); + insertHotspot(project, file, rule1); + insertHotspot(project, file, rule2); + IssueDto hotspot3 = insertHotspot(project, file, rule3); + indexIssues(); + + SearchWsResponse response = newRequest(project).setParam(PARAM_STIG_ASD_V5R3, "V-222400") + .executeProtobuf(SearchWsResponse.class); + + assertThat(response.getHotspotsList()) + .extracting(SearchWsResponse.Hotspot::getKey) + .containsExactly(hotspot3.getKey()); + } + @Test public void returns_hotspots_with_specified_pciDss_category() { ProjectData projectData = dbTester.components().insertPublicProject(); @@ -1617,10 +1645,10 @@ public class SearchActionIT { indexPermissions(); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); RuleDto rule1 = newRule(SECURITY_HOTSPOT); - RuleDto rule2 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(of("cwe:117", "cwe:190"))); - RuleDto rule3 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(of("owaspAsvs-4.0:2.1.1"))); - RuleDto rule4 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(of("owaspAsvs-4.0:1.1.1"))); - RuleDto rule5 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(of("owaspAsvs-4.0:3.6.1"))); + RuleDto rule2 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(Set.of("cwe:117", "cwe:190"))); + RuleDto rule3 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(Set.of("owaspAsvs-4.0:2.1.1"))); + RuleDto rule4 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(Set.of("owaspAsvs-4.0:1.1.1"))); + RuleDto rule5 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(Set.of("owaspAsvs-4.0:3.6.1"))); insertHotspot(project, file, rule1); insertHotspot(project, file, rule2); IssueDto hotspot3 = insertHotspot(project, file, rule3); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java index 12d0a67628b..9d9818ec646 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java @@ -1749,6 +1749,31 @@ public class SearchActionIT { .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey()); } + @Test + public void only_vulnerabilities_are_returned_by_stig_R5V3() { + ComponentDto project = db.components().insertPublicProject().getMainBranchComponent(); + ComponentDto file = db.components().insertComponent(newFileDto(project)); + Consumer ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto + .setSecurityStandards(Sets.newHashSet("cwe:20", "cwe:564", "stig-ASD_V5R3:V-222402", "stig-ASD_V5R3:V-222403", "stig-ASD_V5R3:V-222404", "ostig-ASD_V5R3:V-222405")) + .setSystemTags(Sets.newHashSet("bad-practice", "cwe", "stig", "sans-top25-insecure", "sql")); + Consumer issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "stig", "sans-top25-insecure", "sql")); + RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer); + db.issues().insertHotspot(hotspotRule, project, file, issueConsumer); + RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer); + IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY)); + IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY)); + db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL)); + indexPermissionsAndIssues(); + + SearchWsResponse result = ws.newRequest() + .setParam("stig-ASD_V5R3", "V-222402") + .executeProtobuf(SearchWsResponse.class); + + assertThat(result.getIssuesList()) + .extracting(Issue::getKey) + .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey()); + } + @Test public void only_vulnerabilities_are_returned_by_sansTop25() { ComponentDto project = db.components().insertPublicProject().getMainBranchComponent(); @@ -2083,7 +2108,7 @@ public class SearchActionIT { "additionalFields", "asc", "assigned", "assignees", "author", "components", "branch", "pullRequest", "createdAfter", "createdAt", "createdBefore", "createdInLast", "directories", "facets", "files", "issues", "scopes", "languages", "onComponentOnly", "p", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "statuses", "tags", "types", "pciDss-3.2", "pciDss-4.0", "owaspAsvs-4.0", - "owaspAsvsLevel", "owaspTop10", "owaspTop10-2021", "sansTop25", "cwe", "sonarsourceSecurity", "timeZone", "inNewCodePeriod", "codeVariants", + "owaspAsvsLevel", "owaspTop10", "owaspTop10-2021", "stig-ASD_V5R3", "sansTop25", "cwe", "sonarsourceSecurity", "timeZone", "inNewCodePeriod", "codeVariants", "cleanCodeAttributeCategories", "impactSeverities", "impactSoftwareQualities", "issueStatuses", "fixedInPullRequest", "prioritizedRule"); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java index fc079cfd91e..c9e4a331c28 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java @@ -110,6 +110,7 @@ public class SearchAction implements HotspotsWsAction { private static final String PARAM_OWASP_ASVS_40 = "owaspAsvs-4.0"; private static final String PARAM_OWASP_TOP_10_2017 = "owaspTop10"; private static final String PARAM_OWASP_TOP_10_2021 = "owaspTop10-2021"; + private static final String PARAM_STIG_ASD_V5R3 = "stig-ASD_V5R3"; /** * @deprecated SansTop25 report is outdated, it has been completely deprecated in version 10.0 and will be removed from version 11.0 */ @@ -151,6 +152,7 @@ public class SearchAction implements HotspotsWsAction { Set owaspAsvs40 = setFromList(request.paramAsStrings(PARAM_OWASP_ASVS_40)); Set owasp2017Top10 = setFromList(request.paramAsStrings(PARAM_OWASP_TOP_10_2017)); Set owasp2021Top10 = setFromList(request.paramAsStrings(PARAM_OWASP_TOP_10_2021)); + Set stigAsdV5R3 = setFromList(request.paramAsStrings(PARAM_STIG_ASD_V5R3)); Set sansTop25 = setFromList(request.paramAsStrings(PARAM_SANS_TOP_25)); Set sonarsourceSecurity = setFromList(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY)); Set cwes = setFromList(request.paramAsStrings(PARAM_CWE)); @@ -160,7 +162,7 @@ public class SearchAction implements HotspotsWsAction { request.mandatoryParamAsInt(PAGE), request.mandatoryParamAsInt(PAGE_SIZE), request.param(PARAM_PROJECT), request.param(PARAM_BRANCH), request.param(PARAM_PULL_REQUEST), hotspotKeys, request.param(PARAM_STATUS), request.param(PARAM_RESOLUTION), request.paramAsBoolean(PARAM_IN_NEW_CODE_PERIOD), request.paramAsBoolean(PARAM_ONLY_MINE), request.paramAsInt(PARAM_OWASP_ASVS_LEVEL), - pciDss32, pciDss40, owaspAsvs40, owasp2017Top10, owasp2021Top10, sansTop25, sonarsourceSecurity, cwes, files); + pciDss32, pciDss40, owaspAsvs40, owasp2017Top10, owasp2021Top10, stigAsdV5R3, sansTop25, sonarsourceSecurity, cwes, files); } @Override @@ -203,6 +205,9 @@ public class SearchAction implements HotspotsWsAction { if (!wsRequest.getOwaspTop10For2021().isEmpty()) { builder.owaspTop10For2021(wsRequest.getOwaspTop10For2021()); } + if (!wsRequest.getStigAsdV5R3().isEmpty()) { + builder.stigAsdR5V3(wsRequest.getStigAsdV5R3()); + } if (!wsRequest.getSansTop25().isEmpty()) { builder.sansTop25(wsRequest.getSansTop25()); } @@ -225,6 +230,7 @@ public class SearchAction implements HotspotsWsAction { + "When issue indexing is in progress returns 503 service unavailable HTTP code.") .setSince("8.1") .setChangelog( + new Change("10.7", format("Added parameter '%s'", PARAM_STIG_ASD_V5R3)), new Change("10.2", format("Parameter '%s' renamed to '%s'", PARAM_PROJECT_KEY, PARAM_PROJECT)), new Change("10.0", "Parameter 'sansTop25' is deprecated"), new Change("9.6", "Added parameters 'pciDss-3.2' and 'pciDss-4.0"), @@ -296,6 +302,9 @@ public class SearchAction implements HotspotsWsAction { .setDescription("Comma-separated list of OWASP 2021 Top 10 lowercase categories.") .setSince("9.4") .setPossibleValues("a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10"); + action.createParam(PARAM_STIG_ASD_V5R3) + .setDescription("Comma-separated list of STIG V5R3 lowercase categories.") + .setSince("10.7"); action.createParam(PARAM_SANS_TOP_25) .setDescription("Comma-separated list of SANS Top 25 categories.") .setDeprecatedSince("10.0") @@ -610,6 +619,7 @@ public class SearchAction implements HotspotsWsAction { private final Set owaspAsvs40; private final Set owaspTop10For2017; private final Set owaspTop10For2021; + private final Set stigAsdV5R3; private final Set sansTop25; private final Set sonarsourceSecurity; private final Set cwe; @@ -619,7 +629,7 @@ public class SearchAction implements HotspotsWsAction { @Nullable String projectKey, @Nullable String branch, @Nullable String pullRequest, Set hotspotKeys, @Nullable String status, @Nullable String resolution, @Nullable Boolean inNewCodePeriod, @Nullable Boolean onlyMine, @Nullable Integer owaspAsvsLevel, Set pciDss32, Set pciDss40, Set owaspAsvs40, - Set owaspTop10For2017, Set owaspTop10For2021, Set sansTop25, Set sonarsourceSecurity, + Set owaspTop10For2017, Set owaspTop10For2021, Set stigAsdV5R3, Set sansTop25, Set sonarsourceSecurity, Set cwe, @Nullable Set files) { this.page = page; this.index = index; @@ -637,6 +647,7 @@ public class SearchAction implements HotspotsWsAction { this.owaspAsvs40 = owaspAsvs40; this.owaspTop10For2017 = owaspTop10For2017; this.owaspTop10For2021 = owaspTop10For2021; + this.stigAsdV5R3 = stigAsdV5R3; this.sansTop25 = sansTop25; this.sonarsourceSecurity = sonarsourceSecurity; this.cwe = cwe; @@ -707,6 +718,10 @@ public class SearchAction implements HotspotsWsAction { return owaspTop10For2021; } + public Set getStigAsdV5R3() { + return stigAsdV5R3; + } + public Set getSansTop25() { return sansTop25; } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java index e47e33b3ac7..b0fa2213b27 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java @@ -135,6 +135,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SCOPES; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SEVERITIES; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SONARSOURCE_SECURITY; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STATUSES; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STIG_ASD_V5R3; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TAGS; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TIMEZONE; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TYPES; @@ -142,8 +143,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TYPES; public class SearchAction implements IssuesWsAction { private static final String LOGIN_MYSELF = "__me__"; private static final Set ISSUE_SCOPES = Arrays.stream(IssueScope.values()).map(Enum::name).collect(Collectors.toSet()); - private static final EnumSet ALL_RULE_TYPES_EXCEPT_SECURITY_HOTSPOTS = - EnumSet.complementOf(EnumSet.of(RuleType.SECURITY_HOTSPOT)); + private static final EnumSet ALL_RULE_TYPES_EXCEPT_SECURITY_HOTSPOTS = EnumSet.complementOf(EnumSet.of(RuleType.SECURITY_HOTSPOT)); static final List SUPPORTED_FACETS = List.of( FACET_PROJECTS, @@ -165,6 +165,7 @@ public class SearchAction implements IssuesWsAction { PARAM_OWASP_ASVS_40, PARAM_OWASP_TOP_10, PARAM_OWASP_TOP_10_2021, + PARAM_STIG_ASD_V5R3, PARAM_SANS_TOP_25, PARAM_CWE, PARAM_CREATED_AT, @@ -214,6 +215,8 @@ public class SearchAction implements IssuesWsAction { + "
When issue indexing is in progress returns 503 service unavailable HTTP code.") .setSince("3.6") .setChangelog( + new Change("10.7", format(NEW_FACET_ADDED_MESSAGE, PARAM_STIG_ASD_V5R3)), + new Change("10.7", format(NEW_PARAM_ADDED_MESSAGE, PARAM_STIG_ASD_V5R3)), new Change("10.6", format(NEW_FACET_ADDED_MESSAGE, PARAM_PRIORITIZED_RULE)), new Change("10.6", format(NEW_PARAM_ADDED_MESSAGE, PARAM_PRIORITIZED_RULE)), new Change("10.4", "Added new param '%s'".formatted(PARAM_FIXED_IN_PULL_REQUEST)), @@ -372,6 +375,9 @@ public class SearchAction implements IssuesWsAction { .setDescription("Comma-separated list of OWASP Top 10 2021 lowercase categories.") .setSince("9.4") .setPossibleValues("a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10"); + action.createParam(PARAM_STIG_ASD_V5R3) + .setDescription("Comma-separated list of STIG V5R3 categories.") + .setSince("9.4"); action.createParam(PARAM_SANS_TOP_25) .setDescription("Comma-separated list of SANS Top 25 categories.") .setDeprecatedSince("10.0") @@ -516,7 +522,7 @@ public class SearchAction implements IssuesWsAction { .filter(FACETS_REQUIRING_PROJECT::contains) .collect(Collectors.toSet()); checkArgument(facetsRequiringProjectParameter.isEmpty() || - (!query.projectUuids().isEmpty()), "Facet(s) '%s' require to also filter by project", + (!query.projectUuids().isEmpty()), "Facet(s) '%s' require to also filter by project", String.join(",", facetsRequiringProjectParameter)); // execute request @@ -595,6 +601,7 @@ public class SearchAction implements IssuesWsAction { addMandatoryValuesToFacet(facets, PARAM_OWASP_ASVS_40, request.getOwaspAsvs40()); addMandatoryValuesToFacet(facets, PARAM_OWASP_TOP_10, request.getOwaspTop10()); addMandatoryValuesToFacet(facets, PARAM_OWASP_TOP_10_2021, request.getOwaspTop10For2021()); + addMandatoryValuesToFacet(facets, PARAM_STIG_ASD_V5R3, request.getStigAsdV5R3()); addMandatoryValuesToFacet(facets, PARAM_SANS_TOP_25, request.getSansTop25()); addMandatoryValuesToFacet(facets, PARAM_CWE, request.getCwe()); addMandatoryValuesToFacet(facets, PARAM_SONARSOURCE_SECURITY, request.getSonarsourceSecurity()); @@ -682,6 +689,7 @@ public class SearchAction implements IssuesWsAction { .setOwaspAsvs40(request.paramAsStrings(PARAM_OWASP_ASVS_40)) .setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10)) .setOwaspTop10For2021(request.paramAsStrings(PARAM_OWASP_TOP_10_2021)) + .setStigAsdV5R3(request.paramAsStrings(PARAM_STIG_ASD_V5R3)) .setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25)) .setCwe(request.paramAsStrings(PARAM_CWE)) .setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY)) diff --git a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java index 84def310e84..ca8aae07c0f 100644 --- a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java +++ b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java @@ -441,6 +441,11 @@ public class SensorContextTester implements SensorContext { return cacheEnabled; } + @Override + public void addTelemetryProperty(String s, String s1) { + throw new UnsupportedOperationException("addTelemetryProperty"); + } + public void setCacheEnabled(boolean enabled) { this.cacheEnabled = enabled; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java index 6ed4046a53d..ec0b9e59f26 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java @@ -214,6 +214,11 @@ public class ProjectSensorContext implements SensorContext { return analysisCacheEnabled.isEnabled(); } + @Override + public void addTelemetryProperty(String s, String s1) { + //NOOP + } + @Override public NewSignificantCode newSignificantCode() { return new DefaultSignificantCode(sensorStorage); 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 2192d46a89d..29d6d06cccc 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 @@ -94,6 +94,7 @@ public class IssuesWsParameters { public static final String PARAM_OWASP_ASVS_40 = "owaspAsvs-4.0"; 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"; @Deprecated public static final String PARAM_SANS_TOP_25 = "sansTop25"; public static final String PARAM_CWE_TOP_25 = "cweTop25"; -- 2.39.5