diff --git a/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java b/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java index 7f16342a027..11d130354d9 100644 --- a/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java +++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java @@ -211,6 +211,7 @@ public static void mergeDependencies(final Dependency dependency, // we may want to merge project references on virtual dependencies... if (dependency.getSha1sum() != null && dependency.getSha1sum().equals(relatedDependency.getSha1sum())) { dependency.addAllProjectReferences(relatedDependency.getProjectReferences()); + dependency.addAllIncludedBy(relatedDependency.getIncludedBy()); } if (dependenciesToRemove != null) { dependenciesToRemove.add(relatedDependency); diff --git a/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java b/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java index 0d5393c1f00..92a1402ebd2 100644 --- a/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java +++ b/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java @@ -102,6 +102,13 @@ public class Dependency extends EvidenceCollection implements Serializable { * A collection of related dependencies. */ private final SortedSet relatedDependencies = new TreeSet<>(Dependency.NAME_COMPARATOR); + /** + * The set of dependencies that included this dependency (i.e., this is a + * transitive dependency because it was included by X). This is a pair where + * the left element is the includedBy and the right element is the type + * (e.g. buildEnv, plugins). + */ + private final Set includedBy = new HashSet<>(); /** * A list of projects that reference this dependency. */ @@ -784,6 +791,46 @@ public synchronized void clearRelatedDependencies() { relatedDependencies.clear(); } + /** + * Get the unmodifiable set of includedBy (the list of parents of this + * transitive dependency). + * + * @return the unmodifiable set of includedBy + */ + public synchronized Set getIncludedBy() { + return Collections.unmodifiableSet(new HashSet<>(includedBy)); + } + + /** + * Adds the parent or root of the transitive dependency chain (i.e., this + * was included by the parent dependency X). + * + * @param includedBy a project reference + */ + public synchronized void addIncludedBy(String includedBy) { + this.includedBy.add(new IncludedByReference(includedBy, null)); + } + + /** + * Adds the parent or root of the transitive dependency chain (i.e., this + * was included by the parent dependency X). + * + * @param includedBy a project reference + * @param type the type of project reference (i.e. 'plugins', 'buildEnv') + */ + public synchronized void addIncludedBy(String includedBy, String type) { + this.includedBy.add(new IncludedByReference(includedBy, type)); + } + + /** + * Adds a set of project references. + * + * @param includedBy a set of project references + */ + public synchronized void addAllIncludedBy(Set includedBy) { + this.includedBy.addAll(includedBy); + } + /** * Get the unmodifiable set of projectReferences. * diff --git a/core/src/main/java/org/owasp/dependencycheck/dependency/IncludedByReference.java b/core/src/main/java/org/owasp/dependencycheck/dependency/IncludedByReference.java new file mode 100644 index 00000000000..bc8d70523e7 --- /dev/null +++ b/core/src/main/java/org/owasp/dependencycheck/dependency/IncludedByReference.java @@ -0,0 +1,73 @@ +/* + * This file is part of dependency-check-core. + * + * 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. + * + * Copyright (c) 2023 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.dependency; + +import java.io.Serializable; + +/** + * POJO to store a reference to the "included by" node in a dependency tree; + * where included by is the root node that caused a dependency to be included. + * + * @author Jeremy Long + */ +public class IncludedByReference implements Serializable { + + /** + * The serial version UID for serialization. + */ + private static final long serialVersionUID = 4339975160204621746L; + + /** + * The reference. + */ + private final String reference; + /** + * The reference's type. + */ + private final String type; + + /** + * Constructs a new reference. + * + * @param reference the reference + * @param type the reference's type + */ + public IncludedByReference(String reference, String type) { + this.reference = reference; + this.type = type; + } + + /** + * Get the value of reference. + * + * @return the value of reference + */ + public String getReference() { + return reference; + } + + /** + * Get the value of type. + * + * @return the value of type + */ + public String getType() { + return type; + } + +} diff --git a/core/src/main/resources/schema/dependency-check.2.5.xsd b/core/src/main/resources/schema/dependency-check.2.5.xsd index 9e18c373499..f258e0661bc 100644 --- a/core/src/main/resources/schema/dependency-check.2.5.xsd +++ b/core/src/main/resources/schema/dependency-check.2.5.xsd @@ -195,6 +195,21 @@ + + + + + + + + + + + + + + + diff --git a/core/src/main/resources/templates/htmlReport.vsl b/core/src/main/resources/templates/htmlReport.vsl index 76478d501d6..45587a2a6d9 100644 --- a/core/src/main/resources/templates/htmlReport.vsl +++ b/core/src/main/resources/templates/htmlReport.vsl @@ -605,6 +605,28 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. .underline { text-decoration: underline; } + .tooltip { + position: relative; + display: inline-block; + border-bottom: 1px dotted black; + } + + .tooltip .tooltiptext { + visibility: hidden; + width: 220px; + background-color: #cccccc; + text-align: center; + border-radius: 6px; + padding: 5px 0; + + /* Position the tooltip */ + position: absolute; + z-index: 1; + } + + .tooltip:hover .tooltiptext { + visibility: visible; + } @@ -815,10 +837,7 @@ Getting Help: SHA256:$enc.html($dependency.Sha256sum) #end #if ($dependency.projectReferences.size()==1) -
Referenced In Project/Scope: - #foreach($ref in $dependency.projectReferences) - $enc.html($ref) - #end +
Referenced In Project/Scope: $enc.html($dependency.projectReferences.iterator().next()) #end #if ($dependency.projectReferences.size()>1)
Referenced In Projects/Scopes: