From ab174b4bb4379935ede44bab6f762d2f3c5c3341 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 9 Apr 2018 14:03:04 -0400 Subject: [PATCH 01/36] upgrade dependency tree version --- .../owasp/dependencycheck/maven/BaseDependencyCheckMojo.java | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 0ac70d17881..ca559329768 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -720,8 +720,8 @@ protected File getCorrectOutputDirectory(MavenProject current) { */ protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) { try { - final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(project, null, reactorProjects); final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); + final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null, reactorProjects); return collectDependencies(engine, project, dn.getChildren(), buildingRequest); } catch (DependencyGraphBuilderException ex) { final String msg = String.format("Unable to build dependency graph on project %s", project.getName()); diff --git a/pom.xml b/pom.xml index 4ae6722044f..043c762d5c3 100644 --- a/pom.xml +++ b/pom.xml @@ -172,7 +172,7 @@ Copyright (c) 2012 - Jeremy Long 1.4 - 2.2 + 3.0.1 1.0.4 0.9.1 From 3825a27d86775b732702a13a8df00aa24d7ed46e Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 9 Apr 2018 14:03:22 -0400 Subject: [PATCH 02/36] update invoker properties --- maven/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/maven/pom.xml b/maven/pom.xml index 58ecdba134b..a64ffa488a9 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -136,6 +136,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. org.apache.maven.shared maven-dependency-tree + 3.0.1 org.jmockit @@ -195,6 +196,9 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. ${project.build.directory}/it target/local-repo + + ${project.version} + From b41c68b8f99da366ef7ef52d59f707b284396f38 Mon Sep 17 00:00:00 2001 From: Hans Aikema Date: Sat, 28 Apr 2018 22:28:42 +0200 Subject: [PATCH 03/36] Add project to buildingRequest --- .../org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java | 1 + 1 file changed, 1 insertion(+) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index ca559329768..539d8f0315a 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -721,6 +721,7 @@ protected File getCorrectOutputDirectory(MavenProject current) { protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) { try { final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); + buildingRequest.setProject(project); final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null, reactorProjects); return collectDependencies(engine, project, dn.getChildren(), buildingRequest); } catch (DependencyGraphBuilderException ex) { From ea0603ff03c7847b37f2ab0a32305a8dc6cb3c42 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 9 Apr 2018 14:03:04 -0400 Subject: [PATCH 04/36] upgrade dependency tree version --- .../owasp/dependencycheck/maven/BaseDependencyCheckMojo.java | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 0ac70d17881..ca559329768 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -720,8 +720,8 @@ protected File getCorrectOutputDirectory(MavenProject current) { */ protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) { try { - final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(project, null, reactorProjects); final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); + final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null, reactorProjects); return collectDependencies(engine, project, dn.getChildren(), buildingRequest); } catch (DependencyGraphBuilderException ex) { final String msg = String.format("Unable to build dependency graph on project %s", project.getName()); diff --git a/pom.xml b/pom.xml index d9ca9e65f8a..4ade018838a 100644 --- a/pom.xml +++ b/pom.xml @@ -172,7 +172,7 @@ Copyright (c) 2012 - Jeremy Long 1.4 - 2.2 + 3.0.1 1.0.4 0.9.1 From 7c8dbcceefc692a3b5c3b16dce3f1028dee72984 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 9 Apr 2018 14:03:22 -0400 Subject: [PATCH 05/36] update invoker properties --- maven/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/maven/pom.xml b/maven/pom.xml index 4105b776aee..e41b41163fe 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -136,6 +136,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. org.apache.maven.shared maven-dependency-tree + 3.0.1 org.jmockit @@ -195,6 +196,9 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. ${project.build.directory}/it target/local-repo + + ${project.version} + From 0c0b0e3f3be02594857ef7997f31aff7abc30b5b Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 15 Apr 2018 06:37:14 -0400 Subject: [PATCH 06/36] added test case --- maven/src/it/740-aggregate/first/pom.xml | 35 +++++++++++++ maven/src/it/740-aggregate/invoker.properties | 19 +++++++ maven/src/it/740-aggregate/pom.xml | 50 +++++++++++++++++++ maven/src/it/740-aggregate/postbuild.groovy | 29 +++++++++++ maven/src/it/740-aggregate/second/pom.xml | 35 +++++++++++++ .../second/src/main/webapp/WEB-INF/web.xml | 26 ++++++++++ .../src/it/740-aggregate/third/fourth/pom.xml | 35 +++++++++++++ .../fourth/src/main/webapp/WEB-INF/web.xml | 26 ++++++++++ maven/src/it/740-aggregate/third/pom.xml | 31 ++++++++++++ 9 files changed, 286 insertions(+) create mode 100644 maven/src/it/740-aggregate/first/pom.xml create mode 100644 maven/src/it/740-aggregate/invoker.properties create mode 100644 maven/src/it/740-aggregate/pom.xml create mode 100644 maven/src/it/740-aggregate/postbuild.groovy create mode 100644 maven/src/it/740-aggregate/second/pom.xml create mode 100644 maven/src/it/740-aggregate/second/src/main/webapp/WEB-INF/web.xml create mode 100644 maven/src/it/740-aggregate/third/fourth/pom.xml create mode 100644 maven/src/it/740-aggregate/third/fourth/src/main/webapp/WEB-INF/web.xml create mode 100644 maven/src/it/740-aggregate/third/pom.xml diff --git a/maven/src/it/740-aggregate/first/pom.xml b/maven/src/it/740-aggregate/first/pom.xml new file mode 100644 index 00000000000..ec008957d09 --- /dev/null +++ b/maven/src/it/740-aggregate/first/pom.xml @@ -0,0 +1,35 @@ + + + + 4.0.0 + + org.owasp.test + threaded-parent + 1.0.0-SNAPSHOT + + first + jar + + + org.apache.commons + commons-collections4 + 4.1 + + + diff --git a/maven/src/it/740-aggregate/invoker.properties b/maven/src/it/740-aggregate/invoker.properties new file mode 100644 index 00000000000..fe31f576949 --- /dev/null +++ b/maven/src/it/740-aggregate/invoker.properties @@ -0,0 +1,19 @@ +# +# This file is part of dependency-check-maven. +# +# 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) 2014 Jeremy Long. All Rights Reserved. +# + +invoker.goals = install ${project.groupId}:${project.artifactId}:${project.version}:check -X -T 10 diff --git a/maven/src/it/740-aggregate/pom.xml b/maven/src/it/740-aggregate/pom.xml new file mode 100644 index 00000000000..73a17227886 --- /dev/null +++ b/maven/src/it/740-aggregate/pom.xml @@ -0,0 +1,50 @@ + + + + 4.0.0 + org.owasp.test + threaded-parent + 1.0.0-SNAPSHOT + pom + + first + second + third + + + + + org.owasp + dependency-check-maven + ${odc.version} + false + + false + + + + + aggregate + + + + + + + \ No newline at end of file diff --git a/maven/src/it/740-aggregate/postbuild.groovy b/maven/src/it/740-aggregate/postbuild.groovy new file mode 100644 index 00000000000..8c1b639faac --- /dev/null +++ b/maven/src/it/740-aggregate/postbuild.groovy @@ -0,0 +1,29 @@ +/* + * This file is part of dependency-check-maven. + * + * 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) 2014 Jeremy Long. All Rights Reserved. + */ + +import java.nio.charset.Charset; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; + +String log = FileUtils.readFileToString(new File(basedir, "build.log"), Charset.defaultCharset().name()); +int count = StringUtils.countMatches(log, "Download Started for NVD CVE - 2002"); +if (count > 1){ + System.out.println(String.format("NVD CVE was downloaded %s times, should be 0 or 1 times", count)); + return false; +} +return true; \ No newline at end of file diff --git a/maven/src/it/740-aggregate/second/pom.xml b/maven/src/it/740-aggregate/second/pom.xml new file mode 100644 index 00000000000..710eace2e07 --- /dev/null +++ b/maven/src/it/740-aggregate/second/pom.xml @@ -0,0 +1,35 @@ + + + + 4.0.0 + + org.owasp.test + threaded-parent + 1.0.0-SNAPSHOT + + second + jar + + + org.owasp.test + fourth + 1.0.0-SNAPSHOT + + + \ No newline at end of file diff --git a/maven/src/it/740-aggregate/second/src/main/webapp/WEB-INF/web.xml b/maven/src/it/740-aggregate/second/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..65c96051cf0 --- /dev/null +++ b/maven/src/it/740-aggregate/second/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,26 @@ + + + + test-app + + index.html + + + diff --git a/maven/src/it/740-aggregate/third/fourth/pom.xml b/maven/src/it/740-aggregate/third/fourth/pom.xml new file mode 100644 index 00000000000..43581af39fb --- /dev/null +++ b/maven/src/it/740-aggregate/third/fourth/pom.xml @@ -0,0 +1,35 @@ + + + + 4.0.0 + + org.owasp.test + third + 1.0.0-SNAPSHOT + + fourth + jar + + + org.apache.james + apache-mime4j-dom + 0.7.2 + + + \ No newline at end of file diff --git a/maven/src/it/740-aggregate/third/fourth/src/main/webapp/WEB-INF/web.xml b/maven/src/it/740-aggregate/third/fourth/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..65c96051cf0 --- /dev/null +++ b/maven/src/it/740-aggregate/third/fourth/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,26 @@ + + + + test-app + + index.html + + + diff --git a/maven/src/it/740-aggregate/third/pom.xml b/maven/src/it/740-aggregate/third/pom.xml new file mode 100644 index 00000000000..a36ca6f3fb9 --- /dev/null +++ b/maven/src/it/740-aggregate/third/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + org.owasp.test + threaded-parent + 1.0.0-SNAPSHOT + + third + pom + + fourth + + \ No newline at end of file From 251aa8fef5c8aaff18395006ac7c2406cfe0079c Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 30 Apr 2018 06:55:41 -0400 Subject: [PATCH 07/36] fix test case --- maven/src/it/740-aggregate/invoker.properties | 2 +- maven/src/it/740-aggregate/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/maven/src/it/740-aggregate/invoker.properties b/maven/src/it/740-aggregate/invoker.properties index fe31f576949..b5087cc941d 100644 --- a/maven/src/it/740-aggregate/invoker.properties +++ b/maven/src/it/740-aggregate/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals = install ${project.groupId}:${project.artifactId}:${project.version}:check -X -T 10 +invoker.goals = verify -X diff --git a/maven/src/it/740-aggregate/pom.xml b/maven/src/it/740-aggregate/pom.xml index 73a17227886..98ae44a22ca 100644 --- a/maven/src/it/740-aggregate/pom.xml +++ b/maven/src/it/740-aggregate/pom.xml @@ -19,7 +19,7 @@ Copyright (c) 2018 Jeremy Long. All Rights Reserved. 4.0.0 org.owasp.test - threaded-parent + aggregate-parent 1.0.0-SNAPSHOT pom From feb688ff94f24488f77b689ce87f6590028fc68e Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 30 Apr 2018 06:56:10 -0400 Subject: [PATCH 08/36] update to create virtual dependencies --- .../dependency/Dependency.java | 11 + .../maven/BaseDependencyCheckMojo.java | 235 ++++++++++++------ 2 files changed, 171 insertions(+), 75 deletions(-) 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 f84514188a9..ca9ded7d437 100644 --- a/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java +++ b/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java @@ -192,6 +192,17 @@ public Dependency(File file, boolean isVirtual) { determineHashes(file); } + /** + * Constructs a new Dependency object. + * + * @param isVirtual specifies if the dependency is virtual indicating the + * file doesn't actually exist. + */ + public Dependency(boolean isVirtual) { + this(); + this.isVirtual = isVirtual; + } + /** * Returns the file name of the dependency. * diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 539d8f0315a..6bf76601785 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -29,6 +29,7 @@ import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.License; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -51,10 +52,12 @@ import org.apache.maven.shared.model.fileset.FileSet; import org.apache.maven.shared.model.fileset.util.FileSetManager; import org.owasp.dependencycheck.Engine; +import org.owasp.dependencycheck.analyzer.JarAnalyzer; import org.owasp.dependencycheck.data.nexus.MavenArtifact; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; import org.owasp.dependencycheck.dependency.Confidence; import org.owasp.dependencycheck.dependency.Dependency; +import org.owasp.dependencycheck.dependency.EvidenceType; import org.owasp.dependencycheck.dependency.Identifier; import org.owasp.dependencycheck.dependency.Vulnerability; import org.owasp.dependencycheck.exception.DependencyNotFoundException; @@ -152,9 +155,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @Parameter(defaultValue = "${project.build.directory}", required = true) private File outputDirectory; /** - * This is a reference to the >reporting< sections outputDirectory. - * This cannot be configured in the dependency-check mojo directly. - * This generally maps to "target/site". + * This is a reference to the >reporting< sections + * outputDirectory. This cannot be configured in the + * dependency-check mojo directly. This generally maps to "target/site". */ @Parameter(property = "project.reporting.outputDirectory", readonly = true) private File reportOutputDirectory; @@ -228,7 +231,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @Parameter(property = "connectionTimeout", defaultValue = "", required = false) private String connectionTimeout; /** - * Sets whether dependency-check should check if there is a new version available. + * Sets whether dependency-check should check if there is a new version + * available. */ @SuppressWarnings("CanBeFinal") @Parameter(property = "versionCheckEnabled", defaultValue = "true", required = false) @@ -719,11 +723,25 @@ protected File getCorrectOutputDirectory(MavenProject current) { * and scanning the dependencies */ protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) { + return scanArtifacts(project, engine, false); + } + + /** + * Scans the project's artifacts and adds them to the engine's dependency + * list. + * + * @param project the project to scan the dependencies of + * @param engine the engine to use to scan the dependencies + * @param aggregate whether the scan is part of an aggregate build + * @return a collection of exceptions that may have occurred while resolving + * and scanning the dependencies + */ + protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine, boolean aggregate) { try { final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); buildingRequest.setProject(project); final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null, reactorProjects); - return collectDependencies(engine, project, dn.getChildren(), buildingRequest); + return collectDependencies(engine, project, dn.getChildren(), buildingRequest, aggregate); } catch (DependencyGraphBuilderException ex) { final String msg = String.format("Unable to build dependency graph on project %s", project.getName()); getLog().debug(msg, ex); @@ -740,101 +758,106 @@ protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) * @param nodes the list of dependency nodes, generally obtained via the * DependencyGraphBuilder * @param buildingRequest the Maven project building request + * @param aggregate whether the scan is part of an aggregate build * @return a collection of exceptions that may have occurred while resolving * and scanning the dependencies */ private ExceptionCollection collectDependencies(Engine engine, MavenProject project, - List nodes, ProjectBuildingRequest buildingRequest) { + List nodes, ProjectBuildingRequest buildingRequest, boolean aggregate) { ExceptionCollection exCol = null; for (DependencyNode dependencyNode : nodes) { if (artifactScopeExcluded.passes(dependencyNode.getArtifact().getScope()) || artifactTypeExcluded.passes(dependencyNode.getArtifact().getType())) { continue; } - exCol = collectDependencies(engine, project, dependencyNode.getChildren(), buildingRequest); - try { - boolean isResolved = false; - File artifactFile = null; - String artifactId = null; - String groupId = null; - String version = null; - List availableVersions = null; - if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) { - for (org.apache.maven.model.Dependency d : project.getDependencies()) { - final Artifact a = dependencyNode.getArtifact(); - if (d.getSystemPath() != null && artifactsMatch(d, a)) { - - artifactFile = new File(d.getSystemPath()); - isResolved = artifactFile.isFile(); - groupId = a.getGroupId(); - artifactId = a.getArtifactId(); - version = a.getVersion(); - availableVersions = a.getAvailableVersions(); - break; - } + exCol = collectDependencies(engine, project, dependencyNode.getChildren(), buildingRequest, aggregate); + boolean isResolved = false; + File artifactFile = null; + String artifactId = null; + String groupId = null; + String version = null; + List availableVersions = null; + if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) { + for (org.apache.maven.model.Dependency d : project.getDependencies()) { + final Artifact a = dependencyNode.getArtifact(); + if (d.getSystemPath() != null && artifactsMatch(d, a)) { + + artifactFile = new File(d.getSystemPath()); + isResolved = artifactFile.isFile(); + groupId = a.getGroupId(); + artifactId = a.getArtifactId(); + version = a.getVersion(); + availableVersions = a.getAvailableVersions(); + break; + } + } + if (!isResolved) { + getLog().error("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString()); + if (exCol == null) { + exCol = new ExceptionCollection(); } - if (!isResolved) { - getLog().error("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString()); + exCol.addException(new DependencyNotFoundException("Unable to resolve system scoped dependency: " + + dependencyNode.toNodeString())); + } + } else { + final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact()); + final Artifact result; + try { + result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact(); + } catch (ArtifactResolverException ex) { + if (!aggregate || addReactorDependency(engine, dependencyNode.getArtifact())) { if (exCol == null) { exCol = new ExceptionCollection(); } - exCol.addException(new DependencyNotFoundException("Unable to resolve system scoped dependency: " - + dependencyNode.toNodeString())); } - } else { - final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact()); - final Artifact result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact(); - isResolved = result.isResolved(); - artifactFile = result.getFile(); - groupId = result.getGroupId(); - artifactId = result.getArtifactId(); - version = result.getVersion(); - availableVersions = result.getAvailableVersions(); + exCol.addException(ex); + continue; } - if (isResolved && artifactFile != null) { - final List deps = engine.scan(artifactFile.getAbsoluteFile(), - project.getName() + ":" + dependencyNode.getArtifact().getScope()); - if (deps != null) { - if (deps.size() == 1) { - final Dependency d = deps.get(0); - if (d != null) { - final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version); - d.addAsEvidence("pom", ma, Confidence.HIGHEST); - if (availableVersions != null) { - for (ArtifactVersion av : availableVersions) { - d.addAvailableVersion(av.toString()); - } + isResolved = result.isResolved(); + artifactFile = result.getFile(); + groupId = result.getGroupId(); + artifactId = result.getArtifactId(); + version = result.getVersion(); + availableVersions = result.getAvailableVersions(); + } + if (isResolved && artifactFile != null) { + final List deps = engine.scan(artifactFile.getAbsoluteFile(), + project.getName() + ":" + dependencyNode.getArtifact().getScope()); + if (deps != null) { + if (deps.size() == 1) { + final Dependency d = deps.get(0); + if (d != null) { + final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version); + d.addAsEvidence("pom", ma, Confidence.HIGHEST); + if (availableVersions != null) { + for (ArtifactVersion av : availableVersions) { + d.addAvailableVersion(av.toString()); } - getLog().debug(String.format("Adding project reference %s on dependency %s", - project.getName(), d.getDisplayFileName())); } - } else if (getLog().isDebugEnabled()) { - final String msg = String.format("More than 1 dependency was identified in first pass scan of '%s' in project %s", - dependencyNode.getArtifact().getId(), project.getName()); - getLog().debug(msg); + getLog().debug(String.format("Adding project reference %s on dependency %s", + project.getName(), d.getDisplayFileName())); } - } else if ("import".equals(dependencyNode.getArtifact().getScope())) { - final String msg = String.format("Skipping '%s:%s' in project %s as it uses an `import` scope", - dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); + } else if (getLog().isDebugEnabled()) { + final String msg = String.format("More than 1 dependency was identified in first pass scan of '%s' in project %s", + dependencyNode.getArtifact().getId(), project.getName()); getLog().debug(msg); - } else { - final String msg = String.format("No analyzer could be found for '%s:%s' in project %s", - dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); - getLog().warn(msg); } - } else { - final String msg = String.format("Unable to resolve '%s' in project %s", - dependencyNode.getArtifact().getId(), project.getName()); + } else if ("import".equals(dependencyNode.getArtifact().getScope())) { + final String msg = String.format("Skipping '%s:%s' in project %s as it uses an `import` scope", + dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); getLog().debug(msg); - if (exCol == null) { - exCol = new ExceptionCollection(); - } + } else { + final String msg = String.format("No analyzer could be found for '%s:%s' in project %s", + dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); + getLog().warn(msg); } - } catch (ArtifactResolverException ex) { + } else { + final String msg = String.format("Unable to resolve '%s' in project %s", + dependencyNode.getArtifact().getId(), project.getName()); + getLog().debug(msg); if (exCol == null) { exCol = new ExceptionCollection(); } - exCol.addException(ex); } } @@ -871,6 +894,66 @@ private ExceptionCollection collectDependencies(Engine engine, MavenProject proj return exCol; } + /** + * Checks if the current artifact is actually in the reactor projects that + * have not yet been built. If true a virtual dependency is created based on + * the evidence in the project. + * + * @param engine a reference to the engine being used to scan + * @param artifact the artifact being analyzed in the mojo + * @return true if the artifact is in the reactor; otherwise + * false + */ + private boolean addReactorDependency(Engine engine, Artifact artifact) { + for (MavenProject project : reactorProjects) { + if (project.getArtifactId().equals(artifact.getArtifactId()) + && project.getGroupId().equals(artifact.getGroupId()) + && project.getVersion().equals(artifact.getVersion())) { + + final String displayName = String.format("%s:%s:%s", + project.getGroupId(), project.getArtifactId(), project.getVersion()); + getLog().info(String.format("Unable to resolve %s as it has not been built yet - creating a virtual dependency instead.", displayName)); + File pom = new File(project.getBasedir(), "pom.xml"); + Dependency d; + if (pom.isFile()) { + d = new Dependency(pom, true); + } else { + d = new Dependency(true); + } + d.setDisplayFileName(displayName); + + d.addEvidence(EvidenceType.PRODUCT, "project", "artifactid", project.getArtifactId(), Confidence.HIGHEST); + d.addEvidence(EvidenceType.VENDOR, "project", "artifactid", project.getArtifactId(), Confidence.LOW); + + d.addEvidence(EvidenceType.VENDOR, "project", "groupid", project.getGroupId(), Confidence.HIGHEST); + d.addEvidence(EvidenceType.PRODUCT, "project", "groupid", project.getGroupId(), Confidence.LOW); + d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM); + //TODO unify the setName/version and package path - they are equivelent ideas submitted by two seperate committers + d.setName(String.format("%s:%s", project.getGroupId(), project.getArtifactId())); + d.setVersion(project.getVersion()); + d.setPackagePath(displayName); + JarAnalyzer.addDescription(d, project.getDescription(), "project", "description"); + for (License l : project.getLicenses()) { + StringBuilder license = new StringBuilder(); + if (l.getName() != null) { + license.append(l.getName()); + } + if (l.getUrl() != null) { + license.append(" ").append(l.getUrl()); + } + if (d.getLicense() == null) { + d.setLicense(license.toString()); + } else if (!d.getLicense().contains(license)) { + d.setLicense(String.format("%s%n%s", d.getLicense(), license.toString())); + } + } + engine.addDependency(d); + return true; + } + } + return false; + } + /** * Determines if the groupId, artifactId, and version of the Maven * dependency and artifact match. @@ -975,7 +1058,8 @@ protected void runCheck() throws MojoExecutionException, MojoFailureException { * @param currentEx the primary exception collection * @param newEx the new exception collection to add * @return the combined exception collection - * @throws MojoExecutionException thrown if dependency-check is configured to fail on errors + * @throws MojoExecutionException thrown if dependency-check is configured + * to fail on errors */ private ExceptionCollection handleAnalysisExceptions(ExceptionCollection currentEx, ExceptionCollection newEx) throws MojoExecutionException { ExceptionCollection returnEx = currentEx; @@ -1453,4 +1537,5 @@ protected String getOutputDirectoryContextKey() { } // + } From c929220117eebc6e8dd0c995fc52fc7f4e467d42 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 30 Apr 2018 07:03:13 -0400 Subject: [PATCH 09/36] fix test case --- maven/src/it/740-aggregate/invoker.properties | 2 +- maven/src/it/740-aggregate/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/maven/src/it/740-aggregate/invoker.properties b/maven/src/it/740-aggregate/invoker.properties index fe31f576949..c32d994a16a 100644 --- a/maven/src/it/740-aggregate/invoker.properties +++ b/maven/src/it/740-aggregate/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals = install ${project.groupId}:${project.artifactId}:${project.version}:check -X -T 10 +invoker.goals = install -X diff --git a/maven/src/it/740-aggregate/pom.xml b/maven/src/it/740-aggregate/pom.xml index 73a17227886..98ae44a22ca 100644 --- a/maven/src/it/740-aggregate/pom.xml +++ b/maven/src/it/740-aggregate/pom.xml @@ -19,7 +19,7 @@ Copyright (c) 2018 Jeremy Long. All Rights Reserved. 4.0.0 org.owasp.test - threaded-parent + aggregate-parent 1.0.0-SNAPSHOT pom From 0b84b096d605ccfc2758bcb89ff20f65a96b1707 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Tue, 1 May 2018 06:55:08 -0400 Subject: [PATCH 10/36] removed debug logging --- maven/src/it/617-hierarchical-cross-deps/invoker.properties | 2 +- maven/src/it/618-aggregator-purge/invoker.properties | 4 ++-- maven/src/it/618-aggregator-update-only/invoker.properties | 2 +- maven/src/it/629-jackson-dataformat/invoker.properties | 2 +- maven/src/it/690-threadsafety/invoker.properties | 2 +- maven/src/it/710-pom-parse-error/invoker.properties | 2 +- maven/src/it/729-system-scope-resolved/invoker.properties | 2 +- maven/src/it/729-system-scope-skipped/invoker.properties | 2 +- .../730-multiple-suppression-files-configs/invoker.properties | 2 +- .../src/it/730-multiple-suppression-files/invoker.properties | 2 +- .../it/815-broken-suppression-aggregate/invoker.properties | 2 +- maven/src/it/846-site-plugin/invoker.properties | 2 +- maven/src/it/false-positives/invoker.properties | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/maven/src/it/617-hierarchical-cross-deps/invoker.properties b/maven/src/it/617-hierarchical-cross-deps/invoker.properties index 29b334c9e85..15acf9ef50c 100644 --- a/maven/src/it/617-hierarchical-cross-deps/invoker.properties +++ b/maven/src/it/617-hierarchical-cross-deps/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X +invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check diff --git a/maven/src/it/618-aggregator-purge/invoker.properties b/maven/src/it/618-aggregator-purge/invoker.properties index 46c174d8e25..0f5be4e07c1 100644 --- a/maven/src/it/618-aggregator-purge/invoker.properties +++ b/maven/src/it/618-aggregator-purge/invoker.properties @@ -16,5 +16,5 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals.1 = ${project.groupId}:${project.artifactId}:${project.version}:update-only -DdataDirectory=./data -Dcve.startyear=2017 -X -invoker.goals.2 = ${project.groupId}:${project.artifactId}:${project.version}:purge -DdataDirectory=./data -X +invoker.goals.1 = ${project.groupId}:${project.artifactId}:${project.version}:update-only -DdataDirectory=./data -Dcve.startyear=2018 +invoker.goals.2 = ${project.groupId}:${project.artifactId}:${project.version}:purge -DdataDirectory=./data diff --git a/maven/src/it/618-aggregator-update-only/invoker.properties b/maven/src/it/618-aggregator-update-only/invoker.properties index 1702ed25f31..b85d53e394d 100644 --- a/maven/src/it/618-aggregator-update-only/invoker.properties +++ b/maven/src/it/618-aggregator-update-only/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals = -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:update-only -X \ No newline at end of file +invoker.goals = -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:update-only \ No newline at end of file diff --git a/maven/src/it/629-jackson-dataformat/invoker.properties b/maven/src/it/629-jackson-dataformat/invoker.properties index 6633267fe92..c199d2648d6 100644 --- a/maven/src/it/629-jackson-dataformat/invoker.properties +++ b/maven/src/it/629-jackson-dataformat/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X -Dformat=ALL +invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -Dformat=ALL diff --git a/maven/src/it/690-threadsafety/invoker.properties b/maven/src/it/690-threadsafety/invoker.properties index 092fcbae279..141d562632b 100644 --- a/maven/src/it/690-threadsafety/invoker.properties +++ b/maven/src/it/690-threadsafety/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X -T 10 +invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -T 10 diff --git a/maven/src/it/710-pom-parse-error/invoker.properties b/maven/src/it/710-pom-parse-error/invoker.properties index 6633267fe92..c199d2648d6 100644 --- a/maven/src/it/710-pom-parse-error/invoker.properties +++ b/maven/src/it/710-pom-parse-error/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X -Dformat=ALL +invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -Dformat=ALL diff --git a/maven/src/it/729-system-scope-resolved/invoker.properties b/maven/src/it/729-system-scope-resolved/invoker.properties index 33d42889112..a074ced3027 100644 --- a/maven/src/it/729-system-scope-resolved/invoker.properties +++ b/maven/src/it/729-system-scope-resolved/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2017 Jeremy Long. All Rights Reserved. # -invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X -Dformat=JSON +invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -Dformat=JSON diff --git a/maven/src/it/729-system-scope-skipped/invoker.properties b/maven/src/it/729-system-scope-skipped/invoker.properties index 73d14647084..f65174ea36e 100644 --- a/maven/src/it/729-system-scope-skipped/invoker.properties +++ b/maven/src/it/729-system-scope-skipped/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -DskipSystemScope=true -Dformat=JSON -X +invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -DskipSystemScope=true -Dformat=JSON diff --git a/maven/src/it/730-multiple-suppression-files-configs/invoker.properties b/maven/src/it/730-multiple-suppression-files-configs/invoker.properties index 9ca2f4cf476..677897a3d8b 100644 --- a/maven/src/it/730-multiple-suppression-files-configs/invoker.properties +++ b/maven/src/it/730-multiple-suppression-files-configs/invoker.properties @@ -15,4 +15,4 @@ # # Copyright (c) 2017 The OWASP Foundation. All Rights Reserved. # -invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X +invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check diff --git a/maven/src/it/730-multiple-suppression-files/invoker.properties b/maven/src/it/730-multiple-suppression-files/invoker.properties index 9ca2f4cf476..677897a3d8b 100644 --- a/maven/src/it/730-multiple-suppression-files/invoker.properties +++ b/maven/src/it/730-multiple-suppression-files/invoker.properties @@ -15,4 +15,4 @@ # # Copyright (c) 2017 The OWASP Foundation. All Rights Reserved. # -invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X +invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check diff --git a/maven/src/it/815-broken-suppression-aggregate/invoker.properties b/maven/src/it/815-broken-suppression-aggregate/invoker.properties index 34b99036143..b47175cd8ac 100644 --- a/maven/src/it/815-broken-suppression-aggregate/invoker.properties +++ b/maven/src/it/815-broken-suppression-aggregate/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2017 The OWASP Foundation. All Rights Reserved. # invoker.buildResult = failure -invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:aggregate -X +invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:aggregate diff --git a/maven/src/it/846-site-plugin/invoker.properties b/maven/src/it/846-site-plugin/invoker.properties index 2010c6d669c..11bb9d2052b 100644 --- a/maven/src/it/846-site-plugin/invoker.properties +++ b/maven/src/it/846-site-plugin/invoker.properties @@ -15,4 +15,4 @@ # # Copyright (c) 2017 The OWASP Foundation. All Rights Reserved. # -invoker.goals = site -Danalyzer.central.enabled=false -Dodcversion=${project.version} -X +invoker.goals = site -Danalyzer.central.enabled=false -Dodcversion=${project.version} diff --git a/maven/src/it/false-positives/invoker.properties b/maven/src/it/false-positives/invoker.properties index 6633267fe92..c199d2648d6 100644 --- a/maven/src/it/false-positives/invoker.properties +++ b/maven/src/it/false-positives/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X -Dformat=ALL +invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -Dformat=ALL From ee3d1e83044cd8a887465fafcfddecc957c1a02f Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 30 Apr 2018 06:55:41 -0400 Subject: [PATCH 11/36] fix test case --- maven/src/it/740-aggregate/invoker.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maven/src/it/740-aggregate/invoker.properties b/maven/src/it/740-aggregate/invoker.properties index c32d994a16a..b5087cc941d 100644 --- a/maven/src/it/740-aggregate/invoker.properties +++ b/maven/src/it/740-aggregate/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals = install -X +invoker.goals = verify -X From 5f10ff7fb3bb8aecd60f19fd647a433a6f943b77 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 30 Apr 2018 06:56:10 -0400 Subject: [PATCH 12/36] update to create virtual dependencies --- .../dependency/Dependency.java | 11 + .../maven/BaseDependencyCheckMojo.java | 235 ++++++++++++------ 2 files changed, 171 insertions(+), 75 deletions(-) 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 f84514188a9..ca9ded7d437 100644 --- a/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java +++ b/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java @@ -192,6 +192,17 @@ public Dependency(File file, boolean isVirtual) { determineHashes(file); } + /** + * Constructs a new Dependency object. + * + * @param isVirtual specifies if the dependency is virtual indicating the + * file doesn't actually exist. + */ + public Dependency(boolean isVirtual) { + this(); + this.isVirtual = isVirtual; + } + /** * Returns the file name of the dependency. * diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 539d8f0315a..6bf76601785 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -29,6 +29,7 @@ import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.License; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -51,10 +52,12 @@ import org.apache.maven.shared.model.fileset.FileSet; import org.apache.maven.shared.model.fileset.util.FileSetManager; import org.owasp.dependencycheck.Engine; +import org.owasp.dependencycheck.analyzer.JarAnalyzer; import org.owasp.dependencycheck.data.nexus.MavenArtifact; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; import org.owasp.dependencycheck.dependency.Confidence; import org.owasp.dependencycheck.dependency.Dependency; +import org.owasp.dependencycheck.dependency.EvidenceType; import org.owasp.dependencycheck.dependency.Identifier; import org.owasp.dependencycheck.dependency.Vulnerability; import org.owasp.dependencycheck.exception.DependencyNotFoundException; @@ -152,9 +155,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @Parameter(defaultValue = "${project.build.directory}", required = true) private File outputDirectory; /** - * This is a reference to the >reporting< sections outputDirectory. - * This cannot be configured in the dependency-check mojo directly. - * This generally maps to "target/site". + * This is a reference to the >reporting< sections + * outputDirectory. This cannot be configured in the + * dependency-check mojo directly. This generally maps to "target/site". */ @Parameter(property = "project.reporting.outputDirectory", readonly = true) private File reportOutputDirectory; @@ -228,7 +231,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @Parameter(property = "connectionTimeout", defaultValue = "", required = false) private String connectionTimeout; /** - * Sets whether dependency-check should check if there is a new version available. + * Sets whether dependency-check should check if there is a new version + * available. */ @SuppressWarnings("CanBeFinal") @Parameter(property = "versionCheckEnabled", defaultValue = "true", required = false) @@ -719,11 +723,25 @@ protected File getCorrectOutputDirectory(MavenProject current) { * and scanning the dependencies */ protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) { + return scanArtifacts(project, engine, false); + } + + /** + * Scans the project's artifacts and adds them to the engine's dependency + * list. + * + * @param project the project to scan the dependencies of + * @param engine the engine to use to scan the dependencies + * @param aggregate whether the scan is part of an aggregate build + * @return a collection of exceptions that may have occurred while resolving + * and scanning the dependencies + */ + protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine, boolean aggregate) { try { final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); buildingRequest.setProject(project); final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null, reactorProjects); - return collectDependencies(engine, project, dn.getChildren(), buildingRequest); + return collectDependencies(engine, project, dn.getChildren(), buildingRequest, aggregate); } catch (DependencyGraphBuilderException ex) { final String msg = String.format("Unable to build dependency graph on project %s", project.getName()); getLog().debug(msg, ex); @@ -740,101 +758,106 @@ protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) * @param nodes the list of dependency nodes, generally obtained via the * DependencyGraphBuilder * @param buildingRequest the Maven project building request + * @param aggregate whether the scan is part of an aggregate build * @return a collection of exceptions that may have occurred while resolving * and scanning the dependencies */ private ExceptionCollection collectDependencies(Engine engine, MavenProject project, - List nodes, ProjectBuildingRequest buildingRequest) { + List nodes, ProjectBuildingRequest buildingRequest, boolean aggregate) { ExceptionCollection exCol = null; for (DependencyNode dependencyNode : nodes) { if (artifactScopeExcluded.passes(dependencyNode.getArtifact().getScope()) || artifactTypeExcluded.passes(dependencyNode.getArtifact().getType())) { continue; } - exCol = collectDependencies(engine, project, dependencyNode.getChildren(), buildingRequest); - try { - boolean isResolved = false; - File artifactFile = null; - String artifactId = null; - String groupId = null; - String version = null; - List availableVersions = null; - if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) { - for (org.apache.maven.model.Dependency d : project.getDependencies()) { - final Artifact a = dependencyNode.getArtifact(); - if (d.getSystemPath() != null && artifactsMatch(d, a)) { - - artifactFile = new File(d.getSystemPath()); - isResolved = artifactFile.isFile(); - groupId = a.getGroupId(); - artifactId = a.getArtifactId(); - version = a.getVersion(); - availableVersions = a.getAvailableVersions(); - break; - } + exCol = collectDependencies(engine, project, dependencyNode.getChildren(), buildingRequest, aggregate); + boolean isResolved = false; + File artifactFile = null; + String artifactId = null; + String groupId = null; + String version = null; + List availableVersions = null; + if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) { + for (org.apache.maven.model.Dependency d : project.getDependencies()) { + final Artifact a = dependencyNode.getArtifact(); + if (d.getSystemPath() != null && artifactsMatch(d, a)) { + + artifactFile = new File(d.getSystemPath()); + isResolved = artifactFile.isFile(); + groupId = a.getGroupId(); + artifactId = a.getArtifactId(); + version = a.getVersion(); + availableVersions = a.getAvailableVersions(); + break; + } + } + if (!isResolved) { + getLog().error("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString()); + if (exCol == null) { + exCol = new ExceptionCollection(); } - if (!isResolved) { - getLog().error("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString()); + exCol.addException(new DependencyNotFoundException("Unable to resolve system scoped dependency: " + + dependencyNode.toNodeString())); + } + } else { + final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact()); + final Artifact result; + try { + result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact(); + } catch (ArtifactResolverException ex) { + if (!aggregate || addReactorDependency(engine, dependencyNode.getArtifact())) { if (exCol == null) { exCol = new ExceptionCollection(); } - exCol.addException(new DependencyNotFoundException("Unable to resolve system scoped dependency: " - + dependencyNode.toNodeString())); } - } else { - final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact()); - final Artifact result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact(); - isResolved = result.isResolved(); - artifactFile = result.getFile(); - groupId = result.getGroupId(); - artifactId = result.getArtifactId(); - version = result.getVersion(); - availableVersions = result.getAvailableVersions(); + exCol.addException(ex); + continue; } - if (isResolved && artifactFile != null) { - final List deps = engine.scan(artifactFile.getAbsoluteFile(), - project.getName() + ":" + dependencyNode.getArtifact().getScope()); - if (deps != null) { - if (deps.size() == 1) { - final Dependency d = deps.get(0); - if (d != null) { - final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version); - d.addAsEvidence("pom", ma, Confidence.HIGHEST); - if (availableVersions != null) { - for (ArtifactVersion av : availableVersions) { - d.addAvailableVersion(av.toString()); - } + isResolved = result.isResolved(); + artifactFile = result.getFile(); + groupId = result.getGroupId(); + artifactId = result.getArtifactId(); + version = result.getVersion(); + availableVersions = result.getAvailableVersions(); + } + if (isResolved && artifactFile != null) { + final List deps = engine.scan(artifactFile.getAbsoluteFile(), + project.getName() + ":" + dependencyNode.getArtifact().getScope()); + if (deps != null) { + if (deps.size() == 1) { + final Dependency d = deps.get(0); + if (d != null) { + final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version); + d.addAsEvidence("pom", ma, Confidence.HIGHEST); + if (availableVersions != null) { + for (ArtifactVersion av : availableVersions) { + d.addAvailableVersion(av.toString()); } - getLog().debug(String.format("Adding project reference %s on dependency %s", - project.getName(), d.getDisplayFileName())); } - } else if (getLog().isDebugEnabled()) { - final String msg = String.format("More than 1 dependency was identified in first pass scan of '%s' in project %s", - dependencyNode.getArtifact().getId(), project.getName()); - getLog().debug(msg); + getLog().debug(String.format("Adding project reference %s on dependency %s", + project.getName(), d.getDisplayFileName())); } - } else if ("import".equals(dependencyNode.getArtifact().getScope())) { - final String msg = String.format("Skipping '%s:%s' in project %s as it uses an `import` scope", - dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); + } else if (getLog().isDebugEnabled()) { + final String msg = String.format("More than 1 dependency was identified in first pass scan of '%s' in project %s", + dependencyNode.getArtifact().getId(), project.getName()); getLog().debug(msg); - } else { - final String msg = String.format("No analyzer could be found for '%s:%s' in project %s", - dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); - getLog().warn(msg); } - } else { - final String msg = String.format("Unable to resolve '%s' in project %s", - dependencyNode.getArtifact().getId(), project.getName()); + } else if ("import".equals(dependencyNode.getArtifact().getScope())) { + final String msg = String.format("Skipping '%s:%s' in project %s as it uses an `import` scope", + dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); getLog().debug(msg); - if (exCol == null) { - exCol = new ExceptionCollection(); - } + } else { + final String msg = String.format("No analyzer could be found for '%s:%s' in project %s", + dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); + getLog().warn(msg); } - } catch (ArtifactResolverException ex) { + } else { + final String msg = String.format("Unable to resolve '%s' in project %s", + dependencyNode.getArtifact().getId(), project.getName()); + getLog().debug(msg); if (exCol == null) { exCol = new ExceptionCollection(); } - exCol.addException(ex); } } @@ -871,6 +894,66 @@ private ExceptionCollection collectDependencies(Engine engine, MavenProject proj return exCol; } + /** + * Checks if the current artifact is actually in the reactor projects that + * have not yet been built. If true a virtual dependency is created based on + * the evidence in the project. + * + * @param engine a reference to the engine being used to scan + * @param artifact the artifact being analyzed in the mojo + * @return true if the artifact is in the reactor; otherwise + * false + */ + private boolean addReactorDependency(Engine engine, Artifact artifact) { + for (MavenProject project : reactorProjects) { + if (project.getArtifactId().equals(artifact.getArtifactId()) + && project.getGroupId().equals(artifact.getGroupId()) + && project.getVersion().equals(artifact.getVersion())) { + + final String displayName = String.format("%s:%s:%s", + project.getGroupId(), project.getArtifactId(), project.getVersion()); + getLog().info(String.format("Unable to resolve %s as it has not been built yet - creating a virtual dependency instead.", displayName)); + File pom = new File(project.getBasedir(), "pom.xml"); + Dependency d; + if (pom.isFile()) { + d = new Dependency(pom, true); + } else { + d = new Dependency(true); + } + d.setDisplayFileName(displayName); + + d.addEvidence(EvidenceType.PRODUCT, "project", "artifactid", project.getArtifactId(), Confidence.HIGHEST); + d.addEvidence(EvidenceType.VENDOR, "project", "artifactid", project.getArtifactId(), Confidence.LOW); + + d.addEvidence(EvidenceType.VENDOR, "project", "groupid", project.getGroupId(), Confidence.HIGHEST); + d.addEvidence(EvidenceType.PRODUCT, "project", "groupid", project.getGroupId(), Confidence.LOW); + d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM); + //TODO unify the setName/version and package path - they are equivelent ideas submitted by two seperate committers + d.setName(String.format("%s:%s", project.getGroupId(), project.getArtifactId())); + d.setVersion(project.getVersion()); + d.setPackagePath(displayName); + JarAnalyzer.addDescription(d, project.getDescription(), "project", "description"); + for (License l : project.getLicenses()) { + StringBuilder license = new StringBuilder(); + if (l.getName() != null) { + license.append(l.getName()); + } + if (l.getUrl() != null) { + license.append(" ").append(l.getUrl()); + } + if (d.getLicense() == null) { + d.setLicense(license.toString()); + } else if (!d.getLicense().contains(license)) { + d.setLicense(String.format("%s%n%s", d.getLicense(), license.toString())); + } + } + engine.addDependency(d); + return true; + } + } + return false; + } + /** * Determines if the groupId, artifactId, and version of the Maven * dependency and artifact match. @@ -975,7 +1058,8 @@ protected void runCheck() throws MojoExecutionException, MojoFailureException { * @param currentEx the primary exception collection * @param newEx the new exception collection to add * @return the combined exception collection - * @throws MojoExecutionException thrown if dependency-check is configured to fail on errors + * @throws MojoExecutionException thrown if dependency-check is configured + * to fail on errors */ private ExceptionCollection handleAnalysisExceptions(ExceptionCollection currentEx, ExceptionCollection newEx) throws MojoExecutionException { ExceptionCollection returnEx = currentEx; @@ -1453,4 +1537,5 @@ protected String getOutputDirectoryContextKey() { } // + } From 916ff90bb58f5975945f17034640691cc6614ea5 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Tue, 1 May 2018 07:09:31 -0400 Subject: [PATCH 13/36] add logging output for 740 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 3a09c560e72..6eda4cbb437 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,6 +49,7 @@ after_success: fi; after_failure: + - cat /home/travis/build/jeremylong/DependencyCheck/maven/target/it/740-aggregate/build.log - cat /home/travis/build/jeremylong/DependencyCheck/maven/target/it/617-hierarchical-cross-deps/build.log - cat /home/travis/build/jeremylong/DependencyCheck/maven/target/it/618-aggregator-purge/build.log - cat /home/travis/build/jeremylong/DependencyCheck/maven/target/it/618-aggregator-update-only/build.log From 894fc8d0ca553d5e1a8aaa704a4129542498b902 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 2 May 2018 05:50:05 -0400 Subject: [PATCH 14/36] fix test case --- maven/src/it/740-aggregate/first/pom.xml | 2 +- maven/src/it/740-aggregate/second/pom.xml | 2 +- maven/src/it/740-aggregate/third/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/maven/src/it/740-aggregate/first/pom.xml b/maven/src/it/740-aggregate/first/pom.xml index ec008957d09..37e6e8b18ee 100644 --- a/maven/src/it/740-aggregate/first/pom.xml +++ b/maven/src/it/740-aggregate/first/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. 4.0.0 org.owasp.test - threaded-parent + aggregate-parent 1.0.0-SNAPSHOT first diff --git a/maven/src/it/740-aggregate/second/pom.xml b/maven/src/it/740-aggregate/second/pom.xml index 710eace2e07..e24fead1e38 100644 --- a/maven/src/it/740-aggregate/second/pom.xml +++ b/maven/src/it/740-aggregate/second/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. 4.0.0 org.owasp.test - threaded-parent + aggregate-parent 1.0.0-SNAPSHOT second diff --git a/maven/src/it/740-aggregate/third/pom.xml b/maven/src/it/740-aggregate/third/pom.xml index a36ca6f3fb9..3bfa07e7337 100644 --- a/maven/src/it/740-aggregate/third/pom.xml +++ b/maven/src/it/740-aggregate/third/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. 4.0.0 org.owasp.test - threaded-parent + aggregate-parent 1.0.0-SNAPSHOT third From 9498f2c17f56a39bc274749393299abf1437202e Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 2 May 2018 05:50:36 -0400 Subject: [PATCH 15/36] update test case --- maven/src/it/740-aggregate/invoker.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maven/src/it/740-aggregate/invoker.properties b/maven/src/it/740-aggregate/invoker.properties index c32d994a16a..b5087cc941d 100644 --- a/maven/src/it/740-aggregate/invoker.properties +++ b/maven/src/it/740-aggregate/invoker.properties @@ -16,4 +16,4 @@ # Copyright (c) 2014 Jeremy Long. All Rights Reserved. # -invoker.goals = install -X +invoker.goals = verify -X From 86b0ce360a0a4f6425a7daa71904dbd261c075fb Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 30 Apr 2018 06:56:10 -0400 Subject: [PATCH 16/36] update to create virtual dependencies --- .../dependency/Dependency.java | 11 + .../maven/BaseDependencyCheckMojo.java | 235 ++++++++++++------ 2 files changed, 171 insertions(+), 75 deletions(-) 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 f84514188a9..ca9ded7d437 100644 --- a/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java +++ b/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java @@ -192,6 +192,17 @@ public Dependency(File file, boolean isVirtual) { determineHashes(file); } + /** + * Constructs a new Dependency object. + * + * @param isVirtual specifies if the dependency is virtual indicating the + * file doesn't actually exist. + */ + public Dependency(boolean isVirtual) { + this(); + this.isVirtual = isVirtual; + } + /** * Returns the file name of the dependency. * diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 539d8f0315a..6bf76601785 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -29,6 +29,7 @@ import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.License; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -51,10 +52,12 @@ import org.apache.maven.shared.model.fileset.FileSet; import org.apache.maven.shared.model.fileset.util.FileSetManager; import org.owasp.dependencycheck.Engine; +import org.owasp.dependencycheck.analyzer.JarAnalyzer; import org.owasp.dependencycheck.data.nexus.MavenArtifact; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; import org.owasp.dependencycheck.dependency.Confidence; import org.owasp.dependencycheck.dependency.Dependency; +import org.owasp.dependencycheck.dependency.EvidenceType; import org.owasp.dependencycheck.dependency.Identifier; import org.owasp.dependencycheck.dependency.Vulnerability; import org.owasp.dependencycheck.exception.DependencyNotFoundException; @@ -152,9 +155,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @Parameter(defaultValue = "${project.build.directory}", required = true) private File outputDirectory; /** - * This is a reference to the >reporting< sections outputDirectory. - * This cannot be configured in the dependency-check mojo directly. - * This generally maps to "target/site". + * This is a reference to the >reporting< sections + * outputDirectory. This cannot be configured in the + * dependency-check mojo directly. This generally maps to "target/site". */ @Parameter(property = "project.reporting.outputDirectory", readonly = true) private File reportOutputDirectory; @@ -228,7 +231,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @Parameter(property = "connectionTimeout", defaultValue = "", required = false) private String connectionTimeout; /** - * Sets whether dependency-check should check if there is a new version available. + * Sets whether dependency-check should check if there is a new version + * available. */ @SuppressWarnings("CanBeFinal") @Parameter(property = "versionCheckEnabled", defaultValue = "true", required = false) @@ -719,11 +723,25 @@ protected File getCorrectOutputDirectory(MavenProject current) { * and scanning the dependencies */ protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) { + return scanArtifacts(project, engine, false); + } + + /** + * Scans the project's artifacts and adds them to the engine's dependency + * list. + * + * @param project the project to scan the dependencies of + * @param engine the engine to use to scan the dependencies + * @param aggregate whether the scan is part of an aggregate build + * @return a collection of exceptions that may have occurred while resolving + * and scanning the dependencies + */ + protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine, boolean aggregate) { try { final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); buildingRequest.setProject(project); final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null, reactorProjects); - return collectDependencies(engine, project, dn.getChildren(), buildingRequest); + return collectDependencies(engine, project, dn.getChildren(), buildingRequest, aggregate); } catch (DependencyGraphBuilderException ex) { final String msg = String.format("Unable to build dependency graph on project %s", project.getName()); getLog().debug(msg, ex); @@ -740,101 +758,106 @@ protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) * @param nodes the list of dependency nodes, generally obtained via the * DependencyGraphBuilder * @param buildingRequest the Maven project building request + * @param aggregate whether the scan is part of an aggregate build * @return a collection of exceptions that may have occurred while resolving * and scanning the dependencies */ private ExceptionCollection collectDependencies(Engine engine, MavenProject project, - List nodes, ProjectBuildingRequest buildingRequest) { + List nodes, ProjectBuildingRequest buildingRequest, boolean aggregate) { ExceptionCollection exCol = null; for (DependencyNode dependencyNode : nodes) { if (artifactScopeExcluded.passes(dependencyNode.getArtifact().getScope()) || artifactTypeExcluded.passes(dependencyNode.getArtifact().getType())) { continue; } - exCol = collectDependencies(engine, project, dependencyNode.getChildren(), buildingRequest); - try { - boolean isResolved = false; - File artifactFile = null; - String artifactId = null; - String groupId = null; - String version = null; - List availableVersions = null; - if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) { - for (org.apache.maven.model.Dependency d : project.getDependencies()) { - final Artifact a = dependencyNode.getArtifact(); - if (d.getSystemPath() != null && artifactsMatch(d, a)) { - - artifactFile = new File(d.getSystemPath()); - isResolved = artifactFile.isFile(); - groupId = a.getGroupId(); - artifactId = a.getArtifactId(); - version = a.getVersion(); - availableVersions = a.getAvailableVersions(); - break; - } + exCol = collectDependencies(engine, project, dependencyNode.getChildren(), buildingRequest, aggregate); + boolean isResolved = false; + File artifactFile = null; + String artifactId = null; + String groupId = null; + String version = null; + List availableVersions = null; + if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) { + for (org.apache.maven.model.Dependency d : project.getDependencies()) { + final Artifact a = dependencyNode.getArtifact(); + if (d.getSystemPath() != null && artifactsMatch(d, a)) { + + artifactFile = new File(d.getSystemPath()); + isResolved = artifactFile.isFile(); + groupId = a.getGroupId(); + artifactId = a.getArtifactId(); + version = a.getVersion(); + availableVersions = a.getAvailableVersions(); + break; + } + } + if (!isResolved) { + getLog().error("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString()); + if (exCol == null) { + exCol = new ExceptionCollection(); } - if (!isResolved) { - getLog().error("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString()); + exCol.addException(new DependencyNotFoundException("Unable to resolve system scoped dependency: " + + dependencyNode.toNodeString())); + } + } else { + final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact()); + final Artifact result; + try { + result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact(); + } catch (ArtifactResolverException ex) { + if (!aggregate || addReactorDependency(engine, dependencyNode.getArtifact())) { if (exCol == null) { exCol = new ExceptionCollection(); } - exCol.addException(new DependencyNotFoundException("Unable to resolve system scoped dependency: " - + dependencyNode.toNodeString())); } - } else { - final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact()); - final Artifact result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact(); - isResolved = result.isResolved(); - artifactFile = result.getFile(); - groupId = result.getGroupId(); - artifactId = result.getArtifactId(); - version = result.getVersion(); - availableVersions = result.getAvailableVersions(); + exCol.addException(ex); + continue; } - if (isResolved && artifactFile != null) { - final List deps = engine.scan(artifactFile.getAbsoluteFile(), - project.getName() + ":" + dependencyNode.getArtifact().getScope()); - if (deps != null) { - if (deps.size() == 1) { - final Dependency d = deps.get(0); - if (d != null) { - final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version); - d.addAsEvidence("pom", ma, Confidence.HIGHEST); - if (availableVersions != null) { - for (ArtifactVersion av : availableVersions) { - d.addAvailableVersion(av.toString()); - } + isResolved = result.isResolved(); + artifactFile = result.getFile(); + groupId = result.getGroupId(); + artifactId = result.getArtifactId(); + version = result.getVersion(); + availableVersions = result.getAvailableVersions(); + } + if (isResolved && artifactFile != null) { + final List deps = engine.scan(artifactFile.getAbsoluteFile(), + project.getName() + ":" + dependencyNode.getArtifact().getScope()); + if (deps != null) { + if (deps.size() == 1) { + final Dependency d = deps.get(0); + if (d != null) { + final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version); + d.addAsEvidence("pom", ma, Confidence.HIGHEST); + if (availableVersions != null) { + for (ArtifactVersion av : availableVersions) { + d.addAvailableVersion(av.toString()); } - getLog().debug(String.format("Adding project reference %s on dependency %s", - project.getName(), d.getDisplayFileName())); } - } else if (getLog().isDebugEnabled()) { - final String msg = String.format("More than 1 dependency was identified in first pass scan of '%s' in project %s", - dependencyNode.getArtifact().getId(), project.getName()); - getLog().debug(msg); + getLog().debug(String.format("Adding project reference %s on dependency %s", + project.getName(), d.getDisplayFileName())); } - } else if ("import".equals(dependencyNode.getArtifact().getScope())) { - final String msg = String.format("Skipping '%s:%s' in project %s as it uses an `import` scope", - dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); + } else if (getLog().isDebugEnabled()) { + final String msg = String.format("More than 1 dependency was identified in first pass scan of '%s' in project %s", + dependencyNode.getArtifact().getId(), project.getName()); getLog().debug(msg); - } else { - final String msg = String.format("No analyzer could be found for '%s:%s' in project %s", - dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); - getLog().warn(msg); } - } else { - final String msg = String.format("Unable to resolve '%s' in project %s", - dependencyNode.getArtifact().getId(), project.getName()); + } else if ("import".equals(dependencyNode.getArtifact().getScope())) { + final String msg = String.format("Skipping '%s:%s' in project %s as it uses an `import` scope", + dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); getLog().debug(msg); - if (exCol == null) { - exCol = new ExceptionCollection(); - } + } else { + final String msg = String.format("No analyzer could be found for '%s:%s' in project %s", + dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName()); + getLog().warn(msg); } - } catch (ArtifactResolverException ex) { + } else { + final String msg = String.format("Unable to resolve '%s' in project %s", + dependencyNode.getArtifact().getId(), project.getName()); + getLog().debug(msg); if (exCol == null) { exCol = new ExceptionCollection(); } - exCol.addException(ex); } } @@ -871,6 +894,66 @@ private ExceptionCollection collectDependencies(Engine engine, MavenProject proj return exCol; } + /** + * Checks if the current artifact is actually in the reactor projects that + * have not yet been built. If true a virtual dependency is created based on + * the evidence in the project. + * + * @param engine a reference to the engine being used to scan + * @param artifact the artifact being analyzed in the mojo + * @return true if the artifact is in the reactor; otherwise + * false + */ + private boolean addReactorDependency(Engine engine, Artifact artifact) { + for (MavenProject project : reactorProjects) { + if (project.getArtifactId().equals(artifact.getArtifactId()) + && project.getGroupId().equals(artifact.getGroupId()) + && project.getVersion().equals(artifact.getVersion())) { + + final String displayName = String.format("%s:%s:%s", + project.getGroupId(), project.getArtifactId(), project.getVersion()); + getLog().info(String.format("Unable to resolve %s as it has not been built yet - creating a virtual dependency instead.", displayName)); + File pom = new File(project.getBasedir(), "pom.xml"); + Dependency d; + if (pom.isFile()) { + d = new Dependency(pom, true); + } else { + d = new Dependency(true); + } + d.setDisplayFileName(displayName); + + d.addEvidence(EvidenceType.PRODUCT, "project", "artifactid", project.getArtifactId(), Confidence.HIGHEST); + d.addEvidence(EvidenceType.VENDOR, "project", "artifactid", project.getArtifactId(), Confidence.LOW); + + d.addEvidence(EvidenceType.VENDOR, "project", "groupid", project.getGroupId(), Confidence.HIGHEST); + d.addEvidence(EvidenceType.PRODUCT, "project", "groupid", project.getGroupId(), Confidence.LOW); + d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM); + //TODO unify the setName/version and package path - they are equivelent ideas submitted by two seperate committers + d.setName(String.format("%s:%s", project.getGroupId(), project.getArtifactId())); + d.setVersion(project.getVersion()); + d.setPackagePath(displayName); + JarAnalyzer.addDescription(d, project.getDescription(), "project", "description"); + for (License l : project.getLicenses()) { + StringBuilder license = new StringBuilder(); + if (l.getName() != null) { + license.append(l.getName()); + } + if (l.getUrl() != null) { + license.append(" ").append(l.getUrl()); + } + if (d.getLicense() == null) { + d.setLicense(license.toString()); + } else if (!d.getLicense().contains(license)) { + d.setLicense(String.format("%s%n%s", d.getLicense(), license.toString())); + } + } + engine.addDependency(d); + return true; + } + } + return false; + } + /** * Determines if the groupId, artifactId, and version of the Maven * dependency and artifact match. @@ -975,7 +1058,8 @@ protected void runCheck() throws MojoExecutionException, MojoFailureException { * @param currentEx the primary exception collection * @param newEx the new exception collection to add * @return the combined exception collection - * @throws MojoExecutionException thrown if dependency-check is configured to fail on errors + * @throws MojoExecutionException thrown if dependency-check is configured + * to fail on errors */ private ExceptionCollection handleAnalysisExceptions(ExceptionCollection currentEx, ExceptionCollection newEx) throws MojoExecutionException { ExceptionCollection returnEx = currentEx; @@ -1453,4 +1537,5 @@ protected String getOutputDirectoryContextKey() { } // + } From 758ee32367b5d7bc823ec1bab0f780f112718ade Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 2 May 2018 06:15:02 -0400 Subject: [PATCH 17/36] added logging --- .../maven/BaseDependencyCheckMojo.java | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 6bf76601785..815f145f4d0 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -905,15 +905,20 @@ private ExceptionCollection collectDependencies(Engine engine, MavenProject proj * false */ private boolean addReactorDependency(Engine engine, Artifact artifact) { - for (MavenProject project : reactorProjects) { - if (project.getArtifactId().equals(artifact.getArtifactId()) - && project.getGroupId().equals(artifact.getGroupId()) - && project.getVersion().equals(artifact.getVersion())) { + for (MavenProject prj : reactorProjects) { + + getLog().debug(String.format("Comparing %s:%s%s to %s:%s:%s", + artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), + prj.getGroupId(), prj.getArtifactId(), prj.getVersion())); + + if (prj.getArtifactId().equals(artifact.getArtifactId()) + && prj.getGroupId().equals(artifact.getGroupId()) + && prj.getVersion().equals(artifact.getVersion())) { final String displayName = String.format("%s:%s:%s", - project.getGroupId(), project.getArtifactId(), project.getVersion()); + prj.getGroupId(), prj.getArtifactId(), prj.getVersion()); getLog().info(String.format("Unable to resolve %s as it has not been built yet - creating a virtual dependency instead.", displayName)); - File pom = new File(project.getBasedir(), "pom.xml"); + File pom = new File(prj.getBasedir(), "pom.xml"); Dependency d; if (pom.isFile()) { d = new Dependency(pom, true); @@ -922,18 +927,18 @@ private boolean addReactorDependency(Engine engine, Artifact artifact) { } d.setDisplayFileName(displayName); - d.addEvidence(EvidenceType.PRODUCT, "project", "artifactid", project.getArtifactId(), Confidence.HIGHEST); - d.addEvidence(EvidenceType.VENDOR, "project", "artifactid", project.getArtifactId(), Confidence.LOW); + d.addEvidence(EvidenceType.PRODUCT, "project", "artifactid", prj.getArtifactId(), Confidence.HIGHEST); + d.addEvidence(EvidenceType.VENDOR, "project", "artifactid", prj.getArtifactId(), Confidence.LOW); - d.addEvidence(EvidenceType.VENDOR, "project", "groupid", project.getGroupId(), Confidence.HIGHEST); - d.addEvidence(EvidenceType.PRODUCT, "project", "groupid", project.getGroupId(), Confidence.LOW); + d.addEvidence(EvidenceType.VENDOR, "project", "groupid", prj.getGroupId(), Confidence.HIGHEST); + d.addEvidence(EvidenceType.PRODUCT, "project", "groupid", prj.getGroupId(), Confidence.LOW); d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM); //TODO unify the setName/version and package path - they are equivelent ideas submitted by two seperate committers - d.setName(String.format("%s:%s", project.getGroupId(), project.getArtifactId())); - d.setVersion(project.getVersion()); + d.setName(String.format("%s:%s", prj.getGroupId(), prj.getArtifactId())); + d.setVersion(prj.getVersion()); d.setPackagePath(displayName); - JarAnalyzer.addDescription(d, project.getDescription(), "project", "description"); - for (License l : project.getLicenses()) { + JarAnalyzer.addDescription(d, prj.getDescription(), "project", "description"); + for (License l : prj.getLicenses()) { StringBuilder license = new StringBuilder(); if (l.getName() != null) { license.append(l.getName()); @@ -953,7 +958,7 @@ private boolean addReactorDependency(Engine engine, Artifact artifact) { } return false; } - + /** * Determines if the groupId, artifactId, and version of the Maven * dependency and artifact match. @@ -1537,5 +1542,4 @@ protected String getOutputDirectoryContextKey() { } // - } From ccae164b4a4948d912ab386cc719b1dce3eb838d Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 2 May 2018 06:30:23 -0400 Subject: [PATCH 18/36] added logging --- .../owasp/dependencycheck/maven/BaseDependencyCheckMojo.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 815f145f4d0..68344549b3f 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -905,6 +905,11 @@ private ExceptionCollection collectDependencies(Engine engine, MavenProject proj * false */ private boolean addReactorDependency(Engine engine, Artifact artifact) { + + getLog().debug(String.format("Checking the reactor projects (%d) for %s:%s:%s", + reactorProjects.size(), + artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion())); + for (MavenProject prj : reactorProjects) { getLog().debug(String.format("Comparing %s:%s%s to %s:%s:%s", From d4b36fadeda7f1c5329a8b61581d67cde6680817 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 2 May 2018 06:46:50 -0400 Subject: [PATCH 19/36] added logging --- .../org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java | 1 + 1 file changed, 1 insertion(+) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 68344549b3f..8b31cfb3d62 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -805,6 +805,7 @@ private ExceptionCollection collectDependencies(Engine engine, MavenProject proj try { result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact(); } catch (ArtifactResolverException ex) { + getLog().debug(String.format("Aggregate : %s", aggregate)); if (!aggregate || addReactorDependency(engine, dependencyNode.getArtifact())) { if (exCol == null) { exCol = new ExceptionCollection(); From c9929d0d3441af4027ca8e36a6914e1098d32ad3 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 2 May 2018 06:54:04 -0400 Subject: [PATCH 20/36] fixed bug - not calling scan artifacts indicate the scan is an aggregate --- .../java/org/owasp/dependencycheck/maven/AggregateMojo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java index 35f2f9fe5db..572e4dc0b5a 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java @@ -64,9 +64,9 @@ public class AggregateMojo extends BaseDependencyCheckMojo { */ @Override protected ExceptionCollection scanDependencies(final Engine engine) throws MojoExecutionException { - ExceptionCollection exCol = scanArtifacts(getProject(), engine); + ExceptionCollection exCol = scanArtifacts(getProject(), engine, true); for (MavenProject childProject : getDescendants(this.getProject())) { - final ExceptionCollection ex = scanArtifacts(childProject, engine); + final ExceptionCollection ex = scanArtifacts(childProject, engine, true); if (ex != null) { if (exCol == null) { exCol = ex; From 46cac41304bf15413863e9dbaa43f712dcda4c50 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 2 May 2018 06:54:18 -0400 Subject: [PATCH 21/36] updated exception handling --- .../dependencycheck/maven/BaseDependencyCheckMojo.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 8b31cfb3d62..945e0a86c6e 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -806,12 +806,16 @@ private ExceptionCollection collectDependencies(Engine engine, MavenProject proj result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact(); } catch (ArtifactResolverException ex) { getLog().debug(String.format("Aggregate : %s", aggregate)); + boolean addException = true; if (!aggregate || addReactorDependency(engine, dependencyNode.getArtifact())) { + addException = false; + } + if (addException) { if (exCol == null) { exCol = new ExceptionCollection(); } + exCol.addException(ex); } - exCol.addException(ex); continue; } isResolved = result.isResolved(); From b4fa608efd611a3c29cb05832953b106f4657f61 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 2 May 2018 07:12:38 -0400 Subject: [PATCH 22/36] fix npe --- .../owasp/dependencycheck/maven/BaseDependencyCheckMojo.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 945e0a86c6e..9c64ee4d4ff 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -947,7 +947,9 @@ private boolean addReactorDependency(Engine engine, Artifact artifact) { d.setName(String.format("%s:%s", prj.getGroupId(), prj.getArtifactId())); d.setVersion(prj.getVersion()); d.setPackagePath(displayName); - JarAnalyzer.addDescription(d, prj.getDescription(), "project", "description"); + if (prj.getDescription() != null) { + JarAnalyzer.addDescription(d, prj.getDescription(), "project", "description"); + } for (License l : prj.getLicenses()) { StringBuilder license = new StringBuilder(); if (l.getName() != null) { From fd072540752527128f1b3b63da148a16feff3db9 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Thu, 3 May 2018 05:59:21 -0400 Subject: [PATCH 23/36] manually apply #1260 as rebase is failing --- maven/src/it/740-aggregate/first/pom.xml | 2 +- maven/src/it/740-aggregate/pom.xml | 2 +- maven/src/it/740-aggregate/second/pom.xml | 2 +- maven/src/it/740-aggregate/third/fourth/pom.xml | 2 +- maven/src/it/740-aggregate/third/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/maven/src/it/740-aggregate/first/pom.xml b/maven/src/it/740-aggregate/first/pom.xml index 37e6e8b18ee..5361ae245ea 100644 --- a/maven/src/it/740-aggregate/first/pom.xml +++ b/maven/src/it/740-aggregate/first/pom.xml @@ -19,7 +19,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. 4.0.0 - org.owasp.test + org.owasp.test.aggregate aggregate-parent 1.0.0-SNAPSHOT diff --git a/maven/src/it/740-aggregate/pom.xml b/maven/src/it/740-aggregate/pom.xml index 98ae44a22ca..7c8e905146c 100644 --- a/maven/src/it/740-aggregate/pom.xml +++ b/maven/src/it/740-aggregate/pom.xml @@ -18,7 +18,7 @@ Copyright (c) 2018 Jeremy Long. All Rights Reserved. --> 4.0.0 - org.owasp.test + org.owasp.test.aggregate aggregate-parent 1.0.0-SNAPSHOT pom diff --git a/maven/src/it/740-aggregate/second/pom.xml b/maven/src/it/740-aggregate/second/pom.xml index e24fead1e38..1682b6bac38 100644 --- a/maven/src/it/740-aggregate/second/pom.xml +++ b/maven/src/it/740-aggregate/second/pom.xml @@ -19,7 +19,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. 4.0.0 - org.owasp.test + org.owasp.test.aggregate aggregate-parent 1.0.0-SNAPSHOT diff --git a/maven/src/it/740-aggregate/third/fourth/pom.xml b/maven/src/it/740-aggregate/third/fourth/pom.xml index 43581af39fb..4e138994df9 100644 --- a/maven/src/it/740-aggregate/third/fourth/pom.xml +++ b/maven/src/it/740-aggregate/third/fourth/pom.xml @@ -19,7 +19,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. 4.0.0 - org.owasp.test + org.owasp.test.aggregate third 1.0.0-SNAPSHOT diff --git a/maven/src/it/740-aggregate/third/pom.xml b/maven/src/it/740-aggregate/third/pom.xml index 3bfa07e7337..19cc22a5d1e 100644 --- a/maven/src/it/740-aggregate/third/pom.xml +++ b/maven/src/it/740-aggregate/third/pom.xml @@ -19,7 +19,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. 4.0.0 - org.owasp.test + org.owasp.test.aggregate aggregate-parent 1.0.0-SNAPSHOT From df9a3c9819d1bee5bb366c7ec7ac2eab203555e6 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Thu, 3 May 2018 06:34:52 -0400 Subject: [PATCH 24/36] fix postbuild validation of test --- maven/src/it/740-aggregate/pom.xml | 1 + maven/src/it/740-aggregate/postbuild.groovy | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/maven/src/it/740-aggregate/pom.xml b/maven/src/it/740-aggregate/pom.xml index 7c8e905146c..39770600d1f 100644 --- a/maven/src/it/740-aggregate/pom.xml +++ b/maven/src/it/740-aggregate/pom.xml @@ -35,6 +35,7 @@ Copyright (c) 2018 Jeremy Long. All Rights Reserved. ${odc.version} false + XML false diff --git a/maven/src/it/740-aggregate/postbuild.groovy b/maven/src/it/740-aggregate/postbuild.groovy index 8c1b639faac..e4219da8035 100644 --- a/maven/src/it/740-aggregate/postbuild.groovy +++ b/maven/src/it/740-aggregate/postbuild.groovy @@ -19,11 +19,16 @@ import java.nio.charset.Charset; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; - -String log = FileUtils.readFileToString(new File(basedir, "build.log"), Charset.defaultCharset().name()); -int count = StringUtils.countMatches(log, "Download Started for NVD CVE - 2002"); -if (count > 1){ - System.out.println(String.format("NVD CVE was downloaded %s times, should be 0 or 1 times", count)); + +String log = FileUtils.readFileToString(new File(basedir, "target/dependency-check-report.xml"), Charset.defaultCharset().name()); +int count = StringUtils.countMatches(log, "fourth-1.0.0-SNAPSHOT"); +if (count == 0) { + System.out.println(String.format("fourth-1.0.0-SNAPSHOT was not identified")); + return false; +} +count = StringUtils.countMatches(log, "org.apache.james:apache-mime4j-core:0.7.2"); +if (count == 0) { + System.out.println(String.format("org.apache.james:apache-mime4j-core:0.7.2 was not identified and is a dependency of fourth-1.0.0-SNAPSHOT")); return false; } return true; \ No newline at end of file From 7707c3063c7ce7836cdba524e1b54b10b0c78db6 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Thu, 3 May 2018 06:50:59 -0400 Subject: [PATCH 25/36] fix test case --- maven/src/it/740-aggregate/second/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maven/src/it/740-aggregate/second/pom.xml b/maven/src/it/740-aggregate/second/pom.xml index 1682b6bac38..c9b9caf5e05 100644 --- a/maven/src/it/740-aggregate/second/pom.xml +++ b/maven/src/it/740-aggregate/second/pom.xml @@ -27,7 +27,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. jar - org.owasp.test + org.owasp.test.aggregate fourth 1.0.0-SNAPSHOT From d013ff67ea740ee6351da501b55f38cc1a224414 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Thu, 3 May 2018 07:10:11 -0400 Subject: [PATCH 26/36] updated logging to debug test in CI --- maven/src/it/740-aggregate/postbuild.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/maven/src/it/740-aggregate/postbuild.groovy b/maven/src/it/740-aggregate/postbuild.groovy index e4219da8035..ef94475d390 100644 --- a/maven/src/it/740-aggregate/postbuild.groovy +++ b/maven/src/it/740-aggregate/postbuild.groovy @@ -24,6 +24,7 @@ String log = FileUtils.readFileToString(new File(basedir, "target/dependency-che int count = StringUtils.countMatches(log, "fourth-1.0.0-SNAPSHOT"); if (count == 0) { System.out.println(String.format("fourth-1.0.0-SNAPSHOT was not identified")); + System.out.println(log); return false; } count = StringUtils.countMatches(log, "org.apache.james:apache-mime4j-core:0.7.2"); From f5fe4d218fc6ea598b05ff508c36a75c614a6ec2 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Thu, 3 May 2018 15:01:29 -0400 Subject: [PATCH 27/36] replace xml encoding that was accidentally remoed --- core/src/main/resources/templates/xmlReport.vsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/templates/xmlReport.vsl b/core/src/main/resources/templates/xmlReport.vsl index cf560147f87..85c85fabd5b 100644 --- a/core/src/main/resources/templates/xmlReport.vsl +++ b/core/src/main/resources/templates/xmlReport.vsl @@ -117,7 +117,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. #foreach($id in $dependency.getIdentifiers()) - ($id.value) + $enc.xml($id.value) #if( $id.url ) $enc.xml($id.url) #end From a4720a158a860039e13324d56fb64e27fbb247d7 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Thu, 3 May 2018 15:01:54 -0400 Subject: [PATCH 28/36] more debug code --- .../owasp/dependencycheck/maven/BaseDependencyCheckMojo.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 9c64ee4d4ff..542afb1ab0f 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -917,7 +917,7 @@ private boolean addReactorDependency(Engine engine, Artifact artifact) { for (MavenProject prj : reactorProjects) { - getLog().debug(String.format("Comparing %s:%s%s to %s:%s:%s", + getLog().debug(String.format("Comparing %s:%s:%s to %s:%s:%s", artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), prj.getGroupId(), prj.getArtifactId(), prj.getVersion())); @@ -964,7 +964,9 @@ private boolean addReactorDependency(Engine engine, Artifact artifact) { d.setLicense(String.format("%s%n%s", d.getLicense(), license.toString())); } } + System.out.println(String.format("Dependency Count Before: %d", engine.getDependencies().length)); engine.addDependency(d); + System.out.println(String.format("Dependency Count after: %d", engine.getDependencies().length)); return true; } } From b3154b93207dfce545a45d19c5a7fad6e6f4f404 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Thu, 3 May 2018 16:02:51 -0400 Subject: [PATCH 29/36] removed system.out statements --- .../owasp/dependencycheck/maven/BaseDependencyCheckMojo.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 542afb1ab0f..174c6d0cbc4 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -931,6 +931,7 @@ private boolean addReactorDependency(Engine engine, Artifact artifact) { File pom = new File(prj.getBasedir(), "pom.xml"); Dependency d; if (pom.isFile()) { + getLog().debug("Adding virtual dependency from pom.xml"); d = new Dependency(pom, true); } else { d = new Dependency(true); @@ -964,9 +965,7 @@ private boolean addReactorDependency(Engine engine, Artifact artifact) { d.setLicense(String.format("%s%n%s", d.getLicense(), license.toString())); } } - System.out.println(String.format("Dependency Count Before: %d", engine.getDependencies().length)); engine.addDependency(d); - System.out.println(String.format("Dependency Count after: %d", engine.getDependencies().length)); return true; } } From 55c022f220ff6a23881b032349b57c6e34135a71 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 5 May 2018 07:59:02 -0400 Subject: [PATCH 30/36] fix virtual dependencies and checksums --- core/src/main/resources/templates/htmlReport.vsl | 8 ++++---- core/src/main/resources/templates/jsonReport.vsl | 4 ++-- core/src/main/resources/templates/xmlReport.vsl | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/resources/templates/htmlReport.vsl b/core/src/main/resources/templates/htmlReport.vsl index 1766fc12418..e680654b423 100644 --- a/core/src/main/resources/templates/htmlReport.vsl +++ b/core/src/main/resources/templates/htmlReport.vsl @@ -731,8 +731,8 @@ Getting Help: File Path: $enc.html($dependency.FilePath)
- MD5: $enc.html($dependency.Md5sum)
- SHA1: $enc.html($dependency.Sha1sum) + MD5: #if($dependency.Md5sum)$enc.html($dependency.Md5sum)#end
+ SHA1: #if($dependency.Sha1sum)$enc.html($dependency.Sha1sum)#end #if ($dependency.projectReferences.size()==1)
Referenced In Project/Scope: #foreach($ref in $dependency.projectReferences) @@ -940,8 +940,8 @@ Getting Help:
File Path: $enc.html($dependency.FilePath)
- MD5: $enc.html($dependency.Md5sum)
- SHA1: $enc.html($dependency.Sha1sum) + MD5: #if($dependency.Md5sum)$enc.html($dependency.Md5sum)#end
+ SHA1: #if($dependency.Sha1sum)$enc.html($dependency.Sha1sum)#end

#set($cnt=$cnt+1) diff --git a/core/src/main/resources/templates/jsonReport.vsl b/core/src/main/resources/templates/jsonReport.vsl index d6425a7b9f8..62fefedf6d5 100644 --- a/core/src/main/resources/templates/jsonReport.vsl +++ b/core/src/main/resources/templates/jsonReport.vsl @@ -27,8 +27,8 @@ "isVirtual": #if($dependency.isVirtual)true#{else}false#end, "fileName": "$enc.json($dependency.DisplayFileName)", "filePath": "$enc.json($dependency.FilePath)", - "md5": "$enc.json($dependency.Md5sum)", - "sha1": "$enc.json($dependency.Sha1sum)" + "md5": "#if($dependency.Md5sum)$enc.json($dependency.Md5sum)#end", + "sha1": "#if($dependency.Sha1sum)$enc.json($dependency.Sha1sum)#end" #if($dependency.description),"description": "$enc.json($dependency.description)"#end #if($dependency.license),"license": "$enc.json($dependency.license)"#end #if ($dependency.projectReferences.size()>0) diff --git a/core/src/main/resources/templates/xmlReport.vsl b/core/src/main/resources/templates/xmlReport.vsl index 85c85fabd5b..ca69daa6056 100644 --- a/core/src/main/resources/templates/xmlReport.vsl +++ b/core/src/main/resources/templates/xmlReport.vsl @@ -48,8 +48,8 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. $enc.xml($dependency.DisplayFileName) $enc.xml($dependency.FilePath) - $enc.xml($dependency.Md5sum) - $enc.xml($dependency.Sha1sum) + #if($dependency.Md5sum)$enc.xml($dependency.Md5sum)#end + #if($dependency.Sha1sum)$enc.xml($dependency.Sha1sum)#end #if ($dependency.description) $enc.xml($dependency.description) #end From efd74a8aa2546de2326649f3df22963bbcb127d4 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 5 May 2018 08:00:01 -0400 Subject: [PATCH 31/36] additional checks to ensure correct dependency merging --- .../dependencycheck/analyzer/DependencyBundlingAnalyzer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 bc741deaee9..f2dd57f1d48 100644 --- a/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java +++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java @@ -405,7 +405,9 @@ private boolean hashesMatch(Dependency dependency1, Dependency dependency2) { */ private boolean isShadedJar(Dependency dependency, Dependency nextDependency) { if (dependency == null || dependency.getFileName() == null - || nextDependency == null || nextDependency.getFileName() == null) { + || nextDependency == null || nextDependency.getFileName() == null + || dependency.getIdentifiers().isEmpty() + || nextDependency.getIdentifiers().isEmpty()) { return false; } final String mainName = dependency.getFileName().toLowerCase(); From db6e0967e47b306ea976796eefebc891180b81a4 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 5 May 2018 08:00:37 -0400 Subject: [PATCH 32/36] fix postbuild checks --- maven/src/it/740-aggregate/postbuild.groovy | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/maven/src/it/740-aggregate/postbuild.groovy b/maven/src/it/740-aggregate/postbuild.groovy index ef94475d390..cc08e782177 100644 --- a/maven/src/it/740-aggregate/postbuild.groovy +++ b/maven/src/it/740-aggregate/postbuild.groovy @@ -20,14 +20,15 @@ import java.nio.charset.Charset; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; -String log = FileUtils.readFileToString(new File(basedir, "target/dependency-check-report.xml"), Charset.defaultCharset().name()); -int count = StringUtils.countMatches(log, "fourth-1.0.0-SNAPSHOT"); +String report = FileUtils.readFileToString(new File(basedir, "target/dependency-check-report.xml"), Charset.defaultCharset().name()); +int count = StringUtils.countMatches(report, "org.owasp.test.aggregate:fourth:1.0.0-SNAPSHOT"); if (count == 0) { System.out.println(String.format("fourth-1.0.0-SNAPSHOT was not identified")); - System.out.println(log); + System.out.println(report +); return false; } -count = StringUtils.countMatches(log, "org.apache.james:apache-mime4j-core:0.7.2"); +count = StringUtils.countMatches(report, "org.apache.james:apache-mime4j-core:0.7.2"); if (count == 0) { System.out.println(String.format("org.apache.james:apache-mime4j-core:0.7.2 was not identified and is a dependency of fourth-1.0.0-SNAPSHOT")); return false; From 949efa2d0612f50a2a53eca4854b2d431785ae1f Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 5 May 2018 08:00:57 -0400 Subject: [PATCH 33/36] added identifier to virtual dependency --- .../owasp/dependencycheck/maven/BaseDependencyCheckMojo.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 174c6d0cbc4..84d53b6dafe 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -944,6 +944,11 @@ private boolean addReactorDependency(Engine engine, Artifact artifact) { d.addEvidence(EvidenceType.VENDOR, "project", "groupid", prj.getGroupId(), Confidence.HIGHEST); d.addEvidence(EvidenceType.PRODUCT, "project", "groupid", prj.getGroupId(), Confidence.LOW); d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM); + Identifier id = new Identifier(); + id.setType("maven"); + id.setConfidence(Confidence.HIGHEST); + id.setValue(displayName); + d.addIdentifier(id); //TODO unify the setName/version and package path - they are equivelent ideas submitted by two seperate committers d.setName(String.format("%s:%s", prj.getGroupId(), prj.getArtifactId())); d.setVersion(prj.getVersion()); From 9d5dceb84ccfe33cd9ed15fbbdb8c2ad38e4b634 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 5 May 2018 12:44:49 -0400 Subject: [PATCH 34/36] remove test code --- maven/src/it/740-aggregate/postbuild.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/maven/src/it/740-aggregate/postbuild.groovy b/maven/src/it/740-aggregate/postbuild.groovy index cc08e782177..6c230aadbf0 100644 --- a/maven/src/it/740-aggregate/postbuild.groovy +++ b/maven/src/it/740-aggregate/postbuild.groovy @@ -24,7 +24,6 @@ String report = FileUtils.readFileToString(new File(basedir, "target/dependency- int count = StringUtils.countMatches(report, "org.owasp.test.aggregate:fourth:1.0.0-SNAPSHOT"); if (count == 0) { System.out.println(String.format("fourth-1.0.0-SNAPSHOT was not identified")); - System.out.println(report ); return false; } From 5e93043b9371e33763c828392956833ff3b3c4db Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 6 May 2018 06:56:04 -0400 Subject: [PATCH 35/36] added test case --- .../analyzer/DependencyBundlingAnalyzer.java | 2 +- .../DependencyBundlingAnalyzerTest.java | 83 +++++++++++++++++-- 2 files changed, 78 insertions(+), 7 deletions(-) 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 f2dd57f1d48..023ca82a59d 100644 --- a/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java +++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java @@ -403,7 +403,7 @@ private boolean hashesMatch(Dependency dependency1, Dependency dependency2) { * @return true if on of the dependencies is a pom.xml and the identifiers * between the two collections match; otherwise false */ - private boolean isShadedJar(Dependency dependency, Dependency nextDependency) { + protected boolean isShadedJar(Dependency dependency, Dependency nextDependency) { if (dependency == null || dependency.getFileName() == null || nextDependency == null || nextDependency.getFileName() == null || dependency.getIdentifiers().isEmpty() diff --git a/core/src/test/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerTest.java b/core/src/test/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerTest.java index ee6c5ddfef9..350e187b274 100644 --- a/core/src/test/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerTest.java +++ b/core/src/test/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerTest.java @@ -17,6 +17,7 @@ */ package org.owasp.dependencycheck.analyzer; +import java.io.File; import mockit.Mocked; import mockit.Verifications; import org.junit.Test; @@ -59,8 +60,8 @@ public void testGetAnalysisPhase() { } /** - * Test of analyze method, of class DependencyBundlingAnalyzer. - * The actually passed dependency does not matter. The analyzer only runs once. + * Test of analyze method, of class DependencyBundlingAnalyzer. The actually + * passed dependency does not matter. The analyzer only runs once. */ @Test public void testAnalyze() throws Exception { @@ -77,10 +78,12 @@ public void testAnalyze() throws Exception { instance.analyze(null, engineMock); assertTrue(instance.getAnalyzed()); - new Verifications() {{ - engineMock.getDependencies(); - times = 1; - }}; + new Verifications() { + { + engineMock.getDependencies(); + times = 1; + } + }; } /** @@ -140,4 +143,72 @@ public void testFirstPathIsShortest() { result = instance.firstPathIsShortest(left, right); assertEquals(expResult, result); } + + @Test + public void testIsShaded() { + DependencyBundlingAnalyzer instance = new DependencyBundlingAnalyzer(); + + Dependency left = null; + Dependency right = null; + + boolean expResult = false; + boolean result = instance.isShadedJar(left, right); + assertEquals(expResult, result); + + left = new Dependency(); + expResult = false; + result = instance.isShadedJar(left, right); + assertEquals(expResult, result); + + left = new Dependency(new File("/path/jar.jar"), true); + expResult = false; + result = instance.isShadedJar(left, right); + assertEquals(expResult, result); + + right = new Dependency(); + expResult = false; + result = instance.isShadedJar(left, right); + assertEquals(expResult, result); + + right = new Dependency(new File("/path/pom.xml"), true); + expResult = false; + result = instance.isShadedJar(left, right); + assertEquals(expResult, result); + + left.addIdentifier("test", "test", "http://example.com/test"); + expResult = false; + result = instance.isShadedJar(left, right); + assertEquals(expResult, result); + + right.addIdentifier("next", "next", "http://example.com/next"); + expResult = false; + result = instance.isShadedJar(left, right); + assertEquals(expResult, result); + + left.addIdentifier("next", "next", "http://example.com/next"); + expResult = true; + result = instance.isShadedJar(left, right); + assertEquals(expResult, result); + + left = new Dependency(new File("/path/pom.xml"), true); + left.addIdentifier("test", "test", "http://example.com/test"); + right = new Dependency(new File("/path/jar.jar"), true); + right.addIdentifier("next", "next", "http://example.com/next"); + expResult = false; + result = instance.isShadedJar(left, right); + assertEquals(expResult, result); + + right.addIdentifier("test", "test", "http://example.com/test"); + expResult = true; + result = instance.isShadedJar(left, right); + assertEquals(expResult, result); + + left = new Dependency(new File("/path/other.jar"), true); + left.addIdentifier("test", "test", "http://example.com/test"); + right = new Dependency(new File("/path/jar.jar"), true); + right.addIdentifier("next", "next", "http://example.com/next"); + expResult = false; + result = instance.isShadedJar(left, right); + assertEquals(expResult, result); + } } From 6f62902e4b74165880e1a8445995e2e986a72d15 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 6 May 2018 07:46:14 -0400 Subject: [PATCH 36/36] fix typo --- maven/src/it/740-aggregate/postbuild.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/maven/src/it/740-aggregate/postbuild.groovy b/maven/src/it/740-aggregate/postbuild.groovy index 6c230aadbf0..eb55854522d 100644 --- a/maven/src/it/740-aggregate/postbuild.groovy +++ b/maven/src/it/740-aggregate/postbuild.groovy @@ -24,7 +24,6 @@ String report = FileUtils.readFileToString(new File(basedir, "target/dependency- int count = StringUtils.countMatches(report, "org.owasp.test.aggregate:fourth:1.0.0-SNAPSHOT"); if (count == 0) { System.out.println(String.format("fourth-1.0.0-SNAPSHOT was not identified")); -); return false; } count = StringUtils.countMatches(report, "org.apache.james:apache-mime4j-core:0.7.2");