Browse Source

SONAR-11370 Extract Owasp, SansTop25 constant to a dedicated helper

tags/7.5
Eric Hartmann 5 years ago
parent
commit
069f74065c

+ 0
- 17
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java View File

@@ -19,17 +19,12 @@
*/
package org.sonar.server.issue.index;

import com.google.common.collect.ImmutableMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.sonar.api.config.Configuration;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.server.es.IndexDefinition;
import org.sonar.server.es.IndexType;
import org.sonar.server.es.NewIndex;

import static java.util.Arrays.asList;
import static org.sonar.server.es.DefaultIndexSettingsElement.SORTABLE_ANALYZER;
import static org.sonar.server.es.NewIndex.SettingsConfiguration.MANUAL_REFRESH_INTERVAL;
import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
@@ -100,18 +95,6 @@ public class IssueIndexDefinition implements IndexDefinition {
public static final String FIELD_ISSUE_OWASP_TOP_10 = "owaspTop10";
public static final String FIELD_ISSUE_SANS_TOP_25 = "sansTop25";
public static final String FIELD_ISSUE_CWE = "cwe";
public static final String UNKNOWN_STANDARD = "unknown";
public static final String SANS_TOP_25_INSECURE_INTERACTION = "insecure-interaction";
public static final String SANS_TOP_25_RISKY_RESOURCE = "risky-resource";
public static final String SANS_TOP_25_POROUS_DEFENSES = "porous-defenses";
// See https://www.sans.org/top25-software-errors
private static final Set<String> INSECURE_CWE = new HashSet<>(asList("89", "78", "79", "434", "352", "601"));
private static final Set<String> RISKY_CWE = new HashSet<>(asList("120", "22", "494", "829", "676", "131", "134", "190"));
private static final Set<String> POROUS_CWE = new HashSet<>(asList("306", "862", "798", "311", "807", "250", "863", "732", "327", "307", "759"));
static final Map<String, Set<String>> SANS_TOP_25_CWE_MAPPING = ImmutableMap.of(
SANS_TOP_25_INSECURE_INTERACTION, INSECURE_CWE,
SANS_TOP_25_RISKY_RESOURCE, RISKY_CWE,
SANS_TOP_25_POROUS_DEFENSES, POROUS_CWE);

private final Configuration config;
private final boolean enableSource;

+ 8
- 20
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java View File

@@ -27,7 +27,6 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -42,11 +41,12 @@ import org.sonar.db.DbSession;
import org.sonar.db.ResultSetIterator;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.stream.Collectors.toList;
import static org.sonar.api.utils.DateUtils.longToDate;
import static org.sonar.db.DatabaseUtils.getLong;
import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_CWE_MAPPING;
import static org.sonar.server.issue.index.IssueIndexDefinition.UNKNOWN_STANDARD;
import static org.sonar.server.issue.index.SecurityStandardHelper.getCwe;
import static org.sonar.server.issue.index.SecurityStandardHelper.getOwaspTop10;
import static org.sonar.server.issue.index.SecurityStandardHelper.getSansTop25;
import static org.sonar.server.issue.index.SecurityStandardHelper.getSecurityStandards;

/**
* Scrolls over table ISSUES and reads documents to populate
@@ -94,10 +94,7 @@ class IssueIteratorForSingleChunk implements IssueIterator {
private static final String ISSUE_KEY_FILTER_SUFFIX = ")";

static final Splitter TAGS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
static final Splitter SECURITY_STANDARDS_SPLITTER = TAGS_SPLITTER;
static final Splitter MODULE_PATH_SPLITTER = Splitter.on('.').trimResults().omitEmptyStrings();
private static final String OWASP_TOP10_PREFIX = "owaspTop10:";
private static final String CWE_PREFIX = "cwe:";

private final DbSession session;

@@ -235,23 +232,14 @@ class IssueIteratorForSingleChunk implements IssueIterator {
doc.setType(RuleType.valueOf(rs.getInt(22)));
String securityStandards = rs.getString(23);

List<String> standards = IssueIteratorForSingleChunk.SECURITY_STANDARDS_SPLITTER.splitToList(securityStandards == null ? "" : securityStandards);
List<String> owaspTop10 = standards.stream().filter(s -> s.startsWith(OWASP_TOP10_PREFIX)).map(s -> s.substring(OWASP_TOP10_PREFIX.length())).collect(toList());
doc.setOwaspTop10(owaspTop10.isEmpty() ? Collections.singletonList(UNKNOWN_STANDARD) : owaspTop10);
List<String> cwe = standards.stream().filter(s -> s.startsWith(CWE_PREFIX)).map(s -> s.substring(CWE_PREFIX.length())).collect(toList());
doc.setCwe(cwe.isEmpty() ? Collections.singletonList(UNKNOWN_STANDARD) : cwe);
List<String> standards = getSecurityStandards(securityStandards);
doc.setOwaspTop10(getOwaspTop10(standards));
List<String> cwe = getCwe(standards);
doc.setCwe(cwe);
doc.setSansTop25(getSansTop25(cwe));
return doc;
}

private static List<String> getSansTop25(List<String> cwe) {
return SANS_TOP_25_CWE_MAPPING
.keySet()
.stream()
.filter(k -> cwe.stream().anyMatch(SANS_TOP_25_CWE_MAPPING.get(k)::contains))
.collect(toList());
}

@CheckForNull
private static String extractDirPath(@Nullable String filePath, String scope) {
if (filePath != null) {

+ 20
- 0
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java View File

@@ -32,6 +32,8 @@ public class SecurityStandardCategoryStatistics {
private final long openSecurityHotspots;
private final long wontFixSecurityHotspots;
private final List<SecurityStandardCategoryStatistics> children;
private long activeRules;
private long totalRules;

public SecurityStandardCategoryStatistics(String category, long vulnerabilities, OptionalInt vulnerabiliyRating, long toReviewSecurityHotspots, long openSecurityHotspots,
long wontFixSecurityHotspots, @Nullable List<SecurityStandardCategoryStatistics> children) {
@@ -71,4 +73,22 @@ public class SecurityStandardCategoryStatistics {
public List<SecurityStandardCategoryStatistics> getChildren() {
return children;
}

public long getActiveRules() {
return activeRules;
}

public long getTotalRules() {
return totalRules;
}

public SecurityStandardCategoryStatistics setActiveRules(long activeRules) {
this.activeRules = activeRules;
return this;
}

public SecurityStandardCategoryStatistics setTotalRules(long totalRules) {
this.totalRules = totalRules;
return this;
}
}

+ 101
- 0
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardHelper.java View File

@@ -0,0 +1,101 @@
/*
* SonarQube
* Copyright (C) 2009-2018 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package org.sonar.server.issue.index;

import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;

public class SecurityStandardHelper {

public static final String UNKNOWN_STANDARD = "unknown";
public static final String SANS_TOP_25_INSECURE_INTERACTION = "insecure-interaction";
public static final String SANS_TOP_25_RISKY_RESOURCE = "risky-resource";
public static final String SANS_TOP_25_POROUS_DEFENSES = "porous-defenses";

private static final String OWASP_TOP10_PREFIX = "owaspTop10:";
private static final String CWE_PREFIX = "cwe:";
// See https://www.sans.org/top25-software-errors
private static final Set<String> INSECURE_CWE = new HashSet<>(asList("89", "78", "79", "434", "352", "601"));
private static final Set<String> RISKY_CWE = new HashSet<>(asList("120", "22", "494", "829", "676", "131", "134", "190"));
private static final Set<String> POROUS_CWE = new HashSet<>(asList("306", "862", "798", "311", "807", "250", "863", "732", "327", "307", "759"));

public static final Map<String, Set<String>> SANS_TOP_25_CWE_MAPPING = ImmutableMap.of(
SANS_TOP_25_INSECURE_INTERACTION, INSECURE_CWE,
SANS_TOP_25_RISKY_RESOURCE, RISKY_CWE,
SANS_TOP_25_POROUS_DEFENSES, POROUS_CWE);

private static final Splitter SECURITY_STANDARDS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();

private SecurityStandardHelper() {
// Utility class
}

public static List<String> getSecurityStandards(@Nullable String securityStandards) {
return securityStandards == null ? emptyList() : SECURITY_STANDARDS_SPLITTER.splitToList(securityStandards);
}

public static List<String> getSansTop25(Collection<String> cwe) {
return SANS_TOP_25_CWE_MAPPING
.keySet()
.stream()
.filter(k -> cwe.stream().anyMatch(SANS_TOP_25_CWE_MAPPING.get(k)::contains))
.collect(toList());
}

public static List<String> getOwaspTop10(Collection<String> securityStandards) {
List<String> result = securityStandards.stream()
.filter(s -> s.startsWith(OWASP_TOP10_PREFIX))
.map(s -> s.substring(OWASP_TOP10_PREFIX.length()))
.collect(toList());
return result.isEmpty() ? singletonList(UNKNOWN_STANDARD) : result;
}

public static List<String> getCwe(Collection<String> securityStandards) {
List<String> result = securityStandards.stream()
.filter(s -> s.startsWith(CWE_PREFIX))
.map(s -> s.substring(CWE_PREFIX.length()))
.collect(toList());
return result.isEmpty() ? singletonList(UNKNOWN_STANDARD) : result;
}

public static List<String> getSansTop25(String securityStandards) {
return getSansTop25(getCwe(getSecurityStandards(securityStandards)));
}

public static List<String> getOwaspTop10(String securityStandards) {
return getOwaspTop10(getSecurityStandards(securityStandards));
}

public static List<String> getCwe(String securityStandards) {
return getCwe(getSecurityStandards(securityStandards));
}
}

+ 2
- 2
server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java View File

@@ -57,8 +57,8 @@ import static org.junit.rules.ExpectedException.none;
import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.server.issue.IssueDocTesting.newDoc;
import static org.sonar.server.issue.index.IssueIndexDefinition.INDEX_TYPE_ISSUE;
import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.IssueIndexDefinition.UNKNOWN_STANDARD;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.permission.index.IndexAuthorizationConstants.TYPE_AUTHORIZATION;

public class IssueIndexerTest {

+ 4
- 4
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java View File

@@ -143,10 +143,10 @@ import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_STAT
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.INDEX_TYPE_ISSUE;
import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.issue.index.IssueIndexDefinition.UNKNOWN_STANDARD;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
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_AUTHORS;

+ 4
- 4
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java View File

@@ -73,10 +73,10 @@ import static org.sonar.process.ProcessProperties.Property.SONARCLOUD_ENABLED;
import static org.sonar.server.es.SearchOptions.MAX_LIMIT;
import static org.sonar.server.issue.index.IssueIndex.FACET_ASSIGNED_TO_ME;
import static org.sonar.server.issue.index.IssueIndex.FACET_PROJECTS;
import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.issue.index.IssueIndexDefinition.UNKNOWN_STANDARD;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.issue.index.IssueQuery.SORT_BY_ASSIGNEE;
import static org.sonar.server.issue.index.IssueQueryFactory.UNKNOWN;
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;

+ 4
- 4
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java View File

@@ -54,10 +54,10 @@ import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
import static org.sonar.server.issue.IssueDocTesting.newDoc;
import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.issue.index.IssueIndexDefinition.UNKNOWN_STANDARD;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;

public class IssueIndexSecurityReportsTest {


Loading…
Cancel
Save