From e70a0ee238f53c66cdaf8b808b3391f43ad784a2 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 21 Oct 2016 07:06:47 -0400 Subject: [PATCH] corrected how project references are propogated when the same dependency is analyzed more then once --- .../org/owasp/dependencycheck/Engine.java | 135 ++++++++++++++++-- .../analyzer/ArchiveAnalyzer.java | 1 + .../maven/BaseDependencyCheckMojo.java | 4 +- 3 files changed, 128 insertions(+), 12 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java index 54f4e12b2..bd44b21b9 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java @@ -197,9 +197,24 @@ public class Engine implements FileFilter { * @since v0.3.2.5 */ public List scan(String[] paths) { + return scan(paths, null); + } + + /** + * Scans an array of files or directories. If a directory is specified, it + * will be scanned recursively. Any dependencies identified are added to the + * dependency collection. + * + * @param paths an array of paths to files or directories to be analyzed + * @param projectReference the name of the project or scope in which the + * dependency was identified + * @return the list of dependencies scanned + * @since v1.4.4 + */ + public List scan(String[] paths, String projectReference) { final List deps = new ArrayList(); for (String path : paths) { - final List d = scan(path); + final List d = scan(path, projectReference); if (d != null) { deps.addAll(d); } @@ -216,8 +231,23 @@ public class Engine implements FileFilter { * @return the list of dependencies scanned */ public List scan(String path) { + return scan(path, null); + } + + /** + * Scans a given file or directory. If a directory is specified, it will be + * scanned recursively. Any dependencies identified are added to the + * dependency collection. + * + * @param path the path to a file or directory to be analyzed + * @param projectReference the name of the project or scope in which the + * dependency was identified + * @return the list of dependencies scanned + * @since v1.4.4 + */ + public List scan(String path, String projectReference) { final File file = new File(path); - return scan(file); + return scan(file, projectReference); } /** @@ -230,9 +260,24 @@ public class Engine implements FileFilter { * @since v0.3.2.5 */ public List scan(File[] files) { + return scan(files, null); + } + + /** + * Scans an array of files or directories. If a directory is specified, it + * will be scanned recursively. Any dependencies identified are added to the + * dependency collection. + * + * @param files an array of paths to files or directories to be analyzed. + * @param projectReference the name of the project or scope in which the + * dependency was identified + * @return the list of dependencies + * @since v1.4.4 + */ + public List scan(File[] files, String projectReference) { final List deps = new ArrayList(); for (File file : files) { - final List d = scan(file); + final List d = scan(file, projectReference); if (d != null) { deps.addAll(d); } @@ -250,9 +295,24 @@ public class Engine implements FileFilter { * @since v0.3.2.5 */ public List scan(Collection files) { + return scan(files, null); + } + + /** + * Scans a collection of files or directories. If a directory is specified, + * it will be scanned recursively. Any dependencies identified are added to + * the dependency collection. + * + * @param files a set of paths to files or directories to be analyzed + * @param projectReference the name of the project or scope in which the + * dependency was identified + * @return the list of dependencies scanned + * @since v1.4.4 + */ + public List scan(Collection files, String projectReference) { final List deps = new ArrayList(); for (File file : files) { - final List d = scan(file); + final List d = scan(file, projectReference); if (d != null) { deps.addAll(d); } @@ -270,11 +330,26 @@ public class Engine implements FileFilter { * @since v0.3.2.4 */ public List scan(File file) { + return scan(file, null); + } + + /** + * Scans a given file or directory. If a directory is specified, it will be + * scanned recursively. Any dependencies identified are added to the + * dependency collection. + * + * @param file the path to a file or directory to be analyzed + * @param projectReference the name of the project or scope in which the + * dependency was identified + * @return the list of dependencies scanned + * @since v1.4.4 + */ + public List scan(File file, String projectReference) { if (file.exists()) { if (file.isDirectory()) { - return scanDirectory(file); + return scanDirectory(file, projectReference); } else { - final Dependency d = scanFile(file); + final Dependency d = scanFile(file, projectReference); if (d != null) { final List deps = new ArrayList(); deps.add(d); @@ -293,17 +368,31 @@ public class Engine implements FileFilter { * @return the list of Dependency objects scanned */ protected List scanDirectory(File dir) { + return scanDirectory(dir, null); + } + + /** + * Recursively scans files and directories. Any dependencies identified are + * added to the dependency collection. + * + * @param dir the directory to scan + * @param projectReference the name of the project or scope in which the + * dependency was identified + * @return the list of Dependency objects scanned + * @since v1.4.4 + */ + protected List scanDirectory(File dir, String projectReference) { final File[] files = dir.listFiles(); final List deps = new ArrayList(); if (files != null) { for (File f : files) { if (f.isDirectory()) { - final List d = scanDirectory(f); + final List d = scanDirectory(f, projectReference); if (d != null) { deps.addAll(d); } } else { - final Dependency d = scanFile(f); + final Dependency d = scanFile(f, projectReference); deps.add(d); } } @@ -319,10 +408,27 @@ public class Engine implements FileFilter { * @return the scanned dependency */ protected Dependency scanFile(File file) { + return scanFile(file, null); + } + + /** + * Scans a specified file. If a dependency is identified it is added to the + * dependency collection. + * + * @param file The file to scan + * @param projectReference the name of the project or scope in which the + * dependency was identified + * @return the scanned dependency + * @since v1.4.4 + */ + protected Dependency scanFile(File file, String projectReference) { Dependency dependency = null; if (file.isFile()) { if (accept(file)) { dependency = new Dependency(file); + if (projectReference != null) { + dependency.addProjectReference(projectReference); + } final String sha1 = dependency.getSha1sum(); boolean found = false; synchronized (dependencies) { @@ -330,7 +436,15 @@ public class Engine implements FileFilter { for (Dependency existing : dependencies) { if (sha1.equals(existing.getSha1sum())) { found = true; - dependency = existing; + if (projectReference != null) { + existing.addProjectReference(projectReference); + } + if (existing.getActualFilePath() != null && dependency.getActualFilePath() != null + && !existing.getActualFilePath().equals(dependency.getActualFilePath())) { + existing.addRelatedDependency(dependency); + } else { + dependency = existing; + } } } } @@ -432,7 +546,8 @@ public class Engine implements FileFilter { /** * Executes executes the analyzer using multiple threads. * - * @param exceptions a collection of exceptions that occurred during analysis + * @param exceptions a collection of exceptions that occurred during + * analysis * @param analyzer the analyzer to execute * @throws ExceptionCollection thrown if exceptions occurred during analysis */ diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.java index 4138b9ec2..8f3b49751 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.java @@ -261,6 +261,7 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { d.getFileName()); d.setFilePath(displayPath); d.setFileName(displayName); + d.setProjectReferences(dependency.getProjectReferences()); //TODO - can we get more evidence from the parent? EAR contains module name, etc. //analyze the dependency (i.e. extract files) if it is a supported type. diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 1ab88141c..d39f9560b 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -661,7 +661,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma try { final ArtifactResult result = repoSystem.resolveArtifact(repoSession, request); if (result.isResolved() && result.getArtifact() != null && result.getArtifact().getFile() != null) { - final List deps = engine.scan(result.getArtifact().getFile().getAbsoluteFile()); + final List deps = engine.scan(result.getArtifact().getFile().getAbsoluteFile(), + project.getName() + ":" + dependencyNode.getArtifact().getScope()); if (deps != null) { if (deps.size() == 1) { final Dependency d = deps.get(0); @@ -669,7 +670,6 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma final Artifact a = result.getArtifact(); final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion()); d.addAsEvidence("pom", ma, Confidence.HIGHEST); - d.addProjectReference(project.getName() + ":" + dependencyNode.getArtifact().getScope()); if (getLog().isDebugEnabled()) { getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(), d.getDisplayFileName()));