From dd497e5ffcf44e5b6e1378770c15f8ec187ae920 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 7 Jun 2013 15:20:38 -0400 Subject: [PATCH] added a new vulnerability report Former-commit-id: f36e328929921e4d278ee8fa5a7370d228bac299 --- .../reporting/ReportGenerator.java | 31 ++- .../dependencycheck/utils/CliParser.java | 29 +-- .../templates/VulnerabilityReport.vsl | 232 ++++++++++++++++++ 3 files changed, 269 insertions(+), 23 deletions(-) create mode 100644 src/main/resources/templates/VulnerabilityReport.vsl diff --git a/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java b/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java index d56a23588..4b551a2dc 100644 --- a/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java +++ b/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java @@ -64,7 +64,11 @@ public class ReportGenerator { /** * Generate HTML report. */ - HTML + HTML, + /** + * Generate HTML Vulnerability report. + */ + VULN } /** * The Velocity Engine. @@ -139,6 +143,9 @@ public class ReportGenerator { if (format == Format.HTML || format == Format.ALL) { generateReport("HtmlReport", outputDir + File.separator + "DependencyCheck-Report.html"); } + if (format == Format.VULN || format == Format.ALL) { + generateReport("VulnerabilityReport", outputDir + File.separator + "DependencyCheck-Vulnerability.html"); + } } /** @@ -151,14 +158,20 @@ public class ReportGenerator { * reports. */ public void generateReports(String outputDir, String outputFormat) throws IOException, Exception { - if ("XML".equalsIgnoreCase(outputFormat)) { - generateReports(outputDir, Format.XML); - } - if ("HTML".equalsIgnoreCase(outputFormat)) { - generateReports(outputDir, Format.HTML); - } - if ("ALL".equalsIgnoreCase(outputFormat)) { - generateReports(outputDir, Format.ALL); + String format = outputFormat.toUpperCase(); + if (format.matches("^(XML|HTML|VULN|ALL)$")) { + if ("XML".equalsIgnoreCase(format)) { + generateReports(outputDir, Format.XML); + } + if ("HTML".equalsIgnoreCase(format)) { + generateReports(outputDir, Format.HTML); + } + if ("VULN".equalsIgnoreCase(format)) { + generateReports(outputDir, Format.VULN); + } + if ("ALL".equalsIgnoreCase(format)) { + generateReports(outputDir, Format.ALL); + } } } diff --git a/src/main/java/org/owasp/dependencycheck/utils/CliParser.java b/src/main/java/org/owasp/dependencycheck/utils/CliParser.java index 87200eeca..43006c5aa 100644 --- a/src/main/java/org/owasp/dependencycheck/utils/CliParser.java +++ b/src/main/java/org/owasp/dependencycheck/utils/CliParser.java @@ -109,8 +109,9 @@ public final class CliParser { final String format = line.getOptionValue(ArgumentName.OUTPUT_FORMAT); if (!("ALL".equalsIgnoreCase(format) || "XML".equalsIgnoreCase(format) - || "HTML".equalsIgnoreCase(format))) { - throw new ParseException("Supported output formats are XML, HTML, or ALL"); + || "HTML".equalsIgnoreCase(format) + || "VULN".equalsIgnoreCase(format))) { + throw new ParseException("Supported output formats are XML, HTML, VULN, or ALL"); } } } @@ -157,47 +158,47 @@ public final class CliParser { @SuppressWarnings("static-access") private Options createCommandLineOptions() { final Option help = new Option(ArgumentName.HELP_SHORT, ArgumentName.HELP, false, - "print this message."); + "Print this message."); final Option deepScan = new Option(ArgumentName.PERFORM_DEEP_SCAN_SHORT, ArgumentName.PERFORM_DEEP_SCAN, false, - "extracts extra information from dependencies that may increase false positives, but also decrease false negatives."); + "Extracts extra information from dependencies that may increase false positives, but also decrease false negatives."); final Option version = new Option(ArgumentName.VERSION_SHORT, ArgumentName.VERSION, - false, "print the version information."); + false, "Print the version information."); final Option noUpdate = new Option(ArgumentName.DISABLE_AUTO_UPDATE_SHORT, ArgumentName.DISABLE_AUTO_UPDATE, - false, "disables the automatic updating of the CPE data."); + false, "Disables the automatic updating of the CPE data."); final Option appName = OptionBuilder.withArgName("name").hasArg().withLongOpt(ArgumentName.APP_NAME) - .withDescription("the name of the application being scanned.") + .withDescription("The name of the application being scanned.") .create(ArgumentName.APP_NAME_SHORT); final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ArgumentName.CONNECTION_TIMEOUT) - .withDescription("the connection timeout (in milliseconds) to use when downloading resources.") + .withDescription("The connection timeout (in milliseconds) to use when downloading resources.") .create(ArgumentName.CONNECTION_TIMEOUT_SHORT); final Option proxyUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ArgumentName.PROXY_URL) - .withDescription("the proxy url to use when downloading resources.") + .withDescription("The proxy url to use when downloading resources.") .create(ArgumentName.PROXY_URL_SHORT); final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ArgumentName.PROXY_PORT) - .withDescription("the proxy port to use when downloading resources.") + .withDescription("The proxy port to use when downloading resources.") .create(ArgumentName.PROXY_PORT_SHORT); final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.SCAN) - .withDescription("the path to scan - this option can be specified multiple times.") + .withDescription("The path to scan - this option can be specified multiple times.") .create(ArgumentName.SCAN_SHORT); final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.PROP) - .withDescription("a property file to load.") + .withDescription("A property file to load.") .create(ArgumentName.PROP_SHORT); final Option out = OptionBuilder.withArgName("folder").hasArg().withLongOpt(ArgumentName.OUT) - .withDescription("the folder to write reports to.") + .withDescription("The folder to write reports to.") .create(ArgumentName.OUT_SHORT); final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ArgumentName.OUTPUT_FORMAT) - .withDescription("the output format to write to (XML, HTML, ALL).") + .withDescription("The output format to write to (XML, HTML, VULN, ALL).") .create(ArgumentName.OUTPUT_FORMAT_SHORT); final OptionGroup og = new OptionGroup(); diff --git a/src/main/resources/templates/VulnerabilityReport.vsl b/src/main/resources/templates/VulnerabilityReport.vsl new file mode 100644 index 000000000..34b908079 --- /dev/null +++ b/src/main/resources/templates/VulnerabilityReport.vsl @@ -0,0 +1,232 @@ +#** +This file is part of Dependency-Check. + +Dependency-Check is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Dependency-Check is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Dependency-Check. If not, see http://www.gnu.org/licenses/. + +Copyright (c) 2013 Jeremy Long. All Rights Reserved. + +@author Jeremy Long (jeremy.long@owasp.org) +@version 1 +*# + + +#[[ + + + + Dependency-Check Report + + + + + + + + +
+

Vulnerability Report

+]]# +

Project: $esc.html($applicationName)

+
Report Generated On: $date

+ #set($depCount=$dependencies.size()) + #set($vulnCount=0) + + #foreach($dependency in $dependencies) + #set($depCount=$depCount+$dependency.getRelatedDependencies().size()) + #if($dependency.getVulnerabilities().size()>0) + #set($vulnCount=$vulnCount+1) + #end + #end + Dependencies Scanned: $depCount
+ Vulnerable Dependencies: $vulnCount

+

Vulnerable Dependencies

+ #set($cnt=0) + + + + + + + + + #foreach($dependency in $dependencies) + #if($dependency.getVulnerabilities().size()>0) + #foreach($vuln in $dependency.getVulnerabilities()) + + + + + #end + #end + #end + +
CVECWESeverity (CVSS)Dependency
$esc.html($vuln.name) + #if ($vuln.cwe) + $vuln.cwe + #end + + #if ($vuln.cvssScore<4.0) + Low + #elseif ($vuln.cvssScore>=7.0) + High + #else + Medium + #end + ($vuln.cvssScore) + #set($cnt=$cnt+1) + #if($dependency.getRelatedDependencies().size()>0)
+
+



This report contains data retrieved from the National Vulnerability Database.

+ +