Skip to content

Commit

Permalink
Merge pull request #723 from DependencyTrack/port-global-audit-view-f…
Browse files Browse the repository at this point in the history
…or-vulnerabilities

Port: Global Audit View for vulnerabilities
  • Loading branch information
nscuro authored Jun 16, 2024
2 parents bc0a8be + 8e04db2 commit 1dee6fe
Show file tree
Hide file tree
Showing 7 changed files with 998 additions and 6 deletions.
68 changes: 62 additions & 6 deletions src/main/java/org/dependencytrack/model/Finding.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,58 @@ public class Finding implements Serializable {
WHERE "COMPONENT"."PROJECT_ID" = ?
""";

// language=SQL
public static final String QUERY_ALL_FINDINGS = """
SELECT "COMPONENT"."UUID"
, "COMPONENT"."NAME"
, "COMPONENT"."GROUP"
, "COMPONENT"."VERSION"
, "COMPONENT"."PURL"
, "COMPONENT"."CPE"
, "VULNERABILITY"."UUID"
, "VULNERABILITY"."SOURCE"
, "VULNERABILITY"."VULNID"
, "VULNERABILITY"."TITLE"
, "VULNERABILITY"."SUBTITLE"
, "VULNERABILITY"."DESCRIPTION"
, "VULNERABILITY"."RECOMMENDATION"
, "VULNERABILITY"."SEVERITY"
, "VULNERABILITY"."CVSSV2BASESCORE"
, "VULNERABILITY"."CVSSV3BASESCORE"
, "VULNERABILITY"."OWASPRRLIKELIHOODSCORE"
, "VULNERABILITY"."OWASPRRTECHNICALIMPACTSCORE"
, "VULNERABILITY"."OWASPRRBUSINESSIMPACTSCORE"
, "EPSS"."SCORE"
, "EPSS"."PERCENTILE"
, "VULNERABILITY"."CWES"
, "FINDINGATTRIBUTION"."ANALYZERIDENTITY"
, "FINDINGATTRIBUTION"."ATTRIBUTED_ON"
, "FINDINGATTRIBUTION"."ALT_ID"
, "FINDINGATTRIBUTION"."REFERENCE_URL"
, "ANALYSIS"."STATE"
, "ANALYSIS"."SUPPRESSED"
, "VULNERABILITY"."PUBLISHED"
, "PROJECT"."UUID"
, "PROJECT"."NAME"
, "PROJECT"."VERSION"
FROM "COMPONENT"
INNER JOIN "COMPONENTS_VULNERABILITIES"
ON "COMPONENT"."ID" = "COMPONENTS_VULNERABILITIES"."COMPONENT_ID"
INNER JOIN "VULNERABILITY"
ON "COMPONENTS_VULNERABILITIES"."VULNERABILITY_ID" = "VULNERABILITY"."ID"
LEFT JOIN "EPSS"
ON "VULNERABILITY"."VULNID" = "EPSS"."CVE"
INNER JOIN "FINDINGATTRIBUTION"
ON "COMPONENT"."ID" = "FINDINGATTRIBUTION"."COMPONENT_ID"
AND "VULNERABILITY"."ID" = "FINDINGATTRIBUTION"."VULNERABILITY_ID"
LEFT JOIN "ANALYSIS"
ON "COMPONENT"."ID" = "ANALYSIS"."COMPONENT_ID"
AND "VULNERABILITY"."ID" = "ANALYSIS"."VULNERABILITY_ID"
AND "COMPONENT"."PROJECT_ID" = "ANALYSIS"."PROJECT_ID"
INNER JOIN "PROJECT"
ON "COMPONENT"."PROJECT_ID" = "PROJECT"."ID"
""";

private final UUID project;
private final Map<String, Object> component = new LinkedHashMap<>();
private final Map<String, Object> vulnerability = new LinkedHashMap<>();
Expand All @@ -109,9 +161,8 @@ public class Finding implements Serializable {
/**
* Constructs a new Finding object. The generic Object array passed as an argument is the
* individual values for each row in a resultset. The order of these must match the order
* of the columns being queried in {@link #QUERY}.
*
* @param o An array of values specific to an individual row returned from {@link #QUERY}
* of the columns being queried in {@link #QUERY} or {@link #QUERY_ALL_FINDINGS}.
* @param o An array of values specific to an individual row returned from {@link #QUERY} or {@link #QUERY_ALL_FINDINGS}
*/
public Finding(UUID project, Object... o) {
this.project = project;
Expand Down Expand Up @@ -154,6 +205,11 @@ public Finding(UUID project, Object... o) {

optValue(analysis, "state", o[26]);
optValue(analysis, "isSuppressed", o[27], false);
if (o.length > 30) {
optValue(vulnerability, "published", o[28]);
optValue(component, "projectName", o[30]);
optValue(component, "projectVersion", o[31]);
}
}

public Map<String, Object> getComponent() {
Expand Down Expand Up @@ -216,7 +272,7 @@ public String getMatrix() {
public void addVulnerabilityAliases(List<VulnerabilityAlias> aliases) {
final Set<Map<String, String>> uniqueAliases = new HashSet<>();
for (final VulnerabilityAlias alias : aliases) {
Map<String, String> map = new HashMap<>();
Map<String,String> map = new HashMap<>();
if (alias.getCveId() != null && !alias.getCveId().isBlank()) {
map.put("cveId", alias.getCveId());
}
Expand All @@ -237,6 +293,6 @@ public void addVulnerabilityAliases(List<VulnerabilityAlias> aliases) {
}
uniqueAliases.add(map);
}
vulnerability.put("aliases", uniqueAliases);
vulnerability.put("aliases",uniqueAliases);
}
}
}
101 changes: 101 additions & 0 deletions src/main/java/org/dependencytrack/model/GroupedFinding.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* This file is part of Dependency-Track.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) OWASP Foundation. All Rights Reserved.
*/
package org.dependencytrack.model;

import com.fasterxml.jackson.annotation.JsonInclude;
import org.dependencytrack.util.VulnerabilityUtil;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;

/**
* The GroupedFinding object is a metadata/value object that combines data from multiple tables. The object can
* only be queried on, not updated or deleted. Modifications to data in the GroupedFinding object need to be made
* to the original source object needing modified.
*
* @since 4.8.0
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class GroupedFinding implements Serializable {

private static final long serialVersionUID = 2246518534279822243L;

// language=SQL
public static final String QUERY = """
SELECT "VULNERABILITY"."SOURCE"
, "VULNERABILITY"."VULNID"
, "VULNERABILITY"."TITLE"
, "VULNERABILITY"."SEVERITY"
, "VULNERABILITY"."CVSSV2BASESCORE"
, "VULNERABILITY"."CVSSV3BASESCORE"
, "VULNERABILITY"."OWASPRRLIKELIHOODSCORE"
, "VULNERABILITY"."OWASPRRTECHNICALIMPACTSCORE"
, "VULNERABILITY"."OWASPRRBUSINESSIMPACTSCORE"
, "FINDINGATTRIBUTION"."ANALYZERIDENTITY"
, "VULNERABILITY"."PUBLISHED"
, "VULNERABILITY"."CWES"
, COUNT(DISTINCT "PROJECT"."ID") AS "AFFECTED_PROJECT_COUNT"
FROM "COMPONENT"
INNER JOIN "COMPONENTS_VULNERABILITIES"
ON ("COMPONENT"."ID" = "COMPONENTS_VULNERABILITIES"."COMPONENT_ID")
INNER JOIN "VULNERABILITY"
ON ("COMPONENTS_VULNERABILITIES"."VULNERABILITY_ID" = "VULNERABILITY"."ID")
INNER JOIN "FINDINGATTRIBUTION"
ON ("COMPONENT"."ID" = "FINDINGATTRIBUTION"."COMPONENT_ID")
AND ("VULNERABILITY"."ID" = "FINDINGATTRIBUTION"."VULNERABILITY_ID")
LEFT JOIN "ANALYSIS"
ON ("COMPONENT"."ID" = "ANALYSIS"."COMPONENT_ID")
AND ("VULNERABILITY"."ID" = "ANALYSIS"."VULNERABILITY_ID")
AND ("COMPONENT"."PROJECT_ID" = "ANALYSIS"."PROJECT_ID")
INNER JOIN "PROJECT"
ON ("COMPONENT"."PROJECT_ID" = "PROJECT"."ID")
""";

private Map<String, Object> vulnerability = new LinkedHashMap<>();
private Map<String, Object> attribution = new LinkedHashMap<>();

public GroupedFinding(Object ...o) {
optValue(vulnerability, "source", o[0]);
optValue(vulnerability, "vulnId", o[1]);
optValue(vulnerability, "title", o[2]);
optValue(vulnerability, "severity", VulnerabilityUtil.getSeverity(o[3], (BigDecimal) o[4], (BigDecimal) o[5], (BigDecimal) o[6], (BigDecimal) o[7], (BigDecimal) o[8]));
optValue(vulnerability, "cvssV2BaseScore", o[4]);
optValue(vulnerability, "cvssV3BaseScore", o[5]);
optValue(attribution, "analyzerIdentity", o[9]);
optValue(vulnerability, "published", o[10]);
optValue(vulnerability, "cwes", Finding.getCwes(o[11]));
optValue(vulnerability, "affectedProjectCount", o[12]);
}

public Map getVulnerability() {
return vulnerability;
}

public Map getAttribution() {
return attribution;
}

private void optValue(Map<String, Object> map, String key, Object value) {
if (value != null) {
map.put(key, value);
}
}
}
Loading

0 comments on commit 1dee6fe

Please sign in to comment.