mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-01-15 00:03:43 +01:00
updated to address issue #193
Former-commit-id: 8361c2fdbec4191e52db16b870406e3e45d97d0d
This commit is contained in:
@@ -41,8 +41,8 @@ import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
|
||||
/**
|
||||
* Maven Plugin that checks project dependencies and the dependencies of all child modules to see if they have any known
|
||||
* published vulnerabilities.
|
||||
* Maven Plugin that checks project dependencies and the dependencies of all child modules to see if they have any known published
|
||||
* vulnerabilities.
|
||||
*
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
@@ -73,21 +73,27 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
||||
|
||||
if (getProject() == getReactorProjects().get(getReactorProjects().size() - 1)) {
|
||||
final Map<MavenProject, Set<MavenProject>> children = buildAggregateInfo();
|
||||
boolean hasOrchestration = false;
|
||||
|
||||
for (MavenProject current : getReactorProjects()) {
|
||||
final List<Dependency> dependencies = readDataFile(current);
|
||||
final List<MavenProject> childProjects = getAllChildren(current, children);
|
||||
//check for orchestration build - execution root with no children or dependencies
|
||||
if ((dependencies == null || dependencies.isEmpty()) && childProjects.isEmpty() && current.isExecutionRoot()) {
|
||||
hasOrchestration = true;
|
||||
final File outputDir = getCorrectOutputDirectory(current);
|
||||
if (outputDir == null) { //dc was never run on this project. write the ser to the target.
|
||||
engine.getDependencies().clear();
|
||||
engine.resetFileTypeAnalyzers();
|
||||
scanArtifacts(current, engine);
|
||||
engine.analyzeDependencies();
|
||||
final File target = new File(current.getBuild().getOutputDirectory()).getParentFile();
|
||||
writeDataFile(current, target, engine.getDependencies());
|
||||
showSummary(current, engine.getDependencies());
|
||||
}
|
||||
}
|
||||
|
||||
for (MavenProject current : getReactorProjects()) {
|
||||
List<Dependency> dependencies = readDataFile(current);
|
||||
final List<MavenProject> childProjects = getAllChildren(current, children);
|
||||
|
||||
//check for orchestration build - execution root with no children or dependencies
|
||||
if ((dependencies == null || dependencies.isEmpty()) && childProjects.isEmpty() && current.isExecutionRoot()) {
|
||||
engine.getDependencies().clear();
|
||||
engine.resetFileTypeAnalyzers();
|
||||
for (MavenProject mod : getReactorProjects()) {
|
||||
scanArtifacts(mod, engine);
|
||||
@@ -113,14 +119,13 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
||||
LOGGER.log(Level.FINE, "Bundling Exception", ex);
|
||||
}
|
||||
}
|
||||
try {
|
||||
final File outputDir = getCorrectOutputDirectory(current);
|
||||
writeReports(engine, current, outputDir);
|
||||
} catch (MojoExecutionException ex) {
|
||||
if (!hasOrchestration) {
|
||||
throw ex;
|
||||
} // else ignore this
|
||||
File outputDir = getCorrectOutputDirectory(current);
|
||||
if (outputDir == null) {
|
||||
//in some regards we shouldn't be writting this, but we are anyway.
|
||||
//we shouldn't write this because nothing is configured to generate this report.
|
||||
outputDir = new File(current.getBuild().getOutputDirectory()).getParentFile();
|
||||
}
|
||||
writeReports(engine, current, outputDir);
|
||||
}
|
||||
}
|
||||
engine.cleanup();
|
||||
@@ -183,8 +188,7 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
||||
*
|
||||
* @return the Engine used to execute dependency-check
|
||||
* @throws MojoExecutionException thrown if there is an exception running the mojo
|
||||
* @throws MojoFailureException thrown if dependency-check is configured to fail the build if severe CVEs are
|
||||
* identified.
|
||||
* @throws MojoFailureException thrown if dependency-check is configured to fail the build if severe CVEs are identified.
|
||||
*/
|
||||
protected Engine generateDataFile() throws MojoExecutionException, MojoFailureException {
|
||||
final Engine engine;
|
||||
@@ -196,8 +200,8 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
||||
}
|
||||
scanArtifacts(getProject(), engine);
|
||||
engine.analyzeDependencies();
|
||||
writeDataFile(engine.getDependencies());
|
||||
showSummary(engine.getDependencies());
|
||||
writeDataFile(getProject(), null, engine.getDependencies());
|
||||
showSummary(getProject(), engine.getDependencies());
|
||||
checkForFailure(engine.getDependencies());
|
||||
return engine;
|
||||
}
|
||||
|
||||
@@ -101,21 +101,29 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
@SuppressWarnings("CanBeFinal")
|
||||
@Parameter(property = "logFile", defaultValue = "")
|
||||
private String logFile = null;
|
||||
|
||||
//"project.reporting.outputDirectory"
|
||||
/**
|
||||
* The output directory. This generally maps to "target".
|
||||
*/
|
||||
@Parameter(defaultValue = "${project.build.directory}", required = true)
|
||||
private File outputDirectory;
|
||||
/**
|
||||
* Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11
|
||||
* which means since the CVSS scores are 0-10, by default the build will never fail.
|
||||
* Specifies the destination directory for the generated Dependency-Check report. This generally maps to "target/site".
|
||||
*/
|
||||
//Parameter(property = "reportOutputDirectory", defaultValue = "${project.reporting.outputDirectory}", required = true)
|
||||
@Parameter(property = "project.reporting.outputDirectory", required = true)
|
||||
private File reportOutputDirectory;
|
||||
/**
|
||||
* Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which
|
||||
* means since the CVSS scores are 0-10, by default the build will never fail.
|
||||
*/
|
||||
@SuppressWarnings("CanBeFinal")
|
||||
@Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true)
|
||||
private float failBuildOnCVSS = 11;
|
||||
/**
|
||||
* Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to
|
||||
* false. Default is true.
|
||||
* Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default
|
||||
* is true.
|
||||
*/
|
||||
@SuppressWarnings("CanBeFinal")
|
||||
@Parameter(property = "autoupdate", defaultValue = "true", required = true)
|
||||
@@ -129,8 +137,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
@Deprecated
|
||||
private boolean aggregate;
|
||||
/**
|
||||
* The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this
|
||||
* within the Site plug-in unless the externalReport is set to true. Default is HTML.
|
||||
* The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the
|
||||
* Site plug-in unless the externalReport is set to true. Default is HTML.
|
||||
*/
|
||||
@SuppressWarnings("CanBeFinal")
|
||||
@Parameter(property = "format", defaultValue = "HTML", required = true)
|
||||
@@ -317,13 +325,6 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
@Parameter(property = "externalReport")
|
||||
@Deprecated
|
||||
private String externalReport = null;
|
||||
|
||||
/**
|
||||
* Specifies the destination directory for the generated Dependency-Check report. This generally maps to
|
||||
* "target/site".
|
||||
*/
|
||||
@Parameter(property = "reportOutputDirectory", defaultValue = "${project.reporting.outputDirectory}", required = true)
|
||||
private File reportOutputDirectory;
|
||||
// </editor-fold>
|
||||
//<editor-fold defaultstate="collapsed" desc="Base Maven implementation">
|
||||
|
||||
@@ -341,8 +342,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the aggregate configuration parameter has been set to true. If it has a MojoExecutionException is
|
||||
* thrown because the aggregate configuration parameter is no longer supported.
|
||||
* Checks if the aggregate configuration parameter has been set to true. If it has a MojoExecutionException is thrown because
|
||||
* the aggregate configuration parameter is no longer supported.
|
||||
*
|
||||
* @throws MojoExecutionException thrown if aggregate is set to true
|
||||
*/
|
||||
@@ -405,15 +406,13 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
*
|
||||
* @param current the Maven project to get the output directory from
|
||||
* @return the directory to write the report(s)
|
||||
* @throws MojoExecutionException thrown if there is an error loading the file path
|
||||
*/
|
||||
protected File getCorrectOutputDirectory(MavenProject current) throws MojoExecutionException {
|
||||
protected File getCorrectOutputDirectory(MavenProject current) {
|
||||
final Object obj = current.getContextValue(getOutputDirectoryContextKey());
|
||||
if (obj != null && obj instanceof File) {
|
||||
return (File) obj;
|
||||
} else {
|
||||
throw new MojoExecutionException(String.format("Unable to determine output directory for '%s'", current.getName()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -526,15 +525,19 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
* @throws DatabaseException thrown if there is a database exception
|
||||
*/
|
||||
protected Engine initializeEngine() throws DatabaseException {
|
||||
final InputStream in = BaseDependencyCheckMojo.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
|
||||
final InputStream in = BaseDependencyCheckMojo.class
|
||||
.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
|
||||
LogUtils.prepareLogger(in, logFile);
|
||||
|
||||
populateSettings();
|
||||
return new Engine(this.project, this.reactorProjects);
|
||||
|
||||
return new Engine(this.project,
|
||||
this.reactorProjects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system
|
||||
* properties required to change the proxy url, port, and connection timeout.
|
||||
* Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
|
||||
* required to change the proxy url, port, and connection timeout.
|
||||
*/
|
||||
private void populateSettings() {
|
||||
Settings.initialize();
|
||||
@@ -699,9 +702,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
|
||||
/**
|
||||
* Returns a reference to the current project. This method is used instead of auto-binding the project via component
|
||||
* annotation in concrete implementations of this. If the child has a <code>@Component MavenProject project;</code>
|
||||
* defined then the abstract class (i.e. this class) will not have access to the current project (just the way Maven
|
||||
* works with the binding).
|
||||
* annotation in concrete implementations of this. If the child has a <code>@Component MavenProject project;</code> defined
|
||||
* then the abstract class (i.e. this class) will not have access to the current project (just the way Maven works with the
|
||||
* binding).
|
||||
*
|
||||
* @return returns a reference to the current project
|
||||
*/
|
||||
@@ -799,9 +802,10 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
/**
|
||||
* Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries.
|
||||
*
|
||||
* @param mp the Maven project for which the summary is shown
|
||||
* @param dependencies a list of dependency objects
|
||||
*/
|
||||
protected void showSummary(List<Dependency> dependencies) {
|
||||
protected void showSummary(MavenProject mp, List<Dependency> dependencies) {
|
||||
if (showSummary) {
|
||||
final StringBuilder summary = new StringBuilder();
|
||||
for (Dependency d : dependencies) {
|
||||
@@ -830,8 +834,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
}
|
||||
}
|
||||
if (summary.length() > 0) {
|
||||
final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities:%n%n%s"
|
||||
+ "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
|
||||
final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s"
|
||||
+ "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString());
|
||||
LOGGER.log(Level.WARNING, msg);
|
||||
}
|
||||
}
|
||||
@@ -840,8 +844,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
//</editor-fold>
|
||||
//<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file">
|
||||
/**
|
||||
* Returns the key used to store the path to the data file that is saved by <code>writeDataFile()</code>. This key
|
||||
* is used in the <code>MavenProject.(set|get)ContextValue</code>.
|
||||
* Returns the key used to store the path to the data file that is saved by <code>writeDataFile()</code>. This key is used in
|
||||
* the <code>MavenProject.(set|get)ContextValue</code>.
|
||||
*
|
||||
* @return the key used to store the path to the data file
|
||||
*/
|
||||
@@ -862,12 +866,18 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
/**
|
||||
* Writes the scan data to disk. This is used to serialize the scan data between the "check" and "aggregate" phase.
|
||||
*
|
||||
* @param mp the mMven project for which the data file was created
|
||||
* @param writeTo the directory to write the data file
|
||||
* @param dependencies the list of dependencies to serialize
|
||||
*/
|
||||
protected void writeDataFile(List<Dependency> dependencies) {
|
||||
File file = null;
|
||||
if (dependencies != null && project.getContextValue(this.getDataFileContextKey()) == null) {
|
||||
file = new File(project.getBuild().getDirectory(), dataFileName);
|
||||
protected void writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) {
|
||||
File file;
|
||||
if (dependencies != null && mp.getContextValue(this.getDataFileContextKey()) == null) {
|
||||
if (writeTo != null) {
|
||||
file = new File(mp.getBuild().getDirectory(), dataFileName);
|
||||
} else {
|
||||
file = new File(writeTo, dataFileName);
|
||||
}
|
||||
OutputStream os = null;
|
||||
OutputStream bos = null;
|
||||
ObjectOutputStream out = null;
|
||||
@@ -881,8 +891,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
//call reset to prevent resource leaks per
|
||||
//https://www.securecoding.cert.org/confluence/display/java/SER10-J.+Avoid+memory+and+resource+leaks+during+serialization
|
||||
out.reset();
|
||||
project.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath());
|
||||
LOGGER.fine(String.format("Serialized data file written to '%s'", file.getAbsolutePath()));
|
||||
mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath());
|
||||
LOGGER.fine(String.format("Serialized data file written to '%s' for %s", file.getAbsolutePath(), mp.getName()));
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "Unable to create data file used for report aggregation; "
|
||||
+ "if report aggregation is being used the results may be incomplete.");
|
||||
@@ -914,8 +924,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the serialized scan data from disk. This is used to serialize the scan data between the "check" and
|
||||
* "aggregate" phase.
|
||||
* Reads the serialized scan data from disk. This is used to serialize the scan data between the "check" and "aggregate"
|
||||
* phase.
|
||||
*
|
||||
* @param project the Maven project to read the data file from
|
||||
* @return a <code>Engine</code> object populated with dependencies if the serialized data file exists; otherwise
|
||||
|
||||
@@ -86,8 +86,8 @@ public class CheckMojo extends BaseDependencyCheckMojo {
|
||||
} else {
|
||||
engine.analyzeDependencies();
|
||||
writeReports(engine, getProject(), getCorrectOutputDirectory());
|
||||
writeDataFile(engine.getDependencies());
|
||||
showSummary(engine.getDependencies());
|
||||
writeDataFile(getProject(), null, engine.getDependencies());
|
||||
showSummary(getProject(), engine.getDependencies());
|
||||
checkForFailure(engine.getDependencies());
|
||||
}
|
||||
engine.cleanup();
|
||||
|
||||
Reference in New Issue
Block a user