assertThat(doc.getCwe()).containsExactlyInAnyOrder(SecurityStandards.UNKNOWN_STANDARD);
assertThat(doc.getOwaspTop10()).isEmpty();
assertThat(doc.getStigAsdV5R3()).isEmpty();
+ assertThat(doc.getCasa()).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("stig-ASD_V5R3:V-222400", "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", "cwe:326", "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"));
underTest.indexAllIssues();
IssueDoc doc = es.getDocuments(TYPE_ISSUE, IssueDoc.class).get(0);
- assertThat(doc.getCwe()).containsExactlyInAnyOrder("123", "863");
+ assertThat(doc.getCwe()).containsExactlyInAnyOrder("123", "863", "326");
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");
+ assertThat(doc.getCasa()).containsExactly("6.2.3", "9.1.2", "6.2.7", "6.2.4");
}
@Test
private List<String> owaspAsvs40;
private List<String> owaspTop10For2021;
private List<String> stigAsdV5R3;
+ private List<String> casa;
private List<String> sansTop25;
private List<String> sonarsourceSecurity;
private List<String> cwe;
return this;
}
+ @CheckForNull
+ public List<String> getCasa() {
+ return casa;
+ }
+
+ public SearchRequest setCasa(@Nullable List<String> casa) {
+ this.casa = casa;
+ return this;
+ }
+
@CheckForNull
public List<String> getSansTop25() {
return sansTop25;
return this;
}
+ @CheckForNull
+ public Collection<String> getCasa() {
+ return getNullableField(IssueIndexDefinition.FIELD_ISSUE_CASA);
+ }
+
+ public IssueDoc setCasa(@Nullable Collection<String> o) {
+ setField(IssueIndexDefinition.FIELD_ISSUE_CASA, o);
+ return this;
+ }
+
@CheckForNull
public Collection<String> getSansTop25() {
return getNullableField(IssueIndexDefinition.FIELD_ISSUE_SANS_TOP_25);
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_CASA = "casa";
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";
private IssueIndexDefinition(Configuration config, boolean enableSource) {
this.config = config;
- this.enableSource = enableSource;
+ this.enableSource = true;
}
/**
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.keywordFieldBuilder(FIELD_ISSUE_CASA).disableNorms().build();
mapping.createBooleanField(FIELD_ISSUE_NEW_CODE_REFERENCE);
mapping.keywordFieldBuilder(FIELD_ISSUE_CODE_VARIANTS).disableNorms().build();
mapping.createBooleanField(FIELD_PRIORITIZED_RULE);
doc.setOwaspTop10(securityStandards.getOwaspTop10());
doc.setOwaspTop10For2021(securityStandards.getOwaspTop10For2021());
doc.setStigAsdV5R3(securityStandards.getStig(StigVersion.ASD_V5R3));
+ doc.setCasa(securityStandards.getCasa());
doc.setPciDss32(securityStandards.getPciDss32());
doc.setPciDss40(securityStandards.getPciDss40());
doc.setOwaspAsvs40(securityStandards.getOwaspAsvs40());
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;
"862", "77", "306", "119", "276", "918", "362", "400", "611", "94");
// https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html#tableView
- public static final List<String> CWE_TOP25_2023 = List.of("787", "79", "89", "416", "78", "20", "125", "22", "352", "434", "862", "476", "287", "190", "502",
+ public static final List<String> CWE_TOP25_2023 = List.of("787", "79", "89", "416", "78", "20", "125", "22", "352", "434", "862", "476", "287", "190", "502",
"77", "119", "798", "918", "306", "362", "269", "94", "863", "276");
public static final String CWE_YEAR_2021 = "2021";
"14.3.2", "14.3.3", "14.4.1", "14.4.2", "14.4.3", "14.4.4", "14.4.5", "14.4.6", "14.4.7", "14.5.1", "14.5.2", "14.5.3");
private static final List<String> OWASP_ASVS_40_LEVEL_2 = Stream.concat(Stream.of("1.1.1", "1.1.2", "1.1.3", "1.1.4", "1.1.5", "1.1.6",
- "1.1.7", "1.10.1", "1.11.1", "1.11.2", "1.12.1", "1.12.2", "1.14.1", "1.14.2", "1.14.3", "1.14.4", "1.14.5", "1.14.6", "1.2.1", "1.2.2", "1.2.3", "1.2.4", "1.4.1", "1.4.2",
- "1.4.3", "1.4.4", "1.4.5", "1.5.1", "1.5.2", "1.5.3", "1.5.4", "1.6.1", "1.6.2", "1.6.3", "1.6.4", "1.7.1", "1.7.2", "1.8.1", "1.8.2", "1.9.1", "1.9.2", "2.3.2", "2.3.3",
- "2.4.1", "2.4.2", "2.4.3", "2.4.4", "2.4.5", "2.5.7", "2.6.1", "2.6.2", "2.6.3", "2.7.5", "2.7.6", "2.8.2", "2.8.3", "2.8.4", "2.8.5", "2.8.6", "2.9.1", "2.9.2", "2.9.3",
- "3.2.4", "3.3.3", "3.3.4", "3.5.1", "3.5.2", "3.5.3", "4.3.3", "5.4.1", "5.4.2", "5.4.3", "6.1.1", "6.1.2", "6.1.3", "6.2.2", "6.2.3", "6.2.4", "6.2.5", "6.2.6", "6.3.1",
- "6.3.2", "6.4.1", "6.4.2", "7.1.3", "7.1.4", "7.2.1", "7.2.2", "7.3.1", "7.3.2", "7.3.3", "7.3.4", "7.4.2", "7.4.3", "8.1.1", "8.1.2", "8.1.3", "8.1.4", "8.3.5", "8.3.6",
- "8.3.7", "8.3.8", "9.2.1", "9.2.2", "9.2.3", "9.2.4", "10.2.1", "10.2.2", "11.1.6", "11.1.7", "11.1.8", "12.1.2", "12.1.3", "12.2.1", "12.3.6", "13.1.4", "13.1.5", "13.2.4",
- "13.2.5", "13.2.6", "13.3.2", "13.4.1", "13.4.2", "14.1.1", "14.1.2", "14.1.3", "14.1.4", "14.2.4", "14.2.5", "14.2.6", "14.5.4"), OWASP_ASVS_40_LEVEL_1.stream())
+ "1.1.7", "1.10.1", "1.11.1", "1.11.2", "1.12.1", "1.12.2", "1.14.1", "1.14.2", "1.14.3", "1.14.4", "1.14.5", "1.14.6", "1.2.1", "1.2.2", "1.2.3", "1.2.4", "1.4.1", "1.4.2",
+ "1.4.3", "1.4.4", "1.4.5", "1.5.1", "1.5.2", "1.5.3", "1.5.4", "1.6.1", "1.6.2", "1.6.3", "1.6.4", "1.7.1", "1.7.2", "1.8.1", "1.8.2", "1.9.1", "1.9.2", "2.3.2", "2.3.3",
+ "2.4.1", "2.4.2", "2.4.3", "2.4.4", "2.4.5", "2.5.7", "2.6.1", "2.6.2", "2.6.3", "2.7.5", "2.7.6", "2.8.2", "2.8.3", "2.8.4", "2.8.5", "2.8.6", "2.9.1", "2.9.2", "2.9.3",
+ "3.2.4", "3.3.3", "3.3.4", "3.5.1", "3.5.2", "3.5.3", "4.3.3", "5.4.1", "5.4.2", "5.4.3", "6.1.1", "6.1.2", "6.1.3", "6.2.2", "6.2.3", "6.2.4", "6.2.5", "6.2.6", "6.3.1",
+ "6.3.2", "6.4.1", "6.4.2", "7.1.3", "7.1.4", "7.2.1", "7.2.2", "7.3.1", "7.3.2", "7.3.3", "7.3.4", "7.4.2", "7.4.3", "8.1.1", "8.1.2", "8.1.3", "8.1.4", "8.3.5", "8.3.6",
+ "8.3.7", "8.3.8", "9.2.1", "9.2.2", "9.2.3", "9.2.4", "10.2.1", "10.2.2", "11.1.6", "11.1.7", "11.1.8", "12.1.2", "12.1.3", "12.2.1", "12.3.6", "13.1.4", "13.1.5", "13.2.4",
+ "13.2.5", "13.2.6", "13.3.2", "13.4.1", "13.4.2", "14.1.1", "14.1.2", "14.1.3", "14.1.4", "14.2.4", "14.2.5", "14.2.6", "14.5.4"), OWASP_ASVS_40_LEVEL_1.stream())
.toList();
private static final List<String> OWASP_ASVS_40_LEVEL_3 = Stream
private static final Ordering<SQCategory> SQ_CATEGORY_ORDERING = Ordering.explicit(stream(SQCategory.values()).toList());
public static final Ordering<String> SQ_CATEGORY_KEYS_ORDERING = Ordering.explicit(stream(SQCategory.values()).map(SQCategory::getKey).toList());
+ public static final Map<String, String> CWES_BY_CASA_CATEGORY;
+
+ static {
+ Map<String, String> map = new HashMap<>();
+ map.put("1.1.4", "1059");
+ map.put("1.14.6", "477");
+ map.put("1.4.1", "602");
+ map.put("1.8.1", null);
+ map.put("1.8.2", null);
+ map.put("2.1.1", "521");
+ map.put("2.3.1", "330");
+ map.put("2.4.1", "916");
+ map.put("2.5.4", "16");
+ map.put("2.6.1", "308");
+ map.put("2.7.2", "287");
+ map.put("2.7.6", "310");
+ map.put("3.3.1", "613");
+ map.put("3.3.3", "613");
+ map.put("3.4.1", "614");
+ map.put("3.4.2", "1004");
+ map.put("3.4.3", "1275");
+ map.put("3.5.2", "798");
+ map.put("3.5.3", "345");
+ map.put("3.7.1", "306");
+ map.put("4.1.1", "602");
+ map.put("4.1.2", "639");
+ map.put("4.1.3", "285");
+ map.put("4.1.5", "285");
+ map.put("4.2.1", "639");
+ map.put("4.2.2", "352");
+ map.put("4.3.1", "419");
+ map.put("4.3.2", "548");
+ map.put("5.1.1", "235");
+ map.put("5.1.5", "601");
+ map.put("5.2.3", "147");
+ map.put("5.2.4", "95");
+ map.put("5.2.5", "94");
+ map.put("5.2.6", "918");
+ map.put("5.2.7", "159");
+ map.put("5.3.1", "116");
+ map.put("5.3.10", "643");
+ map.put("5.3.3", "79");
+ map.put("5.3.4", "89");
+ map.put("5.3.6", "830");
+ map.put("5.3.7", "90");
+ map.put("5.3.8", "78");
+ map.put("5.3.9", "829");
+ map.put("5.5.2", "611");
+ map.put("6.1.1", "311");
+ map.put("6.2.1", "310");
+ map.put("6.2.3", "326");
+ map.put("6.2.4", "326");
+ map.put("6.2.7", "326");
+ map.put("6.2.8", "385");
+ map.put("6.3.2", "338");
+ map.put("6.4.2", "320");
+ map.put("7.1.1", "532");
+ map.put("8.1.1", "524");
+ map.put("8.2.2", "922");
+ map.put("8.3.1", "319");
+ map.put("8.3.5", "532");
+ map.put("9.1.2", "326");
+ map.put("9.2.1", "295");
+ map.put("9.2.4", "299");
+ map.put("10.3.2", "353");
+ map.put("10.3.3", "350");
+ map.put("11.1.4", "770");
+ map.put("12.4.1", "552");
+ map.put("12.4.2", "509");
+ map.put("13.1.3", "598");
+ map.put("13.1.4", "285");
+ map.put("13.2.1", "650");
+ map.put("14.1.1", null);
+ map.put("14.1.4", null);
+ map.put("14.1.5", null);
+ map.put("14.3.2", "497");
+ map.put("14.5.2", "346");
+ CWES_BY_CASA_CATEGORY = Collections.unmodifiableMap(map);
+ }
private final Set<String> standards;
private final Set<String> cwe;
+ private final Set<String> casaCategories;
private final SQCategory sqCategory;
private final Set<SQCategory> ignoredSQCategories;
- private SecurityStandards(Set<String> standards, Set<String> cwe, SQCategory sqCategory, Set<SQCategory> ignoredSQCategories) {
+ private SecurityStandards(Set<String> standards, Set<String> cwe, Set<String> casaCategories,
+ SQCategory sqCategory, Set<SQCategory> ignoredSQCategories) {
this.standards = standards;
this.cwe = cwe;
+ this.casaCategories = casaCategories;
this.sqCategory = sqCategory;
this.ignoredSQCategories = ignoredSQCategories;
}
return getMatchingStandards(standards, version.prefix() + ":");
}
+ public Set<String> getCasa() {
+ return casaCategories;
+ }
+
/**
* @deprecated SansTop25 report is outdated, it has been completely deprecated in version 10.0 and will be removed from version 11.0
*/
List<SQCategory> sq = toSortedSQCategories(cwe);
SQCategory sqCategory = sq.iterator().next();
Set<SQCategory> ignoredSQCategories = sq.stream().skip(1).collect(Collectors.toSet());
- return new SecurityStandards(standards, cwe, sqCategory, ignoredSQCategories);
+ Set<String> casaCategories = toCasaCategories(cwe);
+ return new SecurityStandards(standards, cwe, casaCategories, sqCategory, ignoredSQCategories);
}
public static Set<String> getRequirementsForCategoryAndLevel(String category, int level) {
return result.isEmpty() ? singletonList(SQCategory.OTHERS) : result;
}
+ private static Set<String> toCasaCategories(Set<String> cwe) {
+ return CWES_BY_CASA_CATEGORY
+ .keySet()
+ .stream()
+ .filter(k -> cwe.contains(CWES_BY_CASA_CATEGORY.get(k)))
+ .collect(Collectors.toSet());
+ }
+
}
.setOwaspAsvs40(asList("1.1.1", "4.2.2"))
.setOwaspAsvsLevel(2)
.setStigAsdV5R3(List.of("V-222400", "V-222401"))
+ .setCasa(List.of("1.4.1", "6.4.2"))
.setPciDss32(asList("1", "4"))
.setPciDss40(asList("3", "5"))
.setCodeVariants(asList("variant1", "variant2"))
assertThat(underTest.getInNewCodePeriod()).isTrue();
assertOwasp(underTest);
assertThat(underTest.getStigAsdV5R3()).containsExactly("V-222400", "V-222401");
+ 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");
assertThat(securityStandards.getStig(RulesDefinition.StigVersion.ASD_V5R3)).containsExactly("V-222400");
}
+ @Test
+ void fromSecurityStandards_shouldReturnExpectedCasaBasedOnCweMapping() {
+ SecurityStandards securityStandards = fromSecurityStandards(Set.of("cwe:326", "cwe:477"));
+ assertThat(securityStandards.getCasa()).containsExactly("6.2.3", "1.14.6", "9.1.2", "6.2.7", "6.2.4");
+ }
+
@Test
void fromSecurityStandards_finds_SQCategory_first_in_order_when_CWEs_map_to_multiple_SQCategories() {
EnumSet<SQCategory> sqCategories = EnumSet.allOf(SQCategory.class);
import static org.sonar.server.issue.index.IssueIndex.Facet.ASSIGNED_TO_ME;
import static org.sonar.server.issue.index.IssueIndex.Facet.ASSIGNEES;
import static org.sonar.server.issue.index.IssueIndex.Facet.AUTHOR;
+import static org.sonar.server.issue.index.IssueIndex.Facet.CASA;
import static org.sonar.server.issue.index.IssueIndex.Facet.CLEAN_CODE_ATTRIBUTE_CATEGORY;
import static org.sonar.server.issue.index.IssueIndex.Facet.CODE_VARIANTS;
import static org.sonar.server.issue.index.IssueIndex.Facet.CREATED_AT;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_BRANCH_UUID;
+import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_CASA;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_CLEAN_CODE_ATTRIBUTE_CATEGORY;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_CODE_VARIANTS;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_COMPONENT_UUID;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ASSIGNEES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_AUTHOR;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CASA;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CLEAN_CODE_ATTRIBUTE_CATEGORIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CODE_VARIANTS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AT;
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),
+ CASA(PARAM_CASA, FIELD_ISSUE_CASA, 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),
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);
+ addSecurityCategoryPrefixFilter(FIELD_ISSUE_CASA, CASA, query.casa(), 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);
}
/**
- * <p>Builds the Elasticsearch boolean query to filter the PCI DSS categories.</p>
+ * <p>Builds the Elasticsearch boolean query to filter the PCI DSS and CASA.</p>
*
* <p>The PCI DSS security report handles all the subcategories as one level. This means that subcategory 1.1 doesn't include the issues from 1.1.1.
* Taking this into account, the search filter follows the same logic and uses prefix matching for top-level categories and exact matching for subcategories</p>
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_CASA, CASA, options, aggregationHelper, esRequest, query.casa().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 Integer owaspAsvsLevel;
private final Collection<String> owaspTop10For2021;
private final Collection<String> stigAsdV5R3;
+ private final Collection<String> casa;
private final Collection<String> sansTop25;
private final Collection<String> cwe;
private final Collection<String> sonarsourceSecurity;
this.owaspTop10 = defaultCollection(builder.owaspTop10);
this.owaspTop10For2021 = defaultCollection(builder.owaspTop10For2021);
this.stigAsdV5R3 = defaultCollection(builder.stigAsdV5R3);
+ this.casa = defaultCollection(builder.casa);
this.sansTop25 = defaultCollection(builder.sansTop25);
this.cwe = defaultCollection(builder.cwe);
this.sonarsourceSecurity = defaultCollection(builder.sonarsourceSecurity);
return stigAsdV5R3;
}
+ public Collection<String> casa() {
+ return casa;
+ }
+
public Collection<String> sansTop25() {
return sansTop25;
}
private Collection<String> owaspTop10;
private Collection<String> owaspTop10For2021;
private Collection<String> stigAsdV5R3;
+ private Collection<String> casa;
private Collection<String> sansTop25;
private Collection<String> cwe;
private Collection<String> sonarsourceSecurity;
return this;
}
+ public Builder casa(@Nullable Collection<String> o) {
+ this.casa = o;
+ return this;
+ }
+
public Builder sansTop25(@Nullable Collection<String> s) {
this.sansTop25 = s;
return this;
.owaspTop10(request.getOwaspTop10())
.owaspTop10For2021(request.getOwaspTop10For2021())
.stigAsdR5V3(request.getStigAsdV5R3())
+ .casa(request.getCasa())
.sansTop25(request.getSansTop25())
.cwe(request.getCwe())
.sonarsourceSecurity(request.getSonarsourceSecurity())
assertThat(query.stigAsdV5R3()).containsOnly("V-222400", "V-222401");
}
+ @Test
+ void build_casa_query() {
+ IssueQuery query = IssueQuery.builder()
+ .casa(List.of("1.1.4", "6.1.1"))
+ .build();
+
+ assertThat(query.casa()).containsOnly("1.1.4", "6.1.1");
+ }
+
@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_CASA;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STIG_ASD_V5R3;
@SuppressWarnings("ALL")
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 casa = actionTester.getDef().param(PARAM_CASA);
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(owaspTop10Param.isRequired()).isFalse();
assertThat(stigAsdV5R3).isNotNull();
assertThat(stigAsdV5R3.isRequired()).isFalse();
+ assertThat(casa).isNotNull();
+ assertThat(casa.isRequired()).isFalse();
assertThat(sansTop25Param).isNotNull();
assertThat(sansTop25Param.isRequired()).isFalse();
assertThat(sonarsourceSecurityParam).isNotNull();
.containsExactly(hotspot3.getKey());
}
+ @Test
+ public void executeProtobuf_WhenHotspotHasCwe_shoultReturnExpectedHotspotOnCasaParam() {
+ 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:310")));
+ RuleDto rule3 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(Set.of("cwe:639")));
+ insertHotspot(project, file, rule1);
+ insertHotspot(project, file, rule2);
+ IssueDto hotspot3 = insertHotspot(project, file, rule3);
+ indexIssues();
+
+ SearchWsResponse response = newRequest(project).setParam(PARAM_CASA, "4.1.2")
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(response.getHotspotsList())
+ .extracting(SearchWsResponse.Hotspot::getKey)
+ .containsExactly(hotspot3.getKey());
+
+ response = newRequest(project).setParam(PARAM_CASA, "4")
+ .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();
SearchWsResponse result = ws.newRequest()
.setParam("stig-ASD_V5R3", "V-222402")
+ .setParam(FACETS, "stig-ASD_V5R3")
.executeProtobuf(SearchWsResponse.class);
assertThat(result.getIssuesList())
.extracting(Issue::getKey)
.containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey());
+
+ assertThat(result.getFacets().getFacets(0).getValuesList())
+ .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
+ .containsExactlyInAnyOrder(tuple("V-222402", 2L), tuple("V-222403", 2L), tuple("V-222404", 2L));
+ }
+
+ @Test
+ public void only_vulnerabilities_are_returned_by_casa() {
+ 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", "cwe:639", "cwe:326"))
+ .setSystemTags(Sets.newHashSet("bad-practice", "cwe", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "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("casa", "4.1.2")
+ .setParam(FACETS, "casa")
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(result.getIssuesList())
+ .extracting(Issue::getKey)
+ .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey());
+
+ assertThat(result.getFacets().getFacets(0).getValuesList())
+ .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
+ .containsExactlyInAnyOrder(tuple("4.1.2", 2L), tuple("4.2.1", 2L), tuple("6.2.3", 2L),
+ tuple("6.2.4", 2L), tuple("6.2.7", 2L), tuple("9.1.2", 2L));
+
+ result = ws.newRequest()
+ .setParam("casa", "4")
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(result.getIssuesList())
+ .as("We should be able to search with only the prefix '4'")
+ .extracting(Issue::getKey)
+ .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey());
}
@Test
"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", "stig-ASD_V5R3", "sansTop25", "cwe", "sonarsourceSecurity", "timeZone", "inNewCodePeriod", "codeVariants",
+ "owaspAsvsLevel", "owaspTop10", "owaspTop10-2021", "stig-ASD_V5R3", "casa", "sansTop25", "cwe", "sonarsourceSecurity", "timeZone", "inNewCodePeriod", "codeVariants",
"cleanCodeAttributeCategories", "impactSeverities", "impactSoftwareQualities", "issueStatuses", "fixedInPullRequest",
"prioritizedRule");
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";
+ private static final String PARAM_CASA = "casa";
/**
* @deprecated SansTop25 report is outdated, it has been completely deprecated in version 10.0 and will be removed from version 11.0
*/
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> casa = setFromList(request.paramAsStrings(PARAM_CASA));
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, stigAsdV5R3, sansTop25, sonarsourceSecurity, cwes, files);
+ pciDss32, pciDss40, owaspAsvs40, owasp2017Top10, owasp2021Top10, stigAsdV5R3, casa, sansTop25, sonarsourceSecurity, cwes, files);
}
@Override
if (!wsRequest.getStigAsdV5R3().isEmpty()) {
builder.stigAsdR5V3(wsRequest.getStigAsdV5R3());
}
+ if (!wsRequest.getCasa().isEmpty()) {
+ builder.casa(wsRequest.getCasa());
+ }
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.7", format("Added parameter '%s' and '%s'", PARAM_STIG_ASD_V5R3, PARAM_CASA)),
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"),
action.createParam(PARAM_STIG_ASD_V5R3)
.setDescription("Comma-separated list of STIG V5R3 lowercase categories.")
.setSince("10.7");
+ action.createParam(PARAM_CASA)
+ .setDescription("Comma-separated list of CASA 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> owaspTop10For2017;
private final Set<String> owaspTop10For2021;
private final Set<String> stigAsdV5R3;
+ private final Set<String> casa;
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> stigAsdV5R3, Set<String> sansTop25, Set<String> sonarsourceSecurity,
+ Set<String> owaspTop10For2017, Set<String> owaspTop10For2021, Set<String> stigAsdV5R3, Set<String> casa, Set<String> sansTop25, Set<String> sonarsourceSecurity,
Set<String> cwe, @Nullable Set<String> files) {
this.page = page;
this.index = index;
this.owaspTop10For2017 = owaspTop10For2017;
this.owaspTop10For2021 = owaspTop10For2021;
this.stigAsdV5R3 = stigAsdV5R3;
+ this.casa = casa;
this.sansTop25 = sansTop25;
this.sonarsourceSecurity = sonarsourceSecurity;
this.cwe = cwe;
return stigAsdV5R3;
}
+ public Set<String> getCasa() {
+ return casa;
+ }
+
public Set<String> getSansTop25() {
return sansTop25;
}
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ASSIGNEES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_AUTHOR;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_BRANCH;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CASA;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CLEAN_CODE_ATTRIBUTE_CATEGORIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CODE_VARIANTS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENTS;
PARAM_OWASP_TOP_10,
PARAM_OWASP_TOP_10_2021,
PARAM_STIG_ASD_V5R3,
+ PARAM_CASA,
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_CASA)),
+ new Change("10.7", format(NEW_PARAM_ADDED_MESSAGE, PARAM_CASA)),
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)),
.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");
+ .setSince("10.7");
+ action.createParam(PARAM_CASA)
+ .setDescription("Comma-separated list of CASA categories.")
+ .setSince("10.7");
action.createParam(PARAM_SANS_TOP_25)
.setDescription("Comma-separated list of SANS Top 25 categories.")
.setDeprecatedSince("10.0")
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_CASA, request.getCasa());
addMandatoryValuesToFacet(facets, PARAM_SANS_TOP_25, request.getSansTop25());
addMandatoryValuesToFacet(facets, PARAM_CWE, request.getCwe());
addMandatoryValuesToFacet(facets, PARAM_SONARSOURCE_SECURITY, request.getSonarsourceSecurity());
.setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10))
.setOwaspTop10For2021(request.paramAsStrings(PARAM_OWASP_TOP_10_2021))
.setStigAsdV5R3(request.paramAsStrings(PARAM_STIG_ASD_V5R3))
+ .setCasa(request.paramAsStrings(PARAM_CASA))
.setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25))
.setCwe(request.paramAsStrings(PARAM_CWE))
.setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY))
public static final String PARAM_OWASP_TOP_10_2021 = "owaspTop10-2021";
public static final String PARAM_STIG_ASD_V5R3 = "stig-ASD_V5R3";
public static final String PARAM_STIG = "stig";
+ public static final String PARAM_CASA = "casa";
@Deprecated
public static final String PARAM_SANS_TOP_25 = "sansTop25";
public static final String PARAM_CWE_TOP_25 = "cweTop25";