mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-01-11 22:41:00 +01:00
@@ -146,7 +146,7 @@ public class Check extends Update {
|
||||
private boolean updateOnly = false;
|
||||
|
||||
/**
|
||||
* The report format to be generated (HTML, XML, VULN, ALL). Default is
|
||||
* The report format to be generated (HTML, XML, VULN, CSV, JSON, ALL). Default is
|
||||
* HTML.
|
||||
*/
|
||||
private String reportFormat = "HTML";
|
||||
@@ -1102,7 +1102,7 @@ public class Check extends Update {
|
||||
}
|
||||
|
||||
/**
|
||||
* An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN",
|
||||
* An enumeration of supported report formats: "ALL", "HTML", "XML", "CSV", "JSON", "VULN",
|
||||
* etc..
|
||||
*/
|
||||
public static class ReportFormats extends EnumeratedAttribute {
|
||||
|
||||
@@ -36,11 +36,11 @@ cveValidForHours | Sets the number of hours to wait before checking for new
|
||||
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
|
||||
failOnError | Whether the build should fail if there is an error executing the dependency-check analysis | true
|
||||
projectName | The name of the project being scanned. | Dependency-Check
|
||||
reportFormat | 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
|
||||
reportFormat | The report format to be generated (HTML, XML, CSV, JSON, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
||||
reportOutputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target'
|
||||
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../general/suppression.html) |
|
||||
hintsFile | The file path to the XML hints file \- used to resolve [false negatives](../general/hints.html) |
|
||||
proxyServer | The Proxy Server; see the [proxy configuration](../data/proxy.html) page for more information. |
|
||||
hintsFile | The file path to the XML hints file \- used to resolve [false negatives](../general/hints.html) |
|
||||
proxyServer | The Proxy Server; see the [proxy configuration](../data/proxy.html) page for more information. |
|
||||
proxyPort | The Proxy Port. |
|
||||
proxyUsername | Defines the proxy user name. |
|
||||
proxyPassword | Defines the proxy password. |
|
||||
|
||||
@@ -120,7 +120,7 @@ public final class CliParser {
|
||||
Format.valueOf(format);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
final String msg = String.format("An invalid 'format' of '%s' was specified. "
|
||||
+ "Supported output formats are XML, JSON, HTML, VULN, or ALL", format);
|
||||
+ "Supported output formats are HTML, XML, CSV, JSON, VULN, or ALL", format);
|
||||
throw new ParseException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ Short | Argument Name | Parameter | Description | Requir
|
||||
| \-\-exclude | \<pattern\> | The path patterns to exclude from the scan \- this option can be specified multiple times. This accepts Ant style path patterns (e.g. **/exclude/**). | Optional
|
||||
| \-\-symLink | \<depth\> | The depth that symbolic links will be followed; the default is 0 meaning symbolic links will not be followed. | Optional
|
||||
\-o | \-\-out | \<path\> | The folder to write reports to. This defaults to the current directory. If the format is not set to ALL one could specify a specific file name. | Optional
|
||||
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, VULN, ALL). The default is HTML. | Required
|
||||
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, CSV, JSON, VULN, ALL). The default is HTML. | Required
|
||||
| \-\-failOnCvss | \<score\> | If the score set between 0 and 10 the exit code from dependency-check will indicate if a vulnerability with a CVSS score equal to or higher was identified. | Optional
|
||||
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
|
||||
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
|
||||
|
||||
@@ -19,7 +19,9 @@ package org.owasp.dependencycheck.reporting;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.owasp.dependencycheck.dependency.Identifier;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -94,4 +96,71 @@ public class EscapeTool {
|
||||
}
|
||||
return StringEscapeUtils.escapeJson(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats text for CSV format. This includes trimming whitespace, replace
|
||||
* line breaks with spaces, and if necessary quotes the text and/or escapes
|
||||
* contained quotes.
|
||||
*
|
||||
* @param text the text to escape and quote
|
||||
* @return the escaped and quoted text
|
||||
*/
|
||||
public String csv(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return text;
|
||||
}
|
||||
return StringEscapeUtils.escapeCsv(text.trim().replace("\n", " "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a set of Identifiers, filters them to none CPE, and formats them
|
||||
* for display in a CSV.
|
||||
*
|
||||
* @param ids the set of identifiers
|
||||
* @return the formated list of none CPE identifiers
|
||||
*/
|
||||
public String csvIdentifiers(Set<Identifier> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
boolean addComma = false;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Identifier id : ids) {
|
||||
if (!"cpe".equals(id.getType())) {
|
||||
if (addComma) {
|
||||
sb.append(", ");
|
||||
} else {
|
||||
addComma = true;
|
||||
}
|
||||
sb.append(id.getValue());
|
||||
}
|
||||
}
|
||||
return StringEscapeUtils.escapeCsv(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a set of Identifiers, filters them to just CPEs, and formats them
|
||||
* for display in a CSV.
|
||||
*
|
||||
* @param ids the set of identifiers
|
||||
* @return the formated list of CPE identifiers
|
||||
*/
|
||||
public String csvCpe(Set<Identifier> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
boolean addComma = false;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Identifier id : ids) {
|
||||
if ("cpe".equals(id.getType())) {
|
||||
if (addComma) {
|
||||
sb.append(", ");
|
||||
} else {
|
||||
addComma = true;
|
||||
}
|
||||
sb.append(id.getValue());
|
||||
}
|
||||
}
|
||||
return StringEscapeUtils.escapeCsv(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,11 @@ public class ReportGenerator {
|
||||
/**
|
||||
* Generate JSON report.
|
||||
*/
|
||||
JSON
|
||||
JSON,
|
||||
/**
|
||||
* Generate CSV report.
|
||||
*/
|
||||
CSV
|
||||
}
|
||||
/**
|
||||
* The Velocity Engine.
|
||||
@@ -191,6 +195,9 @@ public class ReportGenerator {
|
||||
if (format == Format.JSON || format == Format.ALL) {
|
||||
generateReport("JsonReport", outputStream);
|
||||
}
|
||||
if (format == Format.CSV || format == Format.ALL) {
|
||||
generateReport("CsvReport", outputStream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,6 +216,9 @@ public class ReportGenerator {
|
||||
generateReport("JsonReport", outputDir + File.separator + "dependency-check-report.json");
|
||||
pretifyJson(outputDir + File.separator + "dependency-check-report.json");
|
||||
}
|
||||
if (format == Format.CSV || format == Format.ALL) {
|
||||
generateReport("CsvReport", outputDir + File.separator + "dependency-check-report.csv");
|
||||
}
|
||||
if (format == Format.HTML || format == Format.ALL) {
|
||||
generateReport("HtmlReport", outputDir + File.separator + "dependency-check-report.html");
|
||||
}
|
||||
@@ -344,6 +354,13 @@ public class ReportGenerator {
|
||||
generateReports(outputDir, Format.JSON);
|
||||
}
|
||||
}
|
||||
if ("CSV".equalsIgnoreCase(format)) {
|
||||
if (pathToCheck.endsWith(".csv")) {
|
||||
generateReport("CsvReport", outputDir);
|
||||
} else {
|
||||
generateReports(outputDir, Format.JSON);
|
||||
}
|
||||
}
|
||||
if ("ALL".equalsIgnoreCase(format)) {
|
||||
generateReports(outputDir, Format.ALL);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#**
|
||||
This file is part of Dependency-Check.
|
||||
|
||||
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) 2017 Jeremy Long. All Rights Reserved.
|
||||
|
||||
@author Jeremy Long <jeremy.long@owasp.org>
|
||||
@version 1 *###
|
||||
"Project","ScanDate","DependencyName","DependencyPath","Description","License","Md5","Sha1","Identifiers","CPE","CVE","CWE","Vulnerability","Severity","CVSSv2"
|
||||
#macro(writeSev $score)#if($score<4.0)"Low"#elseif($score>=7.0)"High"#else"Medium"#end#end
|
||||
#foreach($dependency in $dependencies)#if($dependency.getVulnerabilities().size()>0)
|
||||
#foreach($vuln in $dependency.getVulnerabilities())
|
||||
$enc.csv($applicationName),$enc.csv($scanDate),$enc.csv($dependency.DisplayFileName),#if($dependency.FilePath)$enc.csv($dependency.FilePath)#end,#if($dependency.description)$enc.csv($dependency.description)#end,#if($dependency.license)$enc.csv($dependency.license)#end,#if($dependency.Md5sum)$enc.csv($dependency.Md5sum)#end,#if($dependency.Sha1sum)$enc.csv($dependency.Sha1sum)#end,#if($dependency.identifiers)$enc.csvIdentifiers($dependency.identifiers)#end,#if($dependency.identifiers)$enc.csvCpe($dependency.identifiers)#end,#if($vuln.name)$enc.csv($vuln.name)#end,#if($dependency.cwe)$enc.csv($vuln.cwe)#end,#if($vuln.description)$enc.csv($vuln.description)#end,#writeSev($vuln.cvssScore),$vuln.cvssScore
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2017 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.reporting;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
import org.owasp.dependencycheck.dependency.Identifier;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jerem
|
||||
*/
|
||||
public class EscapeToolTest {
|
||||
|
||||
/**
|
||||
* Test of url method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testUrl() {
|
||||
String text = null;
|
||||
EscapeTool instance = new EscapeTool();
|
||||
String expResult = null;
|
||||
String result = instance.url(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "";
|
||||
expResult = "";
|
||||
result = instance.url(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = " ";
|
||||
expResult = "+";
|
||||
result = instance.url(text);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of html method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testHtml() {
|
||||
EscapeTool instance = new EscapeTool();
|
||||
String text = null;
|
||||
String expResult = null;
|
||||
String result = instance.html(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "";
|
||||
expResult = "";
|
||||
result = instance.html(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "<div>";
|
||||
expResult = "<div>";
|
||||
result = instance.html(text);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of xml method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testXml() {
|
||||
EscapeTool instance = new EscapeTool();
|
||||
String text = null;
|
||||
String expResult = null;
|
||||
String result = instance.xml(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "";
|
||||
expResult = "";
|
||||
result = instance.xml(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "<div>";
|
||||
expResult = "<div>";
|
||||
result = instance.xml(text);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of json method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testJson() {
|
||||
String text = null;
|
||||
EscapeTool instance = new EscapeTool();
|
||||
String expResult = null;
|
||||
String result = instance.json(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "";
|
||||
expResult = "";
|
||||
result = instance.json(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "test \"quote\"\"";
|
||||
expResult = "test \\\"quote\\\"\\\"";
|
||||
result = instance.json(text);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of csv method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testCsv() {
|
||||
String text = null;
|
||||
EscapeTool instance = new EscapeTool();
|
||||
String expResult = null;
|
||||
String result = instance.csv(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "";
|
||||
expResult = "";
|
||||
result = instance.csv(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "one, two";
|
||||
expResult = "\"one, two\"";
|
||||
result = instance.csv(text);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of csvIdentifiers method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testCsvIdentifiers() {
|
||||
EscapeTool instance = new EscapeTool();
|
||||
Set<Identifier> ids = null;
|
||||
String expResult = "";
|
||||
String result = instance.csvIdentifiers(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
expResult = "";
|
||||
result = instance.csvIdentifiers(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
expResult = "";
|
||||
result = instance.csvIdentifiers(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
expResult = "somegroup:something:1.0";
|
||||
result = instance.csvIdentifiers(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
expResult = "somegroup:something:1.0";
|
||||
result = instance.csvIdentifiers(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("gav", "somegroup2:something:1.2", ""));
|
||||
expResult = "\"somegroup:something:1.0, somegroup2:something:1.2\"";
|
||||
String expResult2 = "\"somegroup2:something:1.2, somegroup:something:1.0\"";
|
||||
result = instance.csvIdentifiers(ids);
|
||||
assertTrue(expResult.equals(result) || expResult2.equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of csvCpe method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testCsvCpe() {
|
||||
EscapeTool instance = new EscapeTool();
|
||||
Set<Identifier> ids = null;
|
||||
String expResult = "";
|
||||
String result = instance.csvCpe(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
expResult = "";
|
||||
result = instance.csvCpe(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
expResult = "";
|
||||
result = instance.csvCpe(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
expResult = "cpe:/a:somegroup:something:1.0";
|
||||
result = instance.csvCpe(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
expResult = "cpe:/a:somegroup:something:1.0";
|
||||
result = instance.csvCpe(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup2:something:1.2", ""));
|
||||
expResult = "\"cpe:/a:somegroup:something:1.0, cpe:/a:somegroup2:something:1.2\"";
|
||||
String expResult2 = "\"cpe:/a:somegroup2:something:1.2, cpe:/a:somegroup:something:1.0\"";
|
||||
result = instance.csvCpe(ids);
|
||||
assertTrue(expResult.equals(result) || expResult2.equals(result));
|
||||
}
|
||||
}
|
||||
@@ -757,6 +757,10 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
return "dependency-check-report.xml#";
|
||||
} else if ("VULN".equalsIgnoreCase(this.format)) {
|
||||
return "dependency-check-vulnerability";
|
||||
} else if ("JSON".equalsIgnoreCase(this.format)) {
|
||||
return "dependency-check-report.json";
|
||||
} else if ("CSV".equalsIgnoreCase(this.format)) {
|
||||
return "dependency-check-report.csv";
|
||||
} else {
|
||||
getLog().warn("Unknown report format used during site generation.");
|
||||
return "dependency-check-report";
|
||||
|
||||
@@ -19,7 +19,7 @@ cveValidForHours | Sets the number of hours to wait before checking f
|
||||
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
|
||||
failBuildOnAnyVulnerability | Specific that if any vulnerability is identified, the build will fail. | false
|
||||
failOnError | Whether the build should fail if there is an error executing the dependency-check analysis. | true
|
||||
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
|
||||
format | The report format to be generated (HTML, XML, CSV, JSON, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
||||
name | The name of the report in the site. | dependency-check or dependency-check:aggregate
|
||||
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'
|
||||
skip | Skips the dependency-check analysis. | false
|
||||
|
||||
@@ -17,7 +17,7 @@ autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is ena
|
||||
cveValidForHours | Sets the number of hours to wait before checking for new updates from the NVD. | 4
|
||||
failOnError | Fails the build if an error occurs during the dependency-check analysis. | true
|
||||
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11; 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). | HTML
|
||||
format | The report format to be generated (HTML, XML, CSV, JSON, VULN, ALL). | HTML
|
||||
outputDirectory | The location to write the report(s). This directory will be located in the build directory. | build/reports
|
||||
skipTestGroups | When set to true (the default) all dependency groups that being with 'test' will be skipped. | true
|
||||
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../general/suppression.html) |
|
||||
|
||||
Reference in New Issue
Block a user