diff --git a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.java b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.java index 61a63be0a..40f718440 100644 --- a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.java +++ b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.java @@ -34,6 +34,7 @@ import org.apache.tools.ant.types.resources.FileProvider; import org.apache.tools.ant.types.resources.Resources; import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.dependency.Dependency; +import org.owasp.dependencycheck.dependency.Identifier; import org.owasp.dependencycheck.dependency.Vulnerability; import org.owasp.dependencycheck.reporting.ReportGenerator; import org.owasp.dependencycheck.reporting.ReportGenerator.Format; @@ -55,6 +56,10 @@ public class DependencyCheckTask extends Task { * Name of the logging properties file. */ private static final String LOG_PROPERTIES_FILE = "log.properties"; + /** + * System specific new line character. + */ + private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); /** * Construct a new DependencyCheckTask. @@ -433,6 +438,28 @@ public class DependencyCheckTask extends Task { public void setSuppressionFile(String suppressionFile) { this.suppressionFile = suppressionFile; } + /** + * flag indicating whether or not to show a summary of findings. + */ + private boolean showSummary = true; + + /** + * Get the value of showSummary. + * + * @return the value of showSummary + */ + public boolean isShowSummary() { + return showSummary; + } + + /** + * Set the value of showSummary. + * + * @param showSummary new value of showSummary + */ + public void setShowSummary(boolean showSummary) { + this.showSummary = showSummary; + } @Override public void execute() throws BuildException { @@ -461,6 +488,9 @@ public class DependencyCheckTask extends Task { if (this.failBuildOnCVSS <= 10) { checkForFailure(engine.getDependencies()); } + if (this.showSummary) { + showSummary(engine.getDependencies()); + } } catch (IOException ex) { Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, null, ex); throw new BuildException("Unable to generate dependency-check report", ex); @@ -568,6 +598,47 @@ public class DependencyCheckTask extends Task { } } + /** + * Generates a warning message listing a summary of dependencies and their + * associated CPE and CVE entries. + * + * @param dependencies a list of dependency objects + */ + private void showSummary(List dependencies) { + final StringBuilder summary = new StringBuilder(); + for (Dependency d : dependencies) { + boolean firstEntry = true; + final StringBuilder ids = new StringBuilder(); + for (Vulnerability v : d.getVulnerabilities()) { + if (firstEntry) { + firstEntry = false; + } else { + ids.append(", "); + } + ids.append(v.getName()); + } + if (ids.length() > 0) { + summary.append(d.getFileName()).append(" ("); + firstEntry = true; + for (Identifier id : d.getIdentifiers()) { + if (firstEntry) { + firstEntry = false; + } else { + summary.append(", "); + } + summary.append(id.getValue()); + } + summary.append(") : ").append(ids).append(NEW_LINE); + } + } + 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()); + Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.WARNING, msg); + } + } + /** * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", * etc.. diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/DependencyCheckMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/DependencyCheckMojo.java index b1cd1ec56..709b3ea1b 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/DependencyCheckMojo.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/DependencyCheckMojo.java @@ -79,6 +79,10 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR * The name of the test scope. */ public static final String TEST_SCOPE = "test"; + /** + * System specific new line character. + */ + private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); // /** * The Maven Project Object. @@ -151,39 +155,45 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR /** * The Proxy URL. */ - @SuppressWarnings("CanBeFinal") + @SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"}) @Parameter(property = "proxyUrl", defaultValue = "", required = false) private String proxyUrl = null; /** * The Proxy Port. */ - @SuppressWarnings("CanBeFinal") + @SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"}) @Parameter(property = "proxyPort", defaultValue = "", required = false) private String proxyPort = null; /** * The Proxy username. */ - @SuppressWarnings("CanBeFinal") + @SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"}) @Parameter(property = "proxyUsername", defaultValue = "", required = false) private String proxyUsername = null; /** * The Proxy password. */ - @SuppressWarnings("CanBeFinal") + @SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"}) @Parameter(property = "proxyPassword", defaultValue = "", required = false) private String proxyPassword = null; /** * The Connection Timeout. */ - @SuppressWarnings("CanBeFinal") + @SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"}) @Parameter(property = "connectionTimeout", defaultValue = "", required = false) private String connectionTimeout = null; /** * The Connection Timeout. */ - @SuppressWarnings("CanBeFinal") + @SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"}) @Parameter(property = "suppressionFile", defaultValue = "", required = false) private String suppressionFile = null; + /** + * Flag indicating whether or not to show a summary in the output. + */ + @SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"}) + @Parameter(property = "showSummary", defaultValue = "true", required = false) + private boolean showSummary = true; // /** @@ -670,6 +680,9 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR if (this.failBuildOnCVSS <= 10) { checkForFailure(engine.getDependencies()); } + if (this.showSummary) { + showSummary(engine.getDependencies()); + } } /** @@ -802,4 +815,45 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR throw new MojoFailureException(msg); } } + + /** + * Generates a warning message listing a summary of dependencies and their + * associated CPE and CVE entries. + * + * @param dependencies a list of dependency objects + */ + private void showSummary(List dependencies) { + final StringBuilder summary = new StringBuilder(); + for (Dependency d : dependencies) { + boolean firstEntry = true; + final StringBuilder ids = new StringBuilder(); + for (Vulnerability v : d.getVulnerabilities()) { + if (firstEntry) { + firstEntry = false; + } else { + ids.append(", "); + } + ids.append(v.getName()); + } + if (ids.length() > 0) { + summary.append(d.getFileName()).append(" ("); + firstEntry = true; + for (Identifier id : d.getIdentifiers()) { + if (firstEntry) { + firstEntry = false; + } else { + summary.append(", "); + } + summary.append(id.getValue()); + } + summary.append(") : ").append(ids).append(NEW_LINE); + } + } + 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()); + Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.WARNING, msg); + } + } }