# 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
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);
@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"));
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
private List<String> owaspTop10;
private List<String> owaspAsvs40;
private List<String> owaspTop10For2021;
+ private List<String> stigAsdV5R3;
private List<String> sansTop25;
private List<String> sonarsourceSecurity;
private List<String> cwe;
return this;
}
+ @CheckForNull
+ public List<String> getStigAsdV5R3() {
+ return stigAsdV5R3;
+ }
+
+ public SearchRequest setStigAsdV5R3(@Nullable List<String> stigAsdV5R3) {
+ this.stigAsdV5R3 = stigAsdV5R3;
+ return this;
+ }
+
@CheckForNull
public List<String> getSansTop25() {
return sansTop25;
return this;
}
+ @CheckForNull
+ public Collection<String> getStigAsdV5R3() {
+ return getNullableField(IssueIndexDefinition.FIELD_ISSUE_STIG_ASD_V5R3);
+ }
+
+ public IssueDoc setStigAsdV5R3(@Nullable Collection<String> o) {
+ setField(IssueIndexDefinition.FIELD_ISSUE_STIG_ASD_V5R3, o);
+ return this;
+ }
+
@CheckForNull
public Collection<String> getSansTop25() {
return getNullableField(IssueIndexDefinition.FIELD_ISSUE_SANS_TOP_25);
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";
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);
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;
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());
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;
return getMatchingStandards(standards, OWASP_TOP10_2021_PREFIX);
}
+ public Set<String> 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
*/
.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"))
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");
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;
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();
}
@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();
}
@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();
}
@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();
}
@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();
}
@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));
}
@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()));
}
@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<SQCategory> sqCategories = EnumSet.allOf(SQCategory.class);
sqCategories.remove(SQCategory.OTHERS);
}
@Test
- public void pciDss_categories_check() {
+ void pciDss_categories_check() {
List<String> 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<String> 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));
}
@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());
assertEquals(7, getRequirementsForCategoryAndLevel(OwaspAsvs.C13, 1).size());
assertEquals(16, getRequirementsForCategoryAndLevel(OwaspAsvs.C14, 1).size());
}
+
+
+ @Test
+ void StigSupportedRequirement_values_shouldReturnAllValues() {
+ Set<String> requirements = Arrays.stream(StigSupportedRequirement.values())
+ .map(StigSupportedRequirement::getRequirement)
+ .collect(toSet());
+
+ assertThat(requirements).isNotEmpty().allSatisfy(e -> assertThat(e).startsWith("V-"));
+ }
}
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;
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;
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;
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),
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);
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());
private final Collection<String> owaspAsvs40;
private final Integer owaspAsvsLevel;
private final Collection<String> owaspTop10For2021;
+ private final Collection<String> stigAsdV5R3;
private final Collection<String> sansTop25;
private final Collection<String> cwe;
private final Collection<String> sonarsourceSecurity;
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);
return owaspTop10For2021;
}
+ public Collection<String> stigAsdV5R3() {
+ return stigAsdV5R3;
+ }
+
public Collection<String> sansTop25() {
return sansTop25;
}
private Integer owaspAsvsLevel;
private Collection<String> owaspTop10;
private Collection<String> owaspTop10For2021;
+ private Collection<String> stigAsdV5R3;
private Collection<String> sansTop25;
private Collection<String> cwe;
private Collection<String> sonarsourceSecurity;
return this;
}
+ public Builder stigAsdR5V3(@Nullable Collection<String> o) {
+ this.stigAsdV5R3 = o;
+ return this;
+ }
+
public Builder sansTop25(@Nullable Collection<String> s) {
this.sansTop25 = s;
return this;
.owaspAsvsLevel(request.getOwaspAsvsLevel())
.owaspTop10(request.getOwaspTop10())
.owaspTop10For2021(request.getOwaspTop10For2021())
+ .stigAsdR5V3(request.getStigAsdV5R3())
.sansTop25(request.getSansTop25())
.cwe(request.getCwe())
.sonarsourceSecurity(request.getSonarsourceSecurity())
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() {
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)
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);
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();
.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();
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);
.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<RuleDto> 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<IssueDto> 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();
"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");
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
*/
Set<String> owaspAsvs40 = setFromList(request.paramAsStrings(PARAM_OWASP_ASVS_40));
Set<String> owasp2017Top10 = setFromList(request.paramAsStrings(PARAM_OWASP_TOP_10_2017));
Set<String> owasp2021Top10 = setFromList(request.paramAsStrings(PARAM_OWASP_TOP_10_2021));
+ Set<String> stigAsdV5R3 = setFromList(request.paramAsStrings(PARAM_STIG_ASD_V5R3));
Set<String> sansTop25 = setFromList(request.paramAsStrings(PARAM_SANS_TOP_25));
Set<String> sonarsourceSecurity = setFromList(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY));
Set<String> cwes = setFromList(request.paramAsStrings(PARAM_CWE));
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
if (!wsRequest.getOwaspTop10For2021().isEmpty()) {
builder.owaspTop10For2021(wsRequest.getOwaspTop10For2021());
}
+ if (!wsRequest.getStigAsdV5R3().isEmpty()) {
+ builder.stigAsdR5V3(wsRequest.getStigAsdV5R3());
+ }
if (!wsRequest.getSansTop25().isEmpty()) {
builder.sansTop25(wsRequest.getSansTop25());
}
+ "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"),
.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")
private final Set<String> owaspAsvs40;
private final Set<String> owaspTop10For2017;
private final Set<String> owaspTop10For2021;
+ private final Set<String> stigAsdV5R3;
private final Set<String> sansTop25;
private final Set<String> sonarsourceSecurity;
private final Set<String> cwe;
@Nullable String projectKey, @Nullable String branch, @Nullable String pullRequest, Set<String> hotspotKeys,
@Nullable String status, @Nullable String resolution, @Nullable Boolean inNewCodePeriod, @Nullable Boolean onlyMine,
@Nullable Integer owaspAsvsLevel, Set<String> pciDss32, Set<String> pciDss40, Set<String> owaspAsvs40,
- Set<String> owaspTop10For2017, Set<String> owaspTop10For2021, Set<String> sansTop25, Set<String> sonarsourceSecurity,
+ Set<String> owaspTop10For2017, Set<String> owaspTop10For2021, Set<String> stigAsdV5R3, Set<String> sansTop25, Set<String> sonarsourceSecurity,
Set<String> cwe, @Nullable Set<String> files) {
this.page = page;
this.index = index;
this.owaspAsvs40 = owaspAsvs40;
this.owaspTop10For2017 = owaspTop10For2017;
this.owaspTop10For2021 = owaspTop10For2021;
+ this.stigAsdV5R3 = stigAsdV5R3;
this.sansTop25 = sansTop25;
this.sonarsourceSecurity = sonarsourceSecurity;
this.cwe = cwe;
return owaspTop10For2021;
}
+ public Set<String> getStigAsdV5R3() {
+ return stigAsdV5R3;
+ }
+
public Set<String> getSansTop25() {
return sansTop25;
}
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;
public class SearchAction implements IssuesWsAction {
private static final String LOGIN_MYSELF = "__me__";
private static final Set<String> ISSUE_SCOPES = Arrays.stream(IssueScope.values()).map(Enum::name).collect(Collectors.toSet());
- private static final EnumSet<RuleType> ALL_RULE_TYPES_EXCEPT_SECURITY_HOTSPOTS =
- EnumSet.complementOf(EnumSet.of(RuleType.SECURITY_HOTSPOT));
+ private static final EnumSet<RuleType> ALL_RULE_TYPES_EXCEPT_SECURITY_HOTSPOTS = EnumSet.complementOf(EnumSet.of(RuleType.SECURITY_HOTSPOT));
static final List<String> SUPPORTED_FACETS = List.of(
FACET_PROJECTS,
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,
+ "<br/>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)),
.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")
.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
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());
.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))
return cacheEnabled;
}
+ @Override
+ public void addTelemetryProperty(String s, String s1) {
+ throw new UnsupportedOperationException("addTelemetryProperty");
+ }
+
public void setCacheEnabled(boolean enabled) {
this.cacheEnabled = enabled;
}
return analysisCacheEnabled.isEnabled();
}
+ @Override
+ public void addTelemetryProperty(String s, String s1) {
+ //NOOP
+ }
+
@Override
public NewSignificantCode newSignificantCode() {
return new DefaultSignificantCode(sensorStorage);
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";