Merge pull request #619 from willowtreeapps/feature/fail-on-cvss

Adds a failOnCVSS command line option
This commit is contained in:
Jeremy Long
2016-11-22 05:50:45 -05:00
committed by GitHub
3 changed files with 105 additions and 6 deletions

View File

@@ -33,6 +33,7 @@ import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
import org.owasp.dependencycheck.dependency.Dependency;
import org.apache.tools.ant.DirectoryScanner;
import org.owasp.dependencycheck.dependency.Vulnerability;
import org.owasp.dependencycheck.reporting.ReportGenerator;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
@@ -161,8 +162,8 @@ public class App {
try {
final String[] scanFiles = cli.getScanFiles();
if (scanFiles != null) {
runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), scanFiles,
cli.getExcludeList(), cli.getSymLinkDepth());
exitCode = runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), scanFiles,
cli.getExcludeList(), cli.getSymLinkDepth(), cli.getFailOnCVSS());
} else {
LOGGER.error("No scan files configured");
}
@@ -203,6 +204,7 @@ public class App {
* @param files the files/directories to scan
* @param excludes the patterns for files/directories to exclude
* @param symLinkDepth the depth that symbolic links will be followed
* @param cvssFailScore the score to fail on if a vulnerability is found
*
* @throws InvalidScanPathException thrown if the path to scan starts with
* "//"
@@ -213,9 +215,10 @@ public class App {
* analysis; there may be multiple exceptions contained within the
* collection.
*/
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files,
String[] excludes, int symLinkDepth) throws InvalidScanPathException, DatabaseException, ExceptionCollection, ReportException {
private int runScan(String reportDirectory, String outputFormat, String applicationName, String[] files,
String[] excludes, int symLinkDepth, int cvssFailScore) throws InvalidScanPathException, DatabaseException, ExceptionCollection, ReportException {
Engine engine = null;
int retCode = 0;
try {
engine = new Engine();
final List<String> antStylePaths = new ArrayList<String>();
@@ -302,12 +305,24 @@ public class App {
if (exCol != null && exCol.getExceptions().size() > 0) {
throw exCol;
}
//Set the exit code based on whether we found a high enough vulnerability
for (Dependency dep : dependencies) {
if (dep.getVulnerabilities().size() != 0) {
for (Vulnerability vuln : dep.getVulnerabilities()) {
LOGGER.debug("VULNERABILITY FOUND " + dep.getDisplayFileName());
if (vuln.getCvssScore() > cvssFailScore)
retCode = 1;
}
}
}
return retCode;
} finally {
if (engine != null) {
engine.cleanup();
}
}
}
/**

View File

@@ -289,6 +289,10 @@ public final class CliParser {
.desc("Enables the experimental analzers.")
.build();
final Option failOnCVSS = Option.builder().hasArg().longOpt(ARGUMENT.FAIL_ON_CVSS)
.desc("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.")
.build();
//This is an option group because it can be specified more then once.
final OptionGroup og = new OptionGroup();
og.addOption(path);
@@ -311,7 +315,8 @@ public final class CliParser {
.addOption(suppressionFile)
.addOption(hintsFile)
.addOption(cveValidForHours)
.addOption(experimentalEnabled);
.addOption(experimentalEnabled)
.addOption(failOnCVSS);
}
/**
@@ -1105,6 +1110,24 @@ public final class CliParser {
return line.hasOption(ARGUMENT.EXPERIMENTAL);
}
/**
* Returns the CVSS value to fail on
*
* @return 11 if nothing is set. Otherwise it returns the int passed from the command line arg
*/
public int getFailOnCVSS() {
if(line.hasOption(ARGUMENT.FAIL_ON_CVSS)) {
String value = line.getOptionValue(ARGUMENT.FAIL_ON_CVSS);
try {
return Integer.parseInt(value);
} catch (NumberFormatException nfe) {
return 11;
}
} else {
return 11;
}
}
/**
* A collection of static final strings that represent the possible command
* line arguments.
@@ -1408,5 +1431,9 @@ public final class CliParser {
* The CLI argument to enable the experimental analyzers.
*/
private static final String EXPERIMENTAL = "enableExperimental";
/**
* The CLI argument to enable the experimental analyzers.
*/
private static final String FAIL_ON_CVSS = "failOnCVSS";
}
}

View File

@@ -115,6 +115,63 @@ public class CliParserTest {
}
/**
* Test of parse method with failOnCVSS without an argument
*
* @throws Exception thrown when an exception occurs.
*/
@Test
public void testParse_failOnCVSSNoArg() throws Exception {
String[] args = {"--failOnCVSS"};
CliParser instance = new CliParser();
try {
instance.parse(args);
} catch (ParseException ex) {
Assert.assertTrue(ex.getMessage().contains("Missing argument"));
}
Assert.assertFalse(instance.isGetVersion());
Assert.assertFalse(instance.isGetHelp());
Assert.assertFalse(instance.isRunScan());
}
/**
* Test of parse method with failOnCVSS invalid argument. It should default to 11
*
* @throws Exception thrown when an exception occurs.
*/
@Test
public void testParse_failOnCVSSInvalidArgument() throws Exception {
String[] args = {"--failOnCVSS","bad"};
CliParser instance = new CliParser();
instance.parse(args);
Assert.assertEquals("Default should be 11", 11, instance.getFailOnCVSS());
Assert.assertFalse(instance.isGetVersion());
Assert.assertFalse(instance.isGetHelp());
Assert.assertFalse(instance.isRunScan());
}
/**
* Test of parse method with failOnCVSS invalid argument. It should default to 11
*
* @throws Exception thrown when an exception occurs.
*/
@Test
public void testParse_failOnCVSSValidArgument() throws Exception {
String[] args = {"--failOnCVSS","6"};
CliParser instance = new CliParser();
instance.parse(args);
Assert.assertEquals(6, instance.getFailOnCVSS());
Assert.assertFalse(instance.isGetVersion());
Assert.assertFalse(instance.isGetHelp());
Assert.assertFalse(instance.isRunScan());
}
/**
* Test of parse method with jar and cpe args, of class CliParser.
*