mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-03-26 11:01:44 +01:00
Merge branch 'issue630'
This commit is contained in:
@@ -36,6 +36,10 @@ public enum AnalysisPhase {
|
|||||||
* Information collection phase.
|
* Information collection phase.
|
||||||
*/
|
*/
|
||||||
INFORMATION_COLLECTION,
|
INFORMATION_COLLECTION,
|
||||||
|
/**
|
||||||
|
* Post information collection phase.
|
||||||
|
*/
|
||||||
|
POST_INFORMATION_COLLECTION,
|
||||||
/**
|
/**
|
||||||
* Pre identifier analysis phase.
|
* Pre identifier analysis phase.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
/**
|
/**
|
||||||
* The phase that this analyzer is intended to run in.
|
* The phase that this analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.FINAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
@@ -130,7 +130,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
* file.
|
* file.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency ignore, Engine engine) throws AnalysisException {
|
public synchronized void analyze(Dependency ignore, Engine engine) throws AnalysisException {
|
||||||
if (!analyzed) {
|
if (!analyzed) {
|
||||||
analyzed = true;
|
analyzed = true;
|
||||||
final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
|
final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
|
||||||
@@ -162,6 +162,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
}
|
}
|
||||||
} else if (cpeIdentifiersMatch(dependency, nextDependency)
|
} else if (cpeIdentifiersMatch(dependency, nextDependency)
|
||||||
&& hasSameBasePath(dependency, nextDependency)
|
&& hasSameBasePath(dependency, nextDependency)
|
||||||
|
&& vulnCountMatches(dependency, nextDependency)
|
||||||
&& fileNameMatch(dependency, nextDependency)) {
|
&& fileNameMatch(dependency, nextDependency)) {
|
||||||
if (isCore(dependency, nextDependency)) {
|
if (isCore(dependency, nextDependency)) {
|
||||||
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
@@ -169,20 +170,6 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
||||||
}
|
}
|
||||||
} else if ((main = getMainGemspecDependency(dependency, nextDependency)) != null) {
|
|
||||||
if (main == dependency) {
|
|
||||||
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
|
||||||
} else {
|
|
||||||
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
|
||||||
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
|
||||||
}
|
|
||||||
} else if ((main = getMainSwiftDependency(dependency, nextDependency)) != null) {
|
|
||||||
if (main == dependency) {
|
|
||||||
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
|
||||||
} else {
|
|
||||||
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
|
||||||
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,7 +211,12 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
* @return a string representing the base path.
|
* @return a string representing the base path.
|
||||||
*/
|
*/
|
||||||
private String getBaseRepoPath(final String path) {
|
private String getBaseRepoPath(final String path) {
|
||||||
int pos = path.indexOf("repository" + File.separator) + 11;
|
int pos;
|
||||||
|
if (path.contains("local-repo")) {
|
||||||
|
pos = path.indexOf("local-repo" + File.separator) + 11;
|
||||||
|
} else {
|
||||||
|
pos = path.indexOf("repository" + File.separator) + 11;
|
||||||
|
}
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@@ -317,6 +309,19 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the two dependencies have the same vulnerability count.
|
||||||
|
*
|
||||||
|
* @param dependency1 a dependency2 to compare
|
||||||
|
* @param dependency2 a dependency2 to compare
|
||||||
|
* @return true if the two dependencies have the same vulnerability count
|
||||||
|
*/
|
||||||
|
private boolean vulnCountMatches(Dependency dependency1, Dependency dependency2) {
|
||||||
|
return dependency1.getVulnerabilities() != null && dependency2.getVulnerabilities() != null
|
||||||
|
&& dependency1.getVulnerabilities().size() == dependency2.getVulnerabilities().size();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the two dependencies have the same base path.
|
* Determines if the two dependencies have the same base path.
|
||||||
*
|
*
|
||||||
@@ -341,7 +346,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) {
|
if (left.matches(".*[/\\\\](repository|local-repo)[/\\\\].*") && right.matches(".*[/\\\\](repository|local-repo)[/\\\\].*")) {
|
||||||
left = getBaseRepoPath(left);
|
left = getBaseRepoPath(left);
|
||||||
right = getBaseRepoPath(right);
|
right = getBaseRepoPath(right);
|
||||||
}
|
}
|
||||||
@@ -357,96 +362,6 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Bundling Ruby gems that are identified from different .gemspec files but
|
|
||||||
* denote the same package path. This happens when Ruby bundler installs an
|
|
||||||
* application's dependencies by running "bundle install".
|
|
||||||
*
|
|
||||||
* @param dependency1 dependency to compare
|
|
||||||
* @param dependency2 dependency to compare
|
|
||||||
* @return true if the the dependencies being analyzed appear to be the
|
|
||||||
* same; otherwise false
|
|
||||||
*/
|
|
||||||
private boolean isSameRubyGem(Dependency dependency1, Dependency dependency2) {
|
|
||||||
if (dependency1 == null || dependency2 == null
|
|
||||||
|| !dependency1.getFileName().endsWith(".gemspec")
|
|
||||||
|| !dependency2.getFileName().endsWith(".gemspec")
|
|
||||||
|| dependency1.getPackagePath() == null
|
|
||||||
|| dependency2.getPackagePath() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ruby gems installed by "bundle install" can have zero or more *.gemspec
|
|
||||||
* files, all of which have the same packagePath and should be grouped. If
|
|
||||||
* one of these gemspec is from <parent>/specifications/*.gemspec, because
|
|
||||||
* it is a stub with fully resolved gem meta-data created by Ruby bundler,
|
|
||||||
* this dependency should be the main one. Otherwise, use dependency2 as
|
|
||||||
* main.
|
|
||||||
*
|
|
||||||
* This method returns null if any dependency is not from *.gemspec, or the
|
|
||||||
* two do not have the same packagePath. In this case, they should not be
|
|
||||||
* grouped.
|
|
||||||
*
|
|
||||||
* @param dependency1 dependency to compare
|
|
||||||
* @param dependency2 dependency to compare
|
|
||||||
* @return the main dependency; or null if a gemspec is not included in the
|
|
||||||
* analysis
|
|
||||||
*/
|
|
||||||
private Dependency getMainGemspecDependency(Dependency dependency1, Dependency dependency2) {
|
|
||||||
if (isSameRubyGem(dependency1, dependency2)) {
|
|
||||||
final File lFile = dependency1.getActualFile();
|
|
||||||
final File left = lFile.getParentFile();
|
|
||||||
if (left != null && left.getName().equalsIgnoreCase("specifications")) {
|
|
||||||
return dependency1;
|
|
||||||
}
|
|
||||||
return dependency2;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bundling same swift dependencies with the same packagePath but identified
|
|
||||||
* by different analyzers.
|
|
||||||
*
|
|
||||||
* @param dependency1 dependency to test
|
|
||||||
* @param dependency2 dependency to test
|
|
||||||
* @return <code>true</code> if the dependencies appear to be the same;
|
|
||||||
* otherwise <code>false</code>
|
|
||||||
*/
|
|
||||||
private boolean isSameSwiftPackage(Dependency dependency1, Dependency dependency2) {
|
|
||||||
if (dependency1 == null || dependency2 == null
|
|
||||||
|| (!dependency1.getFileName().endsWith(".podspec")
|
|
||||||
&& !dependency1.getFileName().equals("Package.swift"))
|
|
||||||
|| (!dependency2.getFileName().endsWith(".podspec")
|
|
||||||
&& !dependency2.getFileName().equals("Package.swift"))
|
|
||||||
|| dependency1.getPackagePath() == null
|
|
||||||
|| dependency2.getPackagePath() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines which of the swift dependencies should be considered the
|
|
||||||
* primary.
|
|
||||||
*
|
|
||||||
* @param dependency1 the first swift dependency to compare
|
|
||||||
* @param dependency2 the second swift dependency to compare
|
|
||||||
* @return the primary swift dependency
|
|
||||||
*/
|
|
||||||
private Dependency getMainSwiftDependency(Dependency dependency1, Dependency dependency2) {
|
|
||||||
if (isSameSwiftPackage(dependency1, dependency2)) {
|
|
||||||
if (dependency1.getFileName().endsWith(".podspec")) {
|
|
||||||
return dependency1;
|
|
||||||
}
|
|
||||||
return dependency2;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is likely a very broken attempt at determining if the 'left'
|
* This is likely a very broken attempt at determining if the 'left'
|
||||||
* dependency is the 'core' library in comparison to the 'right' library.
|
* dependency is the 'core' library in comparison to the 'right' library.
|
||||||
@@ -469,10 +384,6 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
|| !rightName.contains("core") && leftName.contains("core")
|
|| !rightName.contains("core") && leftName.contains("core")
|
||||||
|| !rightName.contains("kernel") && leftName.contains("kernel")) {
|
|| !rightName.contains("kernel") && leftName.contains("kernel")) {
|
||||||
returnVal = true;
|
returnVal = true;
|
||||||
// } else if (leftName.matches(".*struts2\\-core.*") && rightName.matches(".*xwork\\-core.*")) {
|
|
||||||
// returnVal = true;
|
|
||||||
// } else if (rightName.matches(".*struts2\\-core.*") && leftName.matches(".*xwork\\-core.*")) {
|
|
||||||
// returnVal = false;
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* considered splitting the names up and comparing the components,
|
* considered splitting the names up and comparing the components,
|
||||||
@@ -577,4 +488,5 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
private boolean containedInWar(String filePath) {
|
private boolean containedInWar(String filePath) {
|
||||||
return filePath == null ? false : filePath.matches(".*\\.(ear|war)[\\\\/].*");
|
return filePath == null ? false : filePath.matches(".*\\.(ear|war)[\\\\/].*");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dependency-check-core.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This analyzer will merge dependencies, created from different source, into a
|
||||||
|
* single dependency.</p>
|
||||||
|
*
|
||||||
|
* @author Jeremy Long
|
||||||
|
*/
|
||||||
|
public class DependencyMergingAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
|
||||||
|
/**
|
||||||
|
* The Logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(DependencyMergingAnalyzer.class);
|
||||||
|
/**
|
||||||
|
* a flag indicating if this analyzer has run. This analyzer only runs once.
|
||||||
|
*/
|
||||||
|
private boolean analyzed = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a flag indicating if this analyzer has run. This analyzer only
|
||||||
|
* runs once. Note this is currently only used in the unit tests.
|
||||||
|
*
|
||||||
|
* @return a flag indicating if this analyzer has run. This analyzer only
|
||||||
|
* runs once
|
||||||
|
*/
|
||||||
|
protected boolean getAnalyzed() {
|
||||||
|
return analyzed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
||||||
|
/**
|
||||||
|
* The name of the analyzer.
|
||||||
|
*/
|
||||||
|
private static final String ANALYZER_NAME = "Dependency Merging Analyzer";
|
||||||
|
/**
|
||||||
|
* The phase that this analyzer is intended to run in.
|
||||||
|
*/
|
||||||
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_INFORMATION_COLLECTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the analyzer.
|
||||||
|
*
|
||||||
|
* @return the name of the analyzer.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return ANALYZER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
|
*
|
||||||
|
* @return the phase that the analyzer is intended to run in.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return ANALYSIS_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does not support parallel processing as it only runs once and then
|
||||||
|
* operates on <em>all</em> dependencies.
|
||||||
|
*
|
||||||
|
* @return whether or not parallel processing is enabled
|
||||||
|
* @see #analyze(Dependency, Engine)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supportsParallelProcessing() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//</editor-fold>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzes a set of dependencies. If they have been found to be the same
|
||||||
|
* dependency created by more multiple FileTypeAnalyzers (i.e. a gemspec
|
||||||
|
* dependency and a dependency from the Bundle Audit Analyzer. The
|
||||||
|
* dependencies are then merged into a single reportable item.
|
||||||
|
*
|
||||||
|
* @param ignore this analyzer ignores the dependency being analyzed
|
||||||
|
* @param engine the engine that is scanning the dependencies
|
||||||
|
* @throws AnalysisException is thrown if there is an error reading the JAR
|
||||||
|
* file.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized void analyze(Dependency ignore, Engine engine) throws AnalysisException {
|
||||||
|
if (!analyzed) {
|
||||||
|
analyzed = true;
|
||||||
|
final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
|
||||||
|
final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
|
||||||
|
//for (Dependency nextDependency : engine.getDependencies()) {
|
||||||
|
while (mainIterator.hasNext()) {
|
||||||
|
final Dependency dependency = mainIterator.next();
|
||||||
|
if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) {
|
||||||
|
final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
|
||||||
|
while (subIterator.hasNext()) {
|
||||||
|
final Dependency nextDependency = subIterator.next();
|
||||||
|
Dependency main = null;
|
||||||
|
if ((main = getMainGemspecDependency(dependency, nextDependency)) != null) {
|
||||||
|
if (main == dependency) {
|
||||||
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
|
} else {
|
||||||
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
|
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
||||||
|
}
|
||||||
|
} else if ((main = getMainSwiftDependency(dependency, nextDependency)) != null) {
|
||||||
|
if (main == dependency) {
|
||||||
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
|
} else {
|
||||||
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
|
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions
|
||||||
|
// was difficult because of the inner iterator.
|
||||||
|
engine.getDependencies().removeAll(dependenciesToRemove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the relatedDependency to the dependency's related dependencies.
|
||||||
|
*
|
||||||
|
* @param dependency the main dependency
|
||||||
|
* @param relatedDependency a collection of dependencies to be removed from
|
||||||
|
* the main analysis loop, this is the source of dependencies to remove
|
||||||
|
* @param dependenciesToRemove a collection of dependencies that will be
|
||||||
|
* removed from the main analysis loop, this function adds to this
|
||||||
|
* collection
|
||||||
|
*/
|
||||||
|
private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) {
|
||||||
|
dependency.addRelatedDependency(relatedDependency);
|
||||||
|
dependency.getVendorEvidence().getEvidence().addAll(relatedDependency.getVendorEvidence().getEvidence());
|
||||||
|
dependency.getProductEvidence().getEvidence().addAll(relatedDependency.getProductEvidence().getEvidence());
|
||||||
|
dependency.getVersionEvidence().getEvidence().addAll(relatedDependency.getVersionEvidence().getEvidence());
|
||||||
|
|
||||||
|
final Iterator<Dependency> i = relatedDependency.getRelatedDependencies().iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
dependency.addRelatedDependency(i.next());
|
||||||
|
i.remove();
|
||||||
|
}
|
||||||
|
if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) {
|
||||||
|
dependency.addAllProjectReferences(relatedDependency.getProjectReferences());
|
||||||
|
}
|
||||||
|
dependenciesToRemove.add(relatedDependency);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bundling Ruby gems that are identified from different .gemspec files but
|
||||||
|
* denote the same package path. This happens when Ruby bundler installs an
|
||||||
|
* application's dependencies by running "bundle install".
|
||||||
|
*
|
||||||
|
* @param dependency1 dependency to compare
|
||||||
|
* @param dependency2 dependency to compare
|
||||||
|
* @return true if the the dependencies being analyzed appear to be the
|
||||||
|
* same; otherwise false
|
||||||
|
*/
|
||||||
|
private boolean isSameRubyGem(Dependency dependency1, Dependency dependency2) {
|
||||||
|
if (dependency1 == null || dependency2 == null
|
||||||
|
|| !dependency1.getFileName().endsWith(".gemspec")
|
||||||
|
|| !dependency2.getFileName().endsWith(".gemspec")
|
||||||
|
|| dependency1.getPackagePath() == null
|
||||||
|
|| dependency2.getPackagePath() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ruby gems installed by "bundle install" can have zero or more *.gemspec
|
||||||
|
* files, all of which have the same packagePath and should be grouped. If
|
||||||
|
* one of these gemspec is from <parent>/specifications/*.gemspec, because
|
||||||
|
* it is a stub with fully resolved gem meta-data created by Ruby bundler,
|
||||||
|
* this dependency should be the main one. Otherwise, use dependency2 as
|
||||||
|
* main.
|
||||||
|
*
|
||||||
|
* This method returns null if any dependency is not from *.gemspec, or the
|
||||||
|
* two do not have the same packagePath. In this case, they should not be
|
||||||
|
* grouped.
|
||||||
|
*
|
||||||
|
* @param dependency1 dependency to compare
|
||||||
|
* @param dependency2 dependency to compare
|
||||||
|
* @return the main dependency; or null if a gemspec is not included in the
|
||||||
|
* analysis
|
||||||
|
*/
|
||||||
|
private Dependency getMainGemspecDependency(Dependency dependency1, Dependency dependency2) {
|
||||||
|
if (isSameRubyGem(dependency1, dependency2)) {
|
||||||
|
final File lFile = dependency1.getActualFile();
|
||||||
|
final File left = lFile.getParentFile();
|
||||||
|
if (left != null && left.getName().equalsIgnoreCase("specifications")) {
|
||||||
|
return dependency1;
|
||||||
|
}
|
||||||
|
return dependency2;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bundling same swift dependencies with the same packagePath but identified
|
||||||
|
* by different file type analyzers.
|
||||||
|
*
|
||||||
|
* @param dependency1 dependency to test
|
||||||
|
* @param dependency2 dependency to test
|
||||||
|
* @return <code>true</code> if the dependencies appear to be the same;
|
||||||
|
* otherwise <code>false</code>
|
||||||
|
*/
|
||||||
|
private boolean isSameSwiftPackage(Dependency dependency1, Dependency dependency2) {
|
||||||
|
if (dependency1 == null || dependency2 == null
|
||||||
|
|| (!dependency1.getFileName().endsWith(".podspec")
|
||||||
|
&& !dependency1.getFileName().equals("Package.swift"))
|
||||||
|
|| (!dependency2.getFileName().endsWith(".podspec")
|
||||||
|
&& !dependency2.getFileName().equals("Package.swift"))
|
||||||
|
|| dependency1.getPackagePath() == null
|
||||||
|
|| dependency2.getPackagePath() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines which of the swift dependencies should be considered the
|
||||||
|
* primary.
|
||||||
|
*
|
||||||
|
* @param dependency1 the first swift dependency to compare
|
||||||
|
* @param dependency2 the second swift dependency to compare
|
||||||
|
* @return the primary swift dependency
|
||||||
|
*/
|
||||||
|
private Dependency getMainSwiftDependency(Dependency dependency1, Dependency dependency2) {
|
||||||
|
if (isSameSwiftPackage(dependency1, dependency2)) {
|
||||||
|
if (dependency1.getFileName().endsWith(".podspec")) {
|
||||||
|
return dependency1;
|
||||||
|
}
|
||||||
|
return dependency2;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ org.owasp.dependencycheck.analyzer.CPEAnalyzer
|
|||||||
org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer
|
org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer
|
||||||
org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer
|
org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer
|
||||||
org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer
|
org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer
|
||||||
|
org.owasp.dependencycheck.analyzer.DependencyMergingAnalyzer
|
||||||
org.owasp.dependencycheck.analyzer.NvdCveAnalyzer
|
org.owasp.dependencycheck.analyzer.NvdCveAnalyzer
|
||||||
org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer
|
org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer
|
||||||
org.owasp.dependencycheck.analyzer.CentralAnalyzer
|
org.owasp.dependencycheck.analyzer.CentralAnalyzer
|
||||||
|
|||||||
@@ -460,4 +460,18 @@
|
|||||||
<filePath regex="true">.*</filePath>
|
<filePath regex="true">.*</filePath>
|
||||||
<cve>CVE-2007-6059</cve>
|
<cve>CVE-2007-6059</cve>
|
||||||
</suppress>
|
</suppress>
|
||||||
|
<suppress base="true">
|
||||||
|
<notes><![CDATA[
|
||||||
|
file name: jackson-core-2.6.5.jar
|
||||||
|
]]></notes>
|
||||||
|
<gav regex="true">com\.fasterxml\.jackson\.core:jackson.*</gav>
|
||||||
|
<cve>CVE-2016-3720</cve>
|
||||||
|
</suppress>
|
||||||
|
<suppress base="true">
|
||||||
|
<notes><![CDATA[
|
||||||
|
file name: jackson-core-2.6.5.jar
|
||||||
|
]]></notes>
|
||||||
|
<gav regex="true">com\.fasterxml\.jackson\.dataformat:jackson(?!\-dataformat\-xml).*</gav>
|
||||||
|
<cve>CVE-2016-3720</cve>
|
||||||
|
</suppress>
|
||||||
</suppressions>
|
</suppressions>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class DependencyBundlingAnalyzerTest extends BaseTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGetAnalysisPhase() {
|
public void testGetAnalysisPhase() {
|
||||||
DependencyBundlingAnalyzer instance = new DependencyBundlingAnalyzer();
|
DependencyBundlingAnalyzer instance = new DependencyBundlingAnalyzer();
|
||||||
AnalysisPhase expResult = AnalysisPhase.PRE_FINDING_ANALYSIS;
|
AnalysisPhase expResult = AnalysisPhase.FINAL;
|
||||||
AnalysisPhase result = instance.getAnalysisPhase();
|
AnalysisPhase result = instance.getAnalysisPhase();
|
||||||
assertEquals(expResult, result);
|
assertEquals(expResult, result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,5 @@
|
|||||||
# Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
# Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||||
#
|
#
|
||||||
|
|
||||||
invoker.goals.1 = ${project.groupId}:${project.artifactId}:${project.version}:update-only
|
invoker.goals.1 = ${project.groupId}:${project.artifactId}:${project.version}:update-only -DdataDirectory=./data -Dcve.startyear=2016
|
||||||
invoker.postBuildHookScript.1 = save-nvd-cve.groovy
|
invoker.goals.2 = ${project.groupId}:${project.artifactId}:${project.version}:purge -DdataDirectory=./data
|
||||||
invoker.goals.2 = ${project.groupId}:${project.artifactId}:${project.version}:purge
|
|
||||||
|
|||||||
@@ -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) 2016 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
|
||||||
|
// Analyse number of "Checking for updates"
|
||||||
|
String log = FileUtils.readFileToString(new File(basedir, "build.log"), Charset.defaultCharset().name());
|
||||||
|
if (!StringUtils.contains(log, "Database file purged; local copy of the NVD has been removed")) {
|
||||||
|
System.out.println("The database was not purged.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
@@ -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 -e -Dformat=ALL
|
||||||
47
dependency-check-maven/src/it/629-jackson-datafromat/pom.xml
Normal file
47
dependency-check-maven/src/it/629-jackson-datafromat/pom.xml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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) 2013 Jeremy Long. All Rights Reserved.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.owasp.test</groupId>
|
||||||
|
<artifactId>test-dataformat-jackson</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.4.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-annotations</artifactId>
|
||||||
|
<version>2.4.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-cbor</artifactId>
|
||||||
|
<version>2.4.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-xml</artifactId>
|
||||||
|
<version>2.4.5</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -16,9 +16,9 @@
|
|||||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
// Save NVD-CVE for next IT (if not already done)
|
// Save NVD-CVE for next IT (if not already done)
|
||||||
File datasDwl = new File("target/local-repo/org/owasp/dependency-check-data/3.0", "dc.h2.db");
|
File datasDwl = new File("target/local-repo/org/owasp/dependency-check-data/3.0", "dc.h2.db");
|
||||||
@@ -27,3 +27,16 @@ if (datasDwl.exists() && !datasSave.exists()){
|
|||||||
System.out.println("Save NVD-CVE into backup");
|
System.out.println("Save NVD-CVE into backup");
|
||||||
FileUtils.copyFile(datasDwl, datasSave);
|
FileUtils.copyFile(datasDwl, datasSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Check to see if jackson-dataformat-xml-2.4.5.jar was identified.
|
||||||
|
//TODO change this to xpath and check for CVE-2016-3720
|
||||||
|
String log = FileUtils.readFileToString(new File(basedir, "target/dependency-check-report.xml"), Charset.defaultCharset().name());
|
||||||
|
int count = StringUtils.countMatches(log, "<fileName>jackson-dataformat-xml-2.4.5.jar</fileName>");
|
||||||
|
if (count == 0){
|
||||||
|
System.out.println(String.format("The update should be unique, it is %s", count));
|
||||||
|
return false;
|
||||||
|
//throw new Exception(String.format("The update should be unique, it is %s", count));
|
||||||
|
}
|
||||||
@@ -77,7 +77,9 @@ public final class XmlUtils {
|
|||||||
factory.setValidating(true);
|
factory.setValidating(true);
|
||||||
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||||
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||||
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
//setting the following unfortunately breaks reading the old suppression files (version 1).
|
||||||
|
//factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
|
||||||
final SAXParser saxParser = factory.newSAXParser();
|
final SAXParser saxParser = factory.newSAXParser();
|
||||||
saxParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
|
saxParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
|
||||||
saxParser.setProperty(JAXP_SCHEMA_SOURCE, schemaStream);
|
saxParser.setProperty(JAXP_SCHEMA_SOURCE, schemaStream);
|
||||||
|
|||||||
Reference in New Issue
Block a user