From fe19c97d8630e1d77e0e259c5b2ba58117d4e37e Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Tue, 5 Aug 2014 18:45:25 -0400 Subject: [PATCH 01/39] corrected link syntax Former-commit-id: 01b9ea03864248a9c5427af6d7238c435c0a4fa7 --- src/site/markdown/index.md | 4 ++-- src/site/markdown/internals.md | 6 ++++-- src/site/markdown/thereport.md | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index b0acd8f8a..72a7b2793 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -14,8 +14,8 @@ libraries in our applications that contain well known published vulnerabilities More information about dependency-check can be found here: -* (How does dependency-check work)[internals.html] -* (How to read the report)[thereport.html] +* [How does dependency-check work](./internals.html) +* [How to read the report](./thereport.html) **IMPORTANT NOTE**: Dependency-check automatically updates itself using the NVD Data Feeds hosted by NIST. **The initial download of the data may take fifteen minutes diff --git a/src/site/markdown/internals.md b/src/site/markdown/internals.md index 3eeeb7086..35433a5e5 100644 --- a/src/site/markdown/internals.md +++ b/src/site/markdown/internals.md @@ -5,7 +5,9 @@ is called Evidence; there are three types of evidence collected: vendor, product JarAnalyzer will collect information from the Manifest, pom.xml, and the package names within the JAR files scanned and it has heuristics to place the information from the various sources into one or more buckets of evidence. -Within the NVD CVE Data (schema can be found [here](http://nvd.nist.gov/schema/nvd-cve-feed_2.0.xsd)) each CVE Entry has a list of vulnerable software: +Within the NVD CVE Data (schema can be found [here](http://nvd.nist.gov/schema/nvd-cve-feed_2.0.xsd)) each CVE Entry has +a list of vulnerable software: + ```xml ... @@ -26,7 +28,7 @@ level that is equal to the lowest level confidence level of evidence used during evidence was used in determining the CPE then the CPE would have a highest confidence level. Because of the way dependency-check works both false positives and false negatives may exist. Please read -(How to read the report)[thereport.html] to get a better understanding of sorting through the false positives and false +[How to read the report](thereport.html) to get a better understanding of sorting through the false positives and false negatives. Dependency-check does not currently use file hashes for identification. If the dependency was built from source the hash diff --git a/src/site/markdown/thereport.md b/src/site/markdown/thereport.md index ab3c31525..21995f8e4 100644 --- a/src/site/markdown/thereport.md +++ b/src/site/markdown/thereport.md @@ -3,8 +3,8 @@ How To Read The Report There is a lot of information contained in the HTML version of the report. When analyzing the results, the first thing one should do is determine if the CPE looks appropriate. Due to the way dependency-check works (see above) the report may contain false positives; these false positives are primarily on the CPE values. If the CPE value is wrong, this is usually obvious and one should use the suppression feature in the report to generate a suppression XML file that can be used on future scans. In addition -to just looking at the CPE values in comparison to the name of the dependency - one may also consider the confidence of the CPE (as discussed in (How does dependency-check -work)[internals.html]). See the (Suppression False Positives)[suppression.html] page for more information on how to generate and use the suppression file. +to just looking at the CPE values in comparison to the name of the dependency - one may also consider the confidence of the CPE (as discussed in [How does dependency-check +work](./internals.html)). See the [Suppressing False Positives](./suppression.html) page for more information on how to generate and use the suppression file. Once you have weeded out any obvious false positives one can then look at the remaining entries and determine if any of the identified CVE entries are actually exploitable in your environment. Determining if a CVE is exploitable in your environment can be tricky - for this I do not currently have any tips other then From f2272730ac59ee83984c6879b3a848c69e4d88e0 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Tue, 5 Aug 2014 18:45:36 -0400 Subject: [PATCH 02/39] version 1.2.4 Former-commit-id: 4de7e508eb1885bb72e866960fa5402f72bf8e49 --- dependency-check-ant/pom.xml | 2 +- dependency-check-cli/pom.xml | 2 +- dependency-check-core/pom.xml | 2 +- dependency-check-jenkins/pom.xml | 2 +- dependency-check-maven/pom.xml | 2 +- dependency-check-utils/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dependency-check-ant/pom.xml b/dependency-check-ant/pom.xml index 12d183bb0..f46d76c4d 100644 --- a/dependency-check-ant/pom.xml +++ b/dependency-check-ant/pom.xml @@ -21,7 +21,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.2.4-SNAPSHOT + 1.2.4 dependency-check-ant diff --git a/dependency-check-cli/pom.xml b/dependency-check-cli/pom.xml index 8af381366..8946f23ad 100644 --- a/dependency-check-cli/pom.xml +++ b/dependency-check-cli/pom.xml @@ -21,7 +21,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.2.4-SNAPSHOT + 1.2.4 dependency-check-cli diff --git a/dependency-check-core/pom.xml b/dependency-check-core/pom.xml index e760639d4..291e8a39e 100644 --- a/dependency-check-core/pom.xml +++ b/dependency-check-core/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.2.4-SNAPSHOT + 1.2.4 dependency-check-core diff --git a/dependency-check-jenkins/pom.xml b/dependency-check-jenkins/pom.xml index 5966fe386..38cc8fe9b 100644 --- a/dependency-check-jenkins/pom.xml +++ b/dependency-check-jenkins/pom.xml @@ -3,7 +3,7 @@ org.owasp dependency-check-parent - 1.2.4-SNAPSHOT + 1.2.4 org.owasp dependency-check-jenkins diff --git a/dependency-check-maven/pom.xml b/dependency-check-maven/pom.xml index de3d15b16..73ff7b502 100644 --- a/dependency-check-maven/pom.xml +++ b/dependency-check-maven/pom.xml @@ -22,7 +22,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.2.4-SNAPSHOT + 1.2.4 dependency-check-maven diff --git a/dependency-check-utils/pom.xml b/dependency-check-utils/pom.xml index 1200559cf..f37149918 100644 --- a/dependency-check-utils/pom.xml +++ b/dependency-check-utils/pom.xml @@ -21,7 +21,7 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.2.4-SNAPSHOT + 1.2.4 dependency-check-utils diff --git a/pom.xml b/pom.xml index e1b968423..bd728030b 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long org.owasp dependency-check-parent - 1.2.4-SNAPSHOT + 1.2.4 pom From d3bff2f39d3b2f6b1bcfa874ebb0396806357fb5 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Tue, 5 Aug 2014 18:55:30 -0400 Subject: [PATCH 03/39] version 1.2.5-SNAPSHOT Former-commit-id: 85ed1238022348f1e9496ffe3c95d4ff8e3d09c3 --- dependency-check-ant/pom.xml | 2 +- dependency-check-cli/pom.xml | 2 +- dependency-check-core/pom.xml | 2 +- dependency-check-jenkins/pom.xml | 2 +- dependency-check-maven/pom.xml | 2 +- dependency-check-utils/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dependency-check-ant/pom.xml b/dependency-check-ant/pom.xml index f46d76c4d..2e40f5da4 100644 --- a/dependency-check-ant/pom.xml +++ b/dependency-check-ant/pom.xml @@ -21,7 +21,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.2.4 + 1.2.5-SNAPSHOT dependency-check-ant diff --git a/dependency-check-cli/pom.xml b/dependency-check-cli/pom.xml index 8946f23ad..fd6ee5220 100644 --- a/dependency-check-cli/pom.xml +++ b/dependency-check-cli/pom.xml @@ -21,7 +21,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.2.4 + 1.2.5-SNAPSHOT dependency-check-cli diff --git a/dependency-check-core/pom.xml b/dependency-check-core/pom.xml index 291e8a39e..fcb406e6b 100644 --- a/dependency-check-core/pom.xml +++ b/dependency-check-core/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.2.4 + 1.2.5-SNAPSHOT dependency-check-core diff --git a/dependency-check-jenkins/pom.xml b/dependency-check-jenkins/pom.xml index 38cc8fe9b..321e4e6cf 100644 --- a/dependency-check-jenkins/pom.xml +++ b/dependency-check-jenkins/pom.xml @@ -3,7 +3,7 @@ org.owasp dependency-check-parent - 1.2.4 + 1.2.5-SNAPSHOT org.owasp dependency-check-jenkins diff --git a/dependency-check-maven/pom.xml b/dependency-check-maven/pom.xml index 73ff7b502..b740c4811 100644 --- a/dependency-check-maven/pom.xml +++ b/dependency-check-maven/pom.xml @@ -22,7 +22,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.2.4 + 1.2.5-SNAPSHOT dependency-check-maven diff --git a/dependency-check-utils/pom.xml b/dependency-check-utils/pom.xml index f37149918..a71065a60 100644 --- a/dependency-check-utils/pom.xml +++ b/dependency-check-utils/pom.xml @@ -21,7 +21,7 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.2.4 + 1.2.5-SNAPSHOT dependency-check-utils diff --git a/pom.xml b/pom.xml index bd728030b..e060b3e28 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long org.owasp dependency-check-parent - 1.2.4 + 1.2.5-SNAPSHOT pom From 3ce85d8ca943b7631888bfe2cf62db44272f866b Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 8 Aug 2014 14:42:23 -0400 Subject: [PATCH 04/39] rework of report generation and added fix for proxy (patch for proxy was from Erik Wramner) to close issue #136 Former-commit-id: afc81123b31189618ade397b830bf421db2918f8 --- .../maven/DependencyCheckMojo.java | 421 +----------------- 1 file changed, 6 insertions(+), 415 deletions(-) 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 9c87a8bf3..88e277e16 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 @@ -20,10 +20,6 @@ package org.owasp.dependencycheck.maven; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.text.DateFormat; -import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Set; @@ -46,16 +42,10 @@ import org.apache.maven.reporting.MavenReport; import org.apache.maven.reporting.MavenReportException; import org.apache.maven.settings.Proxy; import org.owasp.dependencycheck.Engine; -import org.owasp.dependencycheck.data.nvdcve.CveDB; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; import org.owasp.dependencycheck.dependency.Dependency; -import org.owasp.dependencycheck.dependency.Evidence; import org.owasp.dependencycheck.dependency.Identifier; -import org.owasp.dependencycheck.dependency.Reference; import org.owasp.dependencycheck.dependency.Vulnerability; -import org.owasp.dependencycheck.dependency.VulnerableSoftware; -import org.owasp.dependencycheck.reporting.ReportGenerator; import org.owasp.dependencycheck.utils.LogUtils; import org.owasp.dependencycheck.utils.Settings; @@ -72,7 +62,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR /** * Logger field reference. */ - private final Logger logger = Logger.getLogger(DependencyCheckMojo.class.getName()); + private static final Logger logger = Logger.getLogger(DependencyCheckMojo.class.getName()); /** * The properties file location. @@ -358,408 +348,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR return engine; } - /** - * Generates the reports for a given dependency-check engine. - * - * @param engine a dependency-check engine - * @param outDirectory the directory to write the reports to - */ - private void generateExternalReports(Engine engine, File outDirectory) { - DatabaseProperties prop = null; - CveDB cve = null; - try { - cve = new CveDB(); - cve.open(); - prop = cve.getDatabaseProperties(); - } catch (DatabaseException ex) { - logger.log(Level.FINE, "Unable to retrieve DB Properties", ex); - } finally { - if (cve != null) { - cve.close(); - } - } - final ReportGenerator r = new ReportGenerator(project.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); - try { - r.generateReports(outDirectory.getCanonicalPath(), format); - } catch (IOException ex) { - logger.log(Level.SEVERE, - "Unexpected exception occurred during analysis; please see the verbose error log for more details."); - logger.log(Level.FINE, null, ex); - } catch (Throwable ex) { - logger.log(Level.SEVERE, - "Unexpected exception occurred during analysis; please see the verbose error log for more details."); - logger.log(Level.FINE, null, ex); - } - } - - /** - * Generates a dependency-check report using the Maven Site format. - * - * @param engine the engine used to scan the dependencies - * @param sink the sink to write the data to - */ - private void generateMavenSiteReport(final Engine engine, Sink sink) { - final List dependencies = engine.getDependencies(); - - writeSiteReportHeader(sink, project.getName()); - writeSiteReportTOC(sink, dependencies); - - int cnt = 0; - for (Dependency d : dependencies) { - writeSiteReportDependencyHeader(sink, d); - cnt = writeSiteReportDependencyEvidenceUsed(d, cnt, sink); - cnt = writeSiteReportDependencyRelatedDependencies(d, cnt, sink); - writeSiteReportDependencyIdentifiers(d, sink); - writeSiteReportDependencyVulnerabilities(d, sink, cnt); - } - sink.body_(); - } - - // - /** - * Writes the vulnerabilities to the site report. - * - * @param d the dependency - * @param sink the sink to write the data to - * @param collapsibleHeaderCount the collapsible header count - */ - private void writeSiteReportDependencyVulnerabilities(Dependency d, Sink sink, int collapsibleHeaderCount) { - int cnt = collapsibleHeaderCount; - if (d.getVulnerabilities() != null && !d.getVulnerabilities().isEmpty()) { - for (Vulnerability v : d.getVulnerabilities()) { - - sink.paragraph(); - sink.bold(); - try { - sink.link("http://web.nvd.nist.gov/view/vuln/detail?vulnId=" + URLEncoder.encode(v.getName(), "US-ASCII")); - sink.text(v.getName()); - sink.link_(); - sink.bold_(); - } catch (UnsupportedEncodingException ex) { - sink.text(v.getName()); - sink.bold_(); - sink.lineBreak(); - sink.text("http://web.nvd.nist.gov/view/vuln/detail?vulnId=" + v.getName()); - } - sink.paragraph_(); - sink.paragraph(); - sink.text("Severity: "); - if (v.getCvssScore() < 4.0) { - sink.text("Low"); - } else { - if (v.getCvssScore() >= 7.0) { - sink.text("High"); - } else { - sink.text("Medium"); - } - } - sink.lineBreak(); - sink.text("CVSS Score: " + v.getCvssScore()); - if (v.getCwe() != null && !v.getCwe().isEmpty()) { - sink.lineBreak(); - sink.text("CWE: "); - sink.text(v.getCwe()); - } - sink.paragraph_(); - sink.paragraph(); - sink.text(v.getDescription()); - if (v.getReferences() != null && !v.getReferences().isEmpty()) { - sink.list(); - for (Reference ref : v.getReferences()) { - sink.listItem(); - sink.text(ref.getSource()); - sink.text(" - "); - sink.link(ref.getUrl()); - sink.text(ref.getName()); - sink.link_(); - sink.listItem_(); - } - sink.list_(); - } - sink.paragraph_(); - if (v.getVulnerableSoftware() != null && !v.getVulnerableSoftware().isEmpty()) { - sink.paragraph(); - - cnt += 1; - sink.rawText("Vulnerable Software [-]"); - sink.rawText("
"); - sink.list(); - for (VulnerableSoftware vs : v.getVulnerableSoftware()) { - sink.listItem(); - try { - sink.link("http://web.nvd.nist.gov/view/vuln/search-results?cpe=" + URLEncoder.encode(vs.getName(), "US-ASCII")); - sink.text(vs.getName()); - sink.link_(); - if (vs.hasPreviousVersion()) { - sink.text(" and all previous versions."); - } - } catch (UnsupportedEncodingException ex) { - sink.text(vs.getName()); - if (vs.hasPreviousVersion()) { - sink.text(" and all previous versions."); - } - sink.text(" (http://web.nvd.nist.gov/view/vuln/search-results?cpe=" + vs.getName() + ")"); - } - - sink.listItem_(); - } - sink.list_(); - sink.rawText("
"); - sink.paragraph_(); - } - } - } - } - - /** - * Writes the identifiers to the site report. - * - * @param d the dependency - * @param sink the sink to write the data to - */ - private void writeSiteReportDependencyIdentifiers(Dependency d, Sink sink) { - if (d.getIdentifiers() != null && !d.getIdentifiers().isEmpty()) { - sink.sectionTitle4(); - sink.text("Identifiers"); - sink.sectionTitle4_(); - sink.list(); - for (Identifier i : d.getIdentifiers()) { - sink.listItem(); - sink.text(i.getType()); - sink.text(": "); - if (i.getUrl() != null && i.getUrl().length() > 0) { - sink.link(i.getUrl()); - sink.text(i.getValue()); - sink.link_(); - } else { - sink.text(i.getValue()); - } - if (i.getDescription() != null && i.getDescription().length() > 0) { - sink.lineBreak(); - sink.text(i.getDescription()); - } - sink.listItem_(); - } - sink.list_(); - } - } - - /** - * Writes the related dependencies to the site report. - * - * @param d the dependency - * @param sink the sink to write the data to - * @param collapsibleHeaderCount the collapsible header count - * @return the collapsible header count - */ - private int writeSiteReportDependencyRelatedDependencies(Dependency d, int collapsibleHeaderCount, Sink sink) { - int cnt = collapsibleHeaderCount; - if (d.getRelatedDependencies() != null && !d.getRelatedDependencies().isEmpty()) { - cnt += 1; - sink.sectionTitle4(); - sink.rawText("Related Dependencies [+]"); - sink.sectionTitle4_(); - sink.rawText("
"); - sink.list(); - for (Dependency r : d.getRelatedDependencies()) { - sink.listItem(); - sink.text(r.getFileName()); - sink.list(); - writeListItem(sink, "File Path: " + r.getFilePath()); - writeListItem(sink, "SHA1: " + r.getSha1sum()); - writeListItem(sink, "MD5: " + r.getMd5sum()); - sink.list_(); - sink.listItem_(); - } - sink.list_(); - sink.rawText("
"); - } - return cnt; - } - - /** - * Writes the evidence used to the site report. - * - * @param d the dependency - * @param sink the sink to write the data to - * @param collapsibleHeaderCount the collapsible header count - * @return the collapsible header count - */ - private int writeSiteReportDependencyEvidenceUsed(Dependency d, int collapsibleHeaderCount, Sink sink) { - int cnt = collapsibleHeaderCount; - final Set evidence = d.getEvidenceForDisplay(); - if (evidence != null && evidence.size() > 0) { - cnt += 1; - sink.sectionTitle4(); - sink.rawText("Evidence Collected [+]"); - sink.sectionTitle4_(); - sink.rawText("
"); - sink.table(); - sink.tableRow(); - writeTableHeaderCell(sink, "Source"); - writeTableHeaderCell(sink, "Name"); - writeTableHeaderCell(sink, "Value"); - sink.tableRow_(); - for (Evidence e : evidence) { - sink.tableRow(); - writeTableCell(sink, e.getSource()); - writeTableCell(sink, e.getName()); - writeTableCell(sink, e.getValue()); - sink.tableRow_(); - } - sink.table_(); - sink.rawText("
"); - } - return cnt; - } - - /** - * Writes the dependency header to the site report. - * - * @param d the dependency - * @param sink the sink to write the data to - */ - private void writeSiteReportDependencyHeader(Sink sink, Dependency d) { - sink.sectionTitle2(); - sink.anchor("sha1" + d.getSha1sum()); - sink.text(d.getFileName()); - sink.anchor_(); - sink.sectionTitle2_(); - if (d.getDescription() != null && d.getDescription().length() > 0) { - sink.paragraph(); - sink.bold(); - sink.text("Description: "); - sink.bold_(); - sink.text(d.getDescription()); - sink.paragraph_(); - } - if (d.getLicense() != null && d.getLicense().length() > 0) { - sink.paragraph(); - sink.bold(); - sink.text("License: "); - sink.bold_(); - if (d.getLicense().startsWith("http://") && !d.getLicense().contains(" ")) { - sink.link(d.getLicense()); - sink.text(d.getLicense()); - sink.link_(); - } else { - sink.text(d.getLicense()); - } - sink.paragraph_(); - } - } - - /** - * Adds a list item to the site report. - * - * @param sink the sink to write the data to - * @param text the text to write - */ - private void writeListItem(Sink sink, String text) { - sink.listItem(); - sink.text(text); - sink.listItem_(); - } - - /** - * Adds a table cell to the site report. - * - * @param sink the sink to write the data to - * @param text the text to write - */ - private void writeTableCell(Sink sink, String text) { - sink.tableCell(); - sink.text(text); - sink.tableCell_(); - } - - /** - * Adds a table header cell to the site report. - * - * @param sink the sink to write the data to - * @param text the text to write - */ - private void writeTableHeaderCell(Sink sink, String text) { - sink.tableHeaderCell(); - sink.text(text); - sink.tableHeaderCell_(); - } - - /** - * Writes the TOC for the site report. - * - * @param sink the sink to write the data to - * @param dependencies the dependencies that are being reported on - */ - private void writeSiteReportTOC(Sink sink, final List dependencies) { - sink.list(); - for (Dependency d : dependencies) { - sink.listItem(); - sink.link("#sha1" + d.getSha1sum()); - sink.text(d.getFileName()); - sink.link_(); - if (!d.getVulnerabilities().isEmpty()) { - sink.rawText(" "); - } - if (!d.getRelatedDependencies().isEmpty()) { - sink.list(); - for (Dependency r : d.getRelatedDependencies()) { - writeListItem(sink, r.getFileName()); - } - sink.list_(); - } - sink.listItem_(); - } - sink.list_(); - } - - /** - * Writes the site report header. - * - * @param sink the sink to write the data to - * @param projectName the name of the project - */ - private void writeSiteReportHeader(Sink sink, String projectName) { - sink.head(); - sink.title(); - sink.text("Dependency-Check Report: " + projectName); - sink.title_(); - sink.head_(); - sink.body(); - sink.rawText(""); - sink.section1(); - sink.sectionTitle1(); - sink.text("Project: " + projectName); - sink.sectionTitle1_(); - sink.date(); - final Date now = new Date(); - sink.text(DateFormat.getDateTimeInstance().format(now)); - sink.date_(); - sink.section1_(); - } - //
- - /** - * Returns the maven settings proxy server. - * - * @param proxy the maven proxy - * @return the proxy url - */ - private String getMavenSettingsProxyServer(Proxy proxy) { - return new StringBuilder(proxy.getProtocol()).append("://").append(proxy.getHost()).toString(); - } - /** * Returns the maven proxy. * @@ -816,14 +404,17 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR final Proxy proxy = getMavenProxy(); if (proxy != null) { - Settings.setString(Settings.KEYS.PROXY_SERVER, getMavenSettingsProxyServer(proxy)); + Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost()); Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort())); final String userName = proxy.getUsername(); final String password = proxy.getPassword(); - if (userName != null && password != null) { + if (userName != null) { Settings.setString(Settings.KEYS.PROXY_USERNAME, userName); + } + if (password != null) { Settings.setString(Settings.KEYS.PROXY_PASSWORD, password); } + } if (connectionTimeout != null && !connectionTimeout.isEmpty()) { From 814a73325888946e2456fd18d55526edb2124815 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 8 Aug 2014 14:43:00 -0400 Subject: [PATCH 05/39] moved reporting functions from the core maven plugin to a utility class Former-commit-id: 0d8507b8534320189ea5f36d0fc1cac7d0843c0f --- .../dependencycheck/maven/ReportingUtil.java | 437 ++++++++++++++++++ 1 file changed, 437 insertions(+) create mode 100644 dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportingUtil.java diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportingUtil.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportingUtil.java new file mode 100644 index 000000000..06e7e99f0 --- /dev/null +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportingUtil.java @@ -0,0 +1,437 @@ +package org.owasp.dependencycheck.maven; + + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.text.DateFormat; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.maven.doxia.sink.Sink; +import org.owasp.dependencycheck.Engine; +import org.owasp.dependencycheck.data.nvdcve.CveDB; +import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +import org.owasp.dependencycheck.dependency.Dependency; +import org.owasp.dependencycheck.dependency.Evidence; +import org.owasp.dependencycheck.dependency.Identifier; +import org.owasp.dependencycheck.dependency.Reference; +import org.owasp.dependencycheck.dependency.Vulnerability; +import org.owasp.dependencycheck.dependency.VulnerableSoftware; +import org.owasp.dependencycheck.reporting.ReportGenerator; + +/** + * A utility class that encapsulates the report generation for dependency-check-maven. + * + * @author Jeremy Long + */ +final class ReportingUtil { + + /** + * Logger field reference. + */ + private static final Logger logger = Logger.getLogger(ReportingUtil.class.getName()); + + /** + * Empty private constructor for this utility class. + */ + private ReportingUtil() { + } + + /** + * Generates the reports for a given dependency-check engine. + * + * @param engine a dependency-check engine + * @param outDirectory the directory to write the reports to + */ + static void generateExternalReports(Engine engine, File outDirectory, String projectName, String format) { + DatabaseProperties prop = null; + CveDB cve = null; + try { + cve = new CveDB(); + cve.open(); + prop = cve.getDatabaseProperties(); + } catch (DatabaseException ex) { + logger.log(Level.FINE, "Unable to retrieve DB Properties", ex); + } finally { + if (cve != null) { + cve.close(); + } + } + final ReportGenerator r = new ReportGenerator(projectName, engine.getDependencies(), engine.getAnalyzers(), prop); + try { + r.generateReports(outDirectory.getCanonicalPath(), format); + } catch (IOException ex) { + logger.log(Level.SEVERE, + "Unexpected exception occurred during analysis; please see the verbose error log for more details."); + logger.log(Level.FINE, null, ex); + } catch (Throwable ex) { + logger.log(Level.SEVERE, + "Unexpected exception occurred during analysis; please see the verbose error log for more details."); + logger.log(Level.FINE, null, ex); + } + } + + /** + * Generates a dependency-check report using the Maven Site format. + * + * @param engine the engine used to scan the dependencies + * @param sink the sink to write the data to + */ + static void generateMavenSiteReport(final Engine engine, Sink sink, String projectName) { + final List dependencies = engine.getDependencies(); + + writeSiteReportHeader(sink, projectName); + writeSiteReportTOC(sink, dependencies); + + int cnt = 0; + for (Dependency d : dependencies) { + writeSiteReportDependencyHeader(sink, d); + cnt = writeSiteReportDependencyEvidenceUsed(d, cnt, sink); + cnt = writeSiteReportDependencyRelatedDependencies(d, cnt, sink); + writeSiteReportDependencyIdentifiers(d, sink); + writeSiteReportDependencyVulnerabilities(d, sink, cnt); + } + sink.body_(); + } + + // + /** + * Writes the vulnerabilities to the site report. + * + * @param d the dependency + * @param sink the sink to write the data to + * @param collapsibleHeaderCount the collapsible header count + */ + private static void writeSiteReportDependencyVulnerabilities(Dependency d, Sink sink, int collapsibleHeaderCount) { + int cnt = collapsibleHeaderCount; + if (d.getVulnerabilities() != null && !d.getVulnerabilities().isEmpty()) { + for (Vulnerability v : d.getVulnerabilities()) { + + sink.paragraph(); + sink.bold(); + try { + sink.link("http://web.nvd.nist.gov/view/vuln/detail?vulnId=" + URLEncoder.encode(v.getName(), "US-ASCII")); + sink.text(v.getName()); + sink.link_(); + sink.bold_(); + } catch (UnsupportedEncodingException ex) { + sink.text(v.getName()); + sink.bold_(); + sink.lineBreak(); + sink.text("http://web.nvd.nist.gov/view/vuln/detail?vulnId=" + v.getName()); + } + sink.paragraph_(); + sink.paragraph(); + sink.text("Severity: "); + if (v.getCvssScore() < 4.0) { + sink.text("Low"); + } else { + if (v.getCvssScore() >= 7.0) { + sink.text("High"); + } else { + sink.text("Medium"); + } + } + sink.lineBreak(); + sink.text("CVSS Score: " + v.getCvssScore()); + if (v.getCwe() != null && !v.getCwe().isEmpty()) { + sink.lineBreak(); + sink.text("CWE: "); + sink.text(v.getCwe()); + } + sink.paragraph_(); + sink.paragraph(); + sink.text(v.getDescription()); + if (v.getReferences() != null && !v.getReferences().isEmpty()) { + sink.list(); + for (Reference ref : v.getReferences()) { + sink.listItem(); + sink.text(ref.getSource()); + sink.text(" - "); + sink.link(ref.getUrl()); + sink.text(ref.getName()); + sink.link_(); + sink.listItem_(); + } + sink.list_(); + } + sink.paragraph_(); + if (v.getVulnerableSoftware() != null && !v.getVulnerableSoftware().isEmpty()) { + sink.paragraph(); + + cnt += 1; + sink.rawText("Vulnerable Software [-]"); + sink.rawText("
"); + sink.list(); + for (VulnerableSoftware vs : v.getVulnerableSoftware()) { + sink.listItem(); + try { + sink.link("http://web.nvd.nist.gov/view/vuln/search-results?cpe=" + URLEncoder.encode(vs.getName(), "US-ASCII")); + sink.text(vs.getName()); + sink.link_(); + if (vs.hasPreviousVersion()) { + sink.text(" and all previous versions."); + } + } catch (UnsupportedEncodingException ex) { + sink.text(vs.getName()); + if (vs.hasPreviousVersion()) { + sink.text(" and all previous versions."); + } + sink.text(" (http://web.nvd.nist.gov/view/vuln/search-results?cpe=" + vs.getName() + ")"); + } + + sink.listItem_(); + } + sink.list_(); + sink.rawText("
"); + sink.paragraph_(); + } + } + } + } + + /** + * Writes the identifiers to the site report. + * + * @param d the dependency + * @param sink the sink to write the data to + */ + private static void writeSiteReportDependencyIdentifiers(Dependency d, Sink sink) { + if (d.getIdentifiers() != null && !d.getIdentifiers().isEmpty()) { + sink.sectionTitle4(); + sink.text("Identifiers"); + sink.sectionTitle4_(); + sink.list(); + for (Identifier i : d.getIdentifiers()) { + sink.listItem(); + sink.text(i.getType()); + sink.text(": "); + if (i.getUrl() != null && i.getUrl().length() > 0) { + sink.link(i.getUrl()); + sink.text(i.getValue()); + sink.link_(); + } else { + sink.text(i.getValue()); + } + if (i.getDescription() != null && i.getDescription().length() > 0) { + sink.lineBreak(); + sink.text(i.getDescription()); + } + sink.listItem_(); + } + sink.list_(); + } + } + + /** + * Writes the related dependencies to the site report. + * + * @param d the dependency + * @param sink the sink to write the data to + * @param collapsibleHeaderCount the collapsible header count + * @return the collapsible header count + */ + private static int writeSiteReportDependencyRelatedDependencies(Dependency d, int collapsibleHeaderCount, Sink sink) { + int cnt = collapsibleHeaderCount; + if (d.getRelatedDependencies() != null && !d.getRelatedDependencies().isEmpty()) { + cnt += 1; + sink.sectionTitle4(); + sink.rawText("Related Dependencies [+]"); + sink.sectionTitle4_(); + sink.rawText("
"); + sink.list(); + for (Dependency r : d.getRelatedDependencies()) { + sink.listItem(); + sink.text(r.getFileName()); + sink.list(); + writeListItem(sink, "File Path: " + r.getFilePath()); + writeListItem(sink, "SHA1: " + r.getSha1sum()); + writeListItem(sink, "MD5: " + r.getMd5sum()); + sink.list_(); + sink.listItem_(); + } + sink.list_(); + sink.rawText("
"); + } + return cnt; + } + + /** + * Writes the evidence used to the site report. + * + * @param d the dependency + * @param sink the sink to write the data to + * @param collapsibleHeaderCount the collapsible header count + * @return the collapsible header count + */ + private static int writeSiteReportDependencyEvidenceUsed(Dependency d, int collapsibleHeaderCount, Sink sink) { + int cnt = collapsibleHeaderCount; + final Set evidence = d.getEvidenceForDisplay(); + if (evidence != null && evidence.size() > 0) { + cnt += 1; + sink.sectionTitle4(); + sink.rawText("Evidence Collected [+]"); + sink.sectionTitle4_(); + sink.rawText("
"); + sink.table(); + sink.tableRow(); + writeTableHeaderCell(sink, "Source"); + writeTableHeaderCell(sink, "Name"); + writeTableHeaderCell(sink, "Value"); + sink.tableRow_(); + for (Evidence e : evidence) { + sink.tableRow(); + writeTableCell(sink, e.getSource()); + writeTableCell(sink, e.getName()); + writeTableCell(sink, e.getValue()); + sink.tableRow_(); + } + sink.table_(); + sink.rawText("
"); + } + return cnt; + } + + /** + * Writes the dependency header to the site report. + * + * @param d the dependency + * @param sink the sink to write the data to + */ + private static void writeSiteReportDependencyHeader(Sink sink, Dependency d) { + sink.sectionTitle2(); + sink.anchor("sha1" + d.getSha1sum()); + sink.text(d.getFileName()); + sink.anchor_(); + sink.sectionTitle2_(); + if (d.getDescription() != null && d.getDescription().length() > 0) { + sink.paragraph(); + sink.bold(); + sink.text("Description: "); + sink.bold_(); + sink.text(d.getDescription()); + sink.paragraph_(); + } + if (d.getLicense() != null && d.getLicense().length() > 0) { + sink.paragraph(); + sink.bold(); + sink.text("License: "); + sink.bold_(); + if (d.getLicense().startsWith("http://") && !d.getLicense().contains(" ")) { + sink.link(d.getLicense()); + sink.text(d.getLicense()); + sink.link_(); + } else { + sink.text(d.getLicense()); + } + sink.paragraph_(); + } + } + + /** + * Adds a list item to the site report. + * + * @param sink the sink to write the data to + * @param text the text to write + */ + private static void writeListItem(Sink sink, String text) { + sink.listItem(); + sink.text(text); + sink.listItem_(); + } + + /** + * Adds a table cell to the site report. + * + * @param sink the sink to write the data to + * @param text the text to write + */ + private static void writeTableCell(Sink sink, String text) { + sink.tableCell(); + sink.text(text); + sink.tableCell_(); + } + + /** + * Adds a table header cell to the site report. + * + * @param sink the sink to write the data to + * @param text the text to write + */ + private static void writeTableHeaderCell(Sink sink, String text) { + sink.tableHeaderCell(); + sink.text(text); + sink.tableHeaderCell_(); + } + + /** + * Writes the TOC for the site report. + * + * @param sink the sink to write the data to + * @param dependencies the dependencies that are being reported on + */ + private static void writeSiteReportTOC(Sink sink, final List dependencies) { + sink.list(); + for (Dependency d : dependencies) { + sink.listItem(); + sink.link("#sha1" + d.getSha1sum()); + sink.text(d.getFileName()); + sink.link_(); + if (!d.getVulnerabilities().isEmpty()) { + sink.rawText(" "); + } + if (!d.getRelatedDependencies().isEmpty()) { + sink.list(); + for (Dependency r : d.getRelatedDependencies()) { + writeListItem(sink, r.getFileName()); + } + sink.list_(); + } + sink.listItem_(); + } + sink.list_(); + } + + /** + * Writes the site report header. + * + * @param sink the sink to write the data to + * @param projectName the name of the project + */ + private static void writeSiteReportHeader(Sink sink, String projectName) { + sink.head(); + sink.title(); + sink.text("Dependency-Check Report: " + projectName); + sink.title_(); + sink.head_(); + sink.body(); + sink.rawText(""); + sink.section1(); + sink.sectionTitle1(); + sink.text("Project: " + projectName); + sink.sectionTitle1_(); + sink.date(); + final Date now = new Date(); + sink.text(DateFormat.getDateTimeInstance().format(now)); + sink.date_(); + sink.section1_(); + } + //
+ +} From 15858d03ff4d6901aa0de2d9d347f60070dd951b Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 8 Aug 2014 14:44:26 -0400 Subject: [PATCH 06/39] moved reporting functions from the core maven plugin to a utility class Former-commit-id: d63d2a7a5031038b9f86bbe94fc4a198374bd9f3 --- .../owasp/dependencycheck/maven/DependencyCheckMojo.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 88e277e16..b947b4617 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 @@ -485,7 +485,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) { Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); } - } /** @@ -498,7 +497,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR Engine engine = null; try { engine = executeDependencyCheck(); - generateExternalReports(engine, outputDirectory); + ReportingUtil.generateExternalReports(engine, outputDirectory, project.getName(), format); if (this.showSummary) { showSummary(engine.getDependencies()); } @@ -542,9 +541,9 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR try { engine = executeDependencyCheck(); if (this.externalReport) { - generateExternalReports(engine, reportOutputDirectory); + ReportingUtil.generateExternalReports(engine, reportOutputDirectory, project.getName(), format); } else { - generateMavenSiteReport(engine, sink); + ReportingUtil.generateMavenSiteReport(engine, sink, project.getName()); } } catch (DatabaseException ex) { logger.log(Level.SEVERE, From 6822188f52cd251a0aff8a8309b02ed90193efa3 Mon Sep 17 00:00:00 2001 From: erik-wramner Date: Sun, 10 Aug 2014 12:15:00 +0200 Subject: [PATCH 07/39] Modified Maven plugin to use proxy host as is, not as an URL. This works correctly for our proxy server with Maven 3. Former-commit-id: 02e97e359b1c5d6d9f1dc9149c9fbed510d31559 --- .../dependencycheck/maven/DependencyCheckMojo.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) 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 9c87a8bf3..0b86516bd 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 @@ -750,16 +750,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR } // - /** - * Returns the maven settings proxy server. - * - * @param proxy the maven proxy - * @return the proxy url - */ - private String getMavenSettingsProxyServer(Proxy proxy) { - return new StringBuilder(proxy.getProtocol()).append("://").append(proxy.getHost()).toString(); - } - /** * Returns the maven proxy. * @@ -816,7 +806,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR final Proxy proxy = getMavenProxy(); if (proxy != null) { - Settings.setString(Settings.KEYS.PROXY_SERVER, getMavenSettingsProxyServer(proxy)); + Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost()); Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort())); final String userName = proxy.getUsername(); final String password = proxy.getPassword(); From b4405ebf3e21417484a504da064b2c2a04f3af2b Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 15 Aug 2014 05:58:10 -0400 Subject: [PATCH 08/39] minor changes to the TOC table - removed # of related dependencies and renamed CVE Impact to Highest Severity to clear up ambiguity Former-commit-id: b8b14ab120d889057864eb6f93cadad9773b9171 --- .../src/main/resources/templates/HtmlReport.vsl | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dependency-check-core/src/main/resources/templates/HtmlReport.vsl b/dependency-check-core/src/main/resources/templates/HtmlReport.vsl index 52062ca6f..654a55622 100644 --- a/dependency-check-core/src/main/resources/templates/HtmlReport.vsl +++ b/dependency-check-core/src/main/resources/templates/HtmlReport.vsl @@ -538,19 +538,17 @@ arising out of or in connection with the use of this tool, the analysis performe - - - - - + + + + #foreach($dependency in $dependencies) #set($lnkcnt=$lnkcnt+1) - #set($mavenlink="") #set($cpeIdCount=0) #set($cpeIdConf="") From 5070fe303a88d9ad43e30a6394b3cdd4313569a6 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 15 Aug 2014 05:59:39 -0400 Subject: [PATCH 09/39] added the configuration value mavenSettingsProxyId to inform users that if you have multiple proxies defined in settings.xml you can choose which one should be used Former-commit-id: 20fa4a92d446fd30a882e07c37897907fb1638b1 --- dependency-check-maven/src/site/markdown/configuration.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dependency-check-maven/src/site/markdown/configuration.md b/dependency-check-maven/src/site/markdown/configuration.md index 672d4c774..e3f8d2bb2 100644 --- a/dependency-check-maven/src/site/markdown/configuration.md +++ b/dependency-check-maven/src/site/markdown/configuration.md @@ -57,4 +57,10 @@ databasePassword | The password used when connecting to the database. Proxy Configuration ==================== -Use [Maven's settings](https://maven.apache.org/settings.html#Proxies) to configure a proxy server. +Use [Maven's settings](https://maven.apache.org/settings.html#Proxies) to configure a proxy server. If multiple proxies +are configured in the Maven settings file you must tell dependency-check which proxy to use with the following property: + +Property | Description | Default Value +---------------------|--------------------------------------------------------------------------------------|------------------ +mavenSettingsProxyId | The id for the proxy, configured via settings.xml, that dependency-check should use. |   + From cb990b55b5e603a14146f550f440e9cf9f8529e8 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 15 Aug 2014 06:00:30 -0400 Subject: [PATCH 10/39] added the apache 2.0 license to the header Former-commit-id: f7d5558f565abe9c3e1a04f79666137e4f67e017 --- .../dependencycheck/maven/ReportingUtil.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportingUtil.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportingUtil.java index 06e7e99f0..04495db4e 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportingUtil.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportingUtil.java @@ -1,6 +1,22 @@ +/* + * 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. + */ package org.owasp.dependencycheck.maven; - import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; From 52097a6867ebbd2c51e9b5d8357bf5bb165fbc85 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 15 Aug 2014 06:02:04 -0400 Subject: [PATCH 11/39] initial version of the ReportAggregationMojo Former-commit-id: e15575413d625c6b5c5f3d73f5a739e1890eec27 --- .../maven/ReportAggregationMojo.java | 340 ++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java new file mode 100644 index 000000000..6da3dc6c1 --- /dev/null +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java @@ -0,0 +1,340 @@ +/* + * 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. + */ +package org.owasp.dependencycheck.maven; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.logging.Logger; +import org.apache.maven.doxia.sink.Sink; +import org.apache.maven.doxia.sink.SinkFactory; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.apache.maven.reporting.MavenMultiPageReport; +import org.apache.maven.reporting.MavenReportException; + +/** + *

+ * This is an abstract reporting mojo that enables report aggregation. Some of the code in the this class was copied + * from the CoberturaReportMojo (http://mojo.codehaus.org/cobertura-maven-plugin/, version 2.6). The authors of the + * CoberturaReportMojo were Will Gwaltney and + * Joakim Erdfelt. There working example of how to do report aggregation was + * invaluable.

+ *

+ * An important point about using this abstract class is that it is intended for one to write some form of serialized + * data (via the {@link org.owasp.dependencycheck.maven.ReportAggregationMojo#writeDataFile() }; note that the + * writeDataFile() function is called automatically after either {@link org.owasp.dependencycheck.maven.ReportAggregationMojo#executeNonAggregateReport(org.apache.maven.doxia.sink.Sink, + * org.apache.maven.doxia.sink.SinkFactory, java.util.Locale) + * } or {@link org.owasp.dependencycheck.maven.ReportAggregationMojo#executeAggregateReport(org.apache.maven.doxia.sink.Sink, + * org.apache.maven.doxia.sink.SinkFactory, java.util.Locale) + * } are called. When executeAggregateReport() is implemented, one can call {@link org.owasp.dependencycheck.maven.ReportAggregationMojo#getChildDataFiles() + * } to obtain a list of the data files to aggregate.

+ * + * + * @author Jeremy Long + */ +public abstract class ReportAggregationMojo extends AbstractMojo implements MavenMultiPageReport { + + /** + * The Maven Project Object. + */ + @Component + private MavenProject project; + + /** + * Logger field reference. + */ + private static final Logger logger = Logger.getLogger(ReportAggregationMojo.class.getName()); + + /** + * List of Maven project of the current build + */ + @Parameter(readonly = true, required = true, property = "reactorProjects") + private List reactorProjects; + + /** + * Generate aggregate reports in multi-module projects. + */ + @Parameter(property = "aggregate", defaultValue = "false") + private boolean aggregate; + + private Map< MavenProject, List< MavenProject>> projectChildren; + + protected void preExecute() throws MojoExecutionException, MojoFailureException { + if (this.canGenerateAggregateReport()) { + buildAggregateInfo(); + } + } + + protected abstract void performExecute() throws MojoExecutionException, MojoFailureException; + + protected void postExecute() throws MojoExecutionException, MojoFailureException { + writeDataFile(); + } + + public final void execute() throws MojoExecutionException, MojoFailureException { + try { + preExecute(); + performExecute(); + } finally { + postExecute(); + } + } + + /** + * Runs prior to the site report generation. + * + * @throws MavenReportException if a maven report exception occurs + */ + protected void preGenerate() throws MavenReportException { + if (canGenerateAggregateReport()) { + buildAggregateInfo(); + } + } + + /** + * Executes after the site report has been generated. + * + * @throws MavenReportException if a maven report exception occurs + */ + protected void postGenerate() throws MavenReportException { + writeDataFile(); + } + + /** + * Generates the non aggregate report. + * + * @param sink the sink to write the report to + * @param sinkFactory the sink factory + * @param locale the locale to use when generating the report + * @throws MavenReportException if a maven report exception occurs + */ + protected abstract void executeNonAggregateReport(Sink sink, SinkFactory sinkFactory, Locale locale) throws MavenReportException; + + /** + * Generates the aggregate Site Report. + * + * @param sink the sink to write the report to + * @param sinkFactory the sink factory + * @param locale the locale to use when generating the report + * @throws MavenReportException if a maven report exception occurs + */ + protected abstract void executeAggregateReport(Sink sink, SinkFactory sinkFactory, Locale locale) throws MavenReportException; + + /** + * Generates the Dependency-Check Site Report. + * + * @param sink the sink to write the report to + * @param locale the locale to use when generating the report + * @throws MavenReportException if a maven report exception occurs + */ + public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException { + generate((Sink) sink, null, locale); + } + + /** + * Generates the Dependency-Check Site Report. + * + * @param sink the sink to write the report to + * @param sinkFactory the sink factory + * @param locale the locale to use when generating the report + * @throws MavenReportException if a maven report exception occurs + */ + public final void generate(Sink sink, SinkFactory sinkFactory, Locale locale) throws MavenReportException { + try { + preGenerate(); + if (canGenerateNonAggregateReport()) { + executeNonAggregateReport(sink, sinkFactory, locale); + } + + if (canGenerateAggregateReport()) { + executeAggregateReport(sink, sinkFactory, locale); + } + } finally { + postGenerate(); + } + } + + /** + * Returns whether or not the mojo can generate a non-aggregate report for this project. + * + * @return true if a non-aggregate report can be generated, otherwise false + */ + protected abstract boolean canGenerateNonAggregateReport(); + + /** + * Returns whether or not we can generate any aggregate reports at this time. + * + * @return true if an aggregate report can be generated, otherwise false + */ + protected abstract boolean canGenerateAggregateReport(); + + /** + * Returns the data file's names. + * + * @return the data file's name + */ + protected abstract String getDataFileName(); + + /** + * Writes the data file to disk in the target directory. + * + */ + protected abstract void writeDataFile(); + + /** + * Collects the information needed for building aggregate reports. + */ + private void buildAggregateInfo() { + if (projectChildren != null) { + // already did this work + return; + } + logger.warning("building aggregate info"); + boolean test = reactorProjects == null; + logger.warning("Reactor is " + test); + + // build parent-child map + projectChildren = new HashMap>(); + for (MavenProject proj : reactorProjects) { + List depList = projectChildren.get(proj.getParent()); + if (depList == null) { + depList = new ArrayList(); + projectChildren.put(proj.getParent(), depList); + } + depList.add(proj); + } + } + + /** + * Returns a list containing all the recursive, non-pom children of the given project, never null. + * + * @return a list of child projects + */ + protected List getAllChildren() { + return getAllChildren(project); + } + + /** + * Returns a list containing all the recursive, non-pom children of the given project, never null. + * + * @param parentProject the parent project to collect the child project references + * @return a list of child projects + */ + private List getAllChildren(MavenProject parentProject) { + List children = projectChildren.get(parentProject); + if (children == null) { + return Collections.emptyList(); + } + + List result = new ArrayList(); + for (MavenProject child : children) { + if (isMultiModule(child)) { + result.addAll(getAllChildren(child)); + } else { + result.add(child); + } + } + return result; + } + + /** + * Returns any existing output files from the current projects children. + * + * @param projects the list of projects to obtain the output files from + * @return a list of output files + */ + protected List getChildDataFiles() { + List projects = getAllChildren(); + return getDataFiles(projects); + } + + /** + * Returns any existing output files from the given list of projects. + * + * @param projects the list of projects to obtain the output files from + * @return a list of output files + */ + protected List getDataFiles(List projects) { + List files = new ArrayList(); + for (MavenProject proj : projects) { + if (isMultiModule(proj)) { + continue; + } + File outputFile = new File(proj.getBasedir(), getDataFileName()); + if (outputFile.exists()) { + files.add(outputFile); + } else { + if (!isMultiModule(project)) { + final String msg = String.format("Unable to aggregate data for '%s' - missing data file '%s'", + proj.getName(), outputFile.getPath()); + logger.warning(msg); + } + } + } + return files; + } + + /** + * Test if the project has pom packaging + * + * @param mavenProject Project to test + * @return True if it has a pom packaging + */ + private boolean isMultiModule(MavenProject mavenProject) { + return "pom".equals(mavenProject.getPackaging()); + } + + /** + * Test if the project has pom packaging + * + * @param mavenProject Project to test + * @return True if it has a pom packaging + */ + protected boolean isMultiModule() { + return "pom".equals(project.getPackaging()); + } + + /** + * Check whether the current project is the last project in a multi-module build. If the maven build is not a + * multi-module project then this will always return true. + * + * @return true if the current project is the last project in a multi-module build; otherwise + * false + */ + protected boolean isLastProject() { + return project.equals(reactorProjects.get(reactorProjects.size() - 1)); + } + + /** + * Returns whether or not the mojo is configured to perform report aggregation. + * + * @return true if report aggregation is enabled; otherwise false + */ + public boolean isAggregate() { + return aggregate; + } +} From 78fab728e46b2a0e917c88f6ee9d8477b2e68786 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 15 Aug 2014 06:22:54 -0400 Subject: [PATCH 12/39] added an additional generate method Former-commit-id: 44b78b525da45918f3b4bc77b368f88e49361c95 --- .../maven/ReportAggregationMojo.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java index 6da3dc6c1..fff329e67 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java @@ -150,11 +150,26 @@ public abstract class ReportAggregationMojo extends AbstractMojo implements Mave * @param sink the sink to write the report to * @param locale the locale to use when generating the report * @throws MavenReportException if a maven report exception occurs + * @deprecated use {@link #generate(org.apache.maven.doxia.sink.Sink, org.apache.maven.doxia.sink.SinkFactory, java.util.Locale) instead. */ + @Deprecated public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException { generate((Sink) sink, null, locale); } + /** + * Generates the Dependency-Check Site Report. + * + * @param sink the sink to write the report to + * @param locale the locale to use when generating the report + * @throws MavenReportException if a maven report exception occurs + * @deprecated use {@link #generate(org.apache.maven.doxia.sink.Sink, org.apache.maven.doxia.sink.SinkFactory, java.util.Locale) instead. + */ + @Deprecated + public final void generate(Sink sink, Locale locale) throws MavenReportException { + generate(sink, null, locale); + } + /** * Generates the Dependency-Check Site Report. * From 4095c5da387f6b80f1111b9e28df969bd114cb63 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 16 Aug 2014 07:27:28 -0400 Subject: [PATCH 13/39] made serializable Former-commit-id: 27d8084ea981766791df05c5e9ef61dbe40ba32c --- .../main/java/org/owasp/dependencycheck/Engine.java | 11 ++++++----- .../owasp/dependencycheck/dependency/Dependency.java | 3 ++- .../owasp/dependencycheck/dependency/Evidence.java | 4 +++- .../dependency/EvidenceCollection.java | 3 ++- .../owasp/dependencycheck/dependency/Identifier.java | 4 +++- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java index 09f12d9ba..3dfb16489 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java @@ -18,6 +18,7 @@ package org.owasp.dependencycheck; import java.io.File; +import java.io.Serializable; import java.util.ArrayList; import java.util.EnumMap; import java.util.HashSet; @@ -52,7 +53,7 @@ import org.owasp.dependencycheck.utils.Settings; * * @author Jeremy Long */ -public class Engine { +public class Engine implements Serializable { /** * The list of dependencies. @@ -61,19 +62,19 @@ public class Engine { /** * A Map of analyzers grouped by Analysis phase. */ - private final EnumMap> analyzers; + private transient final EnumMap> analyzers; /** * A Map of analyzers grouped by Analysis phase. */ - private final Set fileTypeAnalyzers; + private transient final Set fileTypeAnalyzers; /** * The ClassLoader to use when dynamically loading Analyzer and Update services. */ - private ClassLoader serviceClassLoader; + private transient ClassLoader serviceClassLoader; /** * The Logger for use throughout the class. */ - private static final Logger LOGGER = Logger.getLogger(Engine.class.getName()); + private transient static final Logger LOGGER = Logger.getLogger(Engine.class.getName()); /** * Creates a new Engine. diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java index 08ddd9819..9ce32d38d 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java @@ -19,6 +19,7 @@ package org.owasp.dependencycheck.dependency; import java.io.File; import java.io.IOException; +import java.io.Serializable; import java.security.NoSuchAlgorithmException; import java.util.Set; import java.util.SortedSet; @@ -35,7 +36,7 @@ import org.owasp.dependencycheck.utils.FileUtils; * * @author Jeremy Long */ -public class Dependency implements Comparable { +public class Dependency implements Serializable, Comparable { /** * The logger. diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Evidence.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Evidence.java index 6b8ad8bd6..594ffb613 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Evidence.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Evidence.java @@ -17,12 +17,14 @@ */ package org.owasp.dependencycheck.dependency; +import java.io.Serializable; + /** * Evidence is a piece of information about a Dependency. * * @author Jeremy Long */ -public class Evidence implements Comparable { +public class Evidence implements Serializable, Comparable { /** * Creates a new Evidence object. diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/EvidenceCollection.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/EvidenceCollection.java index 141370ab1..eae3f9750 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/EvidenceCollection.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/EvidenceCollection.java @@ -17,6 +17,7 @@ */ package org.owasp.dependencycheck.dependency; +import java.io.Serializable; import java.net.MalformedURLException; import java.util.HashSet; import java.util.Iterator; @@ -36,7 +37,7 @@ import org.owasp.dependencycheck.utils.UrlStringUtils; * * @author Jeremy Long */ -public class EvidenceCollection implements Iterable { +public class EvidenceCollection implements Serializable, Iterable { /** * The logger. diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Identifier.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Identifier.java index 6e44ec613..3f64b2faa 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Identifier.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Identifier.java @@ -17,11 +17,13 @@ */ package org.owasp.dependencycheck.dependency; +import java.io.Serializable; + /** * * @author Jeremy Long */ -public class Identifier implements Comparable { +public class Identifier implements Serializable, Comparable { /** * Constructs a new Identifier with the specified data. From abdb3d17f9115d55b89cc4fd3cebceaa9d857d40 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 16 Aug 2014 07:29:35 -0400 Subject: [PATCH 14/39] added initial plumbing to support report aggregation per issue #19 - report aggregation is still not complete Former-commit-id: df248d0c1a7f3628653717029f034a46afde742b --- .../maven/DependencyCheckMojo.java | 128 ++++++++++++------ 1 file changed, 85 insertions(+), 43 deletions(-) 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 b947b4617..be970e3d2 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 @@ -17,9 +17,14 @@ */ package org.owasp.dependencycheck.maven; +import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.io.OutputStream; import java.util.List; import java.util.Locale; import java.util.Set; @@ -28,7 +33,6 @@ import java.util.logging.Logger; import org.apache.maven.artifact.Artifact; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.doxia.sink.SinkFactory; -import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; @@ -37,7 +41,6 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; -import org.apache.maven.reporting.MavenMultiPageReport; import org.apache.maven.reporting.MavenReport; import org.apache.maven.reporting.MavenReportException; import org.apache.maven.settings.Proxy; @@ -57,7 +60,7 @@ import org.owasp.dependencycheck.utils.Settings; @Mojo(name = "check", defaultPhase = LifecyclePhase.COMPILE, threadSafe = true, requiresDependencyResolution = ResolutionScope.RUNTIME_PLUS_SYSTEM, requiresOnline = true) -public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageReport { +public class DependencyCheckMojo extends ReportAggregationMojo { /** * Logger field reference. @@ -76,6 +79,11 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR * System specific new line character. */ private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); + /** + * The dependency-check engine used to scan the project. + */ + private Engine engine = null; + // /** * The Maven Project Object. @@ -87,18 +95,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR */ @Parameter(property = "logfile", defaultValue = "") private String logFile; - /** - * The name of the report to be displayed in the Maven Generated Reports page. - */ - @Parameter(property = "name", defaultValue = "Dependency-Check") - private String name; - /** - * The description of the Dependency-Check report to be displayed in the Maven Generated Reports page. - */ - @Parameter(property = "description", defaultValue = "A report providing details on any published " - + "vulnerabilities within project dependencies. This report is a best effort but may contain " - + "false positives and false negatives.") - private String description; /** * Specifies the destination directory for the generated Dependency-Check report. This generally maps to * "target/site". @@ -366,6 +362,8 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR } else if (proxies.size() == 1) { return proxies.get(0); } else { + logger.warning("Multiple proxy defentiions exist in the Maven settings. In the dependency-check " + + "configuration set the maveSettingsProxyId so that the correct proxy will be used."); throw new IllegalStateException("Ambiguous proxy definition"); } } @@ -493,8 +491,8 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR * @throws MojoExecutionException if a maven exception occurs * @throws MojoFailureException thrown if a CVSS score is found that is higher then the configured level */ - public void execute() throws MojoExecutionException, MojoFailureException { - Engine engine = null; + @Override + protected void performExecute() throws MojoExecutionException, MojoFailureException { try { engine = executeDependencyCheck(); ReportingUtil.generateExternalReports(engine, outputDirectory, project.getName(), format); @@ -508,24 +506,27 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR logger.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped"); logger.log(Level.FINE, "", ex); - } finally { - Settings.cleanup(true); - if (engine != null) { - engine.cleanup(); - } } } - /** - * Generates the Dependency-Check Site Report. - * - * @param sink the sink to write the report to - * @param locale the locale to use when generating the report - * @throws MavenReportException if a Maven report exception occurs - */ - public void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, - Locale locale) throws MavenReportException { - generate((Sink) sink, null, locale); + @Override + protected void postExecute() throws MojoExecutionException, MojoFailureException { + super.postExecute(); + Settings.cleanup(true); + if (engine != null) { + engine.cleanup(); + engine = null; + } + } + + @Override + protected void postGenerate() throws MavenReportException { + super.postGenerate(); + Settings.cleanup(true); + if (engine != null) { + engine.cleanup(); + engine = null; + } } /** @@ -536,9 +537,10 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR * @param locale the locale to use when generating the report * @throws MavenReportException if a maven report exception occurs */ - public void generate(Sink sink, SinkFactory sinkFactory, Locale locale) throws MavenReportException { - Engine engine = null; + @Override + protected void executeNonAggregateReport(Sink sink, SinkFactory sinkFactory, Locale locale) throws MavenReportException { try { + //TODO figure out if the serialized data is present from THIS build and use it instead? engine = executeDependencyCheck(); if (this.externalReport) { ReportingUtil.generateExternalReports(engine, reportOutputDirectory, project.getName(), format); @@ -549,11 +551,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR logger.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped"); logger.log(Level.FINE, "", ex); - } finally { - Settings.cleanup(true); - if (engine != null) { - engine.cleanup(); - } } } @@ -593,7 +590,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR * @return the report name */ public String getName(Locale locale) { - return name; + return "dependency-check"; } /** @@ -621,7 +618,9 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR * @return the description */ public String getDescription(Locale locale) { - return description; + return "A report providing details on any published " + + "vulnerabilities within project dependencies. This report is a best effort but may contain " + + "false positives and false negatives."; } /** @@ -636,10 +635,10 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR /** * Returns whether or not the plugin can generate a report. * - * @return true + * @return true if a report can be generated; otherwise false */ public boolean canGenerateReport() { - return true; + return canGenerateNonAggregateReport() || canGenerateAggregateReport(); } // @@ -713,4 +712,47 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR logger.log(Level.WARNING, msg); } } + + @Override + protected void executeAggregateReport(Sink sink, SinkFactory sinkFactory, Locale locale) throws MavenReportException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + protected boolean canGenerateNonAggregateReport() { + return true; + } + + @Override + protected boolean canGenerateAggregateReport() { + return isAggregate() && isLastProject(); + } + + @Override + protected String getDataFileName() { + return "dependency-check.ser"; + } + + @Override + protected void writeDataFile() { + if (engine != null) { + File file = new File(project.getBuild().getDirectory(), getDataFileName()); + try { + OutputStream os = new FileOutputStream(file); + OutputStream bos = new BufferedOutputStream(os); + ObjectOutput out = new ObjectOutputStream(bos); + try { + out.writeObject(engine); + out.flush(); + } finally { + out.close(); + } + project.setContextValue("dependency-check-path", file.getAbsolutePath()); + } 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."); + logger.log(Level.FINE, ex.getMessage(), ex); + } + } + } } From ae4cc543f6eb70f6e632ba9241604b610fafdc32 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 16 Aug 2014 07:30:34 -0400 Subject: [PATCH 15/39] corrected outputFile name to correctly use the target directory from project.getBuild().getDirectory() Former-commit-id: 7ef2ca45e502e945e7356f9c63845eb4e7b532fc --- .../org/owasp/dependencycheck/maven/ReportAggregationMojo.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java index fff329e67..83c00782a 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/ReportAggregationMojo.java @@ -299,7 +299,8 @@ public abstract class ReportAggregationMojo extends AbstractMojo implements Mave if (isMultiModule(proj)) { continue; } - File outputFile = new File(proj.getBasedir(), getDataFileName()); + //TODO can we get the path from the context? + File outputFile = new File(proj.getBuild().getDirectory(), getDataFileName()); if (outputFile.exists()) { files.add(outputFile); } else { From f1cc44dead040ddc5866000169976ff5681f0fe4 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 29 Aug 2014 05:38:40 -0400 Subject: [PATCH 16/39] removed the externalReport option Former-commit-id: 4cc3ec2638140f8320eb8946d2154dae330786b0 --- .../src/site/markdown/configuration.md | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/dependency-check-maven/src/site/markdown/configuration.md b/dependency-check-maven/src/site/markdown/configuration.md index e3f8d2bb2..efc8cfbe5 100644 --- a/dependency-check-maven/src/site/markdown/configuration.md +++ b/dependency-check-maven/src/site/markdown/configuration.md @@ -5,7 +5,6 @@ The following properties can be set on the dependency-check-maven plugin. Property | Description | Default Value ---------------------|------------------------------------|------------------ autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true -externalReport | When using as a Site plugin this parameter sets whether or not the external report format should be used. | false outputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target' failBuildOnCVSS | 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. | 11 format | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML @@ -31,7 +30,7 @@ jarAnalyzer | Sets whether Jar Analyzer will be used. nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. | true nexusUrl | Defines the Nexus URL. | https://repository.sonatype.org/service/local/ nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true -nuspecAnalyzerEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true +nuspecAnalyzerEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true assemblyAnalyzerEnabled | Sets whether or not the .NET Assembly Analyzer should be used. | true pathToMono | The path to Mono for .NET assembly analysis on non-windows systems |   @@ -40,20 +39,20 @@ Advanced Configuration The following properties can be configured in the plugin. However, they are less frequently changed. One exception may be the cvedUrl properties, which can be used to host a mirror of the NVD within an enterprise environment. -Property | Description | Default Value ----------------------|-------------------------------------------------------------------------|------------------ -cveUrl12Modified | URL for the modified CVE 1.2 | http://nvd.nist.gov/download/nvdcve-modified.xml -cveUrl20Modified | URL for the modified CVE 2.0 | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml -cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year | http://nvd.nist.gov/download/nvdcve-%d.xml -cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml -connectionTimeout | The URL Connection Timeout. |   -dataDirectory | Data directory to hold SQL CVEs contents. This should generally not be changed. |   +Property | Description | Default Value +---------------------|--------------------------------------------------------------------------|------------------ +cveUrl12Modified | URL for the modified CVE 1.2. | http://nvd.nist.gov/download/nvdcve-modified.xml +cveUrl20Modified | URL for the modified CVE 2.0. | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml +cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year. | http://nvd.nist.gov/download/nvdcve-%d.xml +cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year. | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml +connectionTimeout | Sets the URL Connection Timeout used when downloading external data. |   +dataDirectory | Sets the data directory to hold SQL CVEs contents. This should generally not be changed. |   databaseDriverName | The name of the database driver. Example: org.h2.Driver. |   databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. |   connectionString | The connection string used to connect to the database. |   databaseUser | The username used when connecting to the database. |   databasePassword | The password used when connecting to the database. |   - +metaFileName | Sets the name of the file to use for storing the metadata about the project. | dependency-check.ser Proxy Configuration ==================== From 459c2beb12248a9808e7738e1d8e1a4e886f0746 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 29 Aug 2014 05:41:31 -0400 Subject: [PATCH 17/39] noop Former-commit-id: a51d953d0c60c39d845d69d66c87db8b904382c4 --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index e060b3e28..751fefd83 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,3 @@ -
Dependency# Related CPE GAVCVE ImpactCVE CountCPE ConfidenceEvidence CountHighest SeverityCVE CountCPE ConfidenceEvidence Count
$enc.html($dependency.DisplayFileName)$dependency.getRelatedDependencies().size()