diff --git a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java index 6c38786d4..afc2cdb86 100644 --- a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java +++ b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java @@ -346,6 +346,28 @@ public class Check extends Update { public void setSuppressionFile(String suppressionFile) { this.suppressionFile = suppressionFile; } + /** + * The path to the suppression file. + */ + private String hintsFile; + + /** + * Get the value of hintsFile. + * + * @return the value of hintsFile + */ + public String getHintsFile() { + return hintsFile; + } + + /** + * Set the value of hintsFile. + * + * @param hintsFile new value of hintsFile + */ + public void setHintsFile(String hintsFile) { + this.hintsFile = hintsFile; + } /** * flag indicating whether or not to show a summary of findings. */ @@ -904,6 +926,7 @@ public class Check extends Update { super.populateSettings(); Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); + Settings.setStringIfNotEmpty(Settings.KEYS.HINTS_FILE, hintsFile); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); diff --git a/dependency-check-ant/src/site/markdown/config-purge.md b/dependency-check-ant/src/site/markdown/config-purge.md index e7026070a..74b1bfa82 100644 --- a/dependency-check-ant/src/site/markdown/config-purge.md +++ b/dependency-check-ant/src/site/markdown/config-purge.md @@ -2,7 +2,7 @@ Configuration ==================== The dependency-check-purge task deletes the local copy of the NVD. This task should rarely be used, if ever. This is included as a convenience method in -the rare circumstance that the local H2 database because corrupt. +the rare circumstance that the local H2 database becomes corrupt. ```xml diff --git a/dependency-check-ant/src/site/markdown/configuration.md b/dependency-check-ant/src/site/markdown/configuration.md index a711cd013..41e585767 100644 --- a/dependency-check-ant/src/site/markdown/configuration.md +++ b/dependency-check-ant/src/site/markdown/configuration.md @@ -39,6 +39,7 @@ projectName | The name of the project being scanned. 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 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 add evidence [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. |   diff --git a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java index de11e4cbe..7a475f7e5 100644 --- a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java +++ b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java @@ -347,6 +347,7 @@ public class App { final String dataDirectory = cli.getDataDirectory(); final File propertiesFile = cli.getPropertiesFile(); final String suppressionFile = cli.getSuppressionFile(); + final String hintsFile = cli.getHintsFile(); final String nexusUrl = cli.getNexusUrl(); final String databaseDriverName = cli.getDatabaseDriverName(); final String databaseDriverPath = cli.getDatabaseDriverPath(); @@ -394,6 +395,7 @@ public class App { Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass); Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); + Settings.setStringIfNotEmpty(Settings.KEYS.HINTS_FILE, hintsFile); Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); //File Type Analyzer Settings diff --git a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java index df75602a1..863c58a90 100644 --- a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java +++ b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java @@ -277,6 +277,10 @@ public final class CliParser { .desc("The file path to the suppression XML file.") .build(); + final Option hintsFile = Option.builder().argName("file").hasArg().longOpt(ARGUMENT.HINTS_FILE) + .desc("The file path to the hints XML file.") + .build(); + final Option cveValidForHours = Option.builder().argName("hours").hasArg().longOpt(ARGUMENT.CVE_VALID_FOR_HOURS) .desc("The number of hours to wait before checking for new updates from the NVD.") .build(); @@ -305,6 +309,7 @@ public final class CliParser { .addOption(props) .addOption(verboseLog) .addOption(suppressionFile) + .addOption(hintsFile) .addOption(cveValidForHours) .addOption(experimentalEnabled); } @@ -962,6 +967,15 @@ public final class CliParser { return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE); } + /** + * Returns the path to the hints file. + * + * @return the path to the hints file + */ + public String getHintsFile() { + return line.getOptionValue(ARGUMENT.HINTS_FILE); + } + /** *

* Prints the manifest information to standard output.

@@ -1273,9 +1287,14 @@ public final class CliParser { */ public static final String SUPPRESSION_FILE = "suppression"; /** - * The CLI argument name for setting the location of the suppression + * The CLI argument name for setting the location of the hint * file. */ + public static final String HINTS_FILE = "hints"; + /** + * The CLI argument name for setting the number of hours to wait before + * checking for new updates from the NVD. + */ public static final String CVE_VALID_FOR_HOURS = "cveValidForHours"; /** * Disables the Jar Analyzer. diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/HintAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/HintAnalyzer.java index cb6b848a7..47bf33d92 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/HintAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/HintAnalyzer.java @@ -323,7 +323,7 @@ public class HintAnalyzer extends AbstractAnalyzer { try { org.apache.commons.io.FileUtils.copyInputStreamToFile(fromClasspath, file); } catch (IOException ex) { - throw new HintParseException("Unable to locate suppressions file in classpath", ex); + throw new HintParseException("Unable to locate hints file in classpath", ex); } } } finally { diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index e492589b9..1ab88141c 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -206,6 +206,13 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma */ @Parameter(property = "suppressionFile", defaultValue = "", required = false) private String suppressionFile; + + /** + * The path to the hints file. + */ + @Parameter(property = "hintsFile", defaultValue = "", required = false) + private String hintsFile; + /** * Flag indicating whether or not to show a summary in the output. */ @@ -848,6 +855,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); + Settings.setStringIfNotEmpty(Settings.KEYS.HINTS_FILE, hintsFile); //File Type Analyzer Settings Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); diff --git a/dependency-check-maven/src/site/markdown/configuration.md b/dependency-check-maven/src/site/markdown/configuration.md index 2707e091c..fe66a2974 100644 --- a/dependency-check-maven/src/site/markdown/configuration.md +++ b/dependency-check-maven/src/site/markdown/configuration.md @@ -26,6 +26,7 @@ skipTestScope | Skip analysis for artifacts with Test Scope skipProvidedScope | Skip analysis for artifacts with Provided Scope | false skipRuntimeScope | Skip analysis for artifacts with Runtime Scope | false 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 suppress [false negatives](../general/hints.html) |   enableExperimental | Enable the [experimental analyzers](../analyzers/index.html). If not enabled the experimental analyzers (see below) will not be loaded or used. | false Analyzer Configuration diff --git a/src/site/markdown/dependency-check-gradle/configuration.md b/src/site/markdown/dependency-check-gradle/configuration.md index 25a0c83aa..8ba9d7374 100644 --- a/src/site/markdown/dependency-check-gradle/configuration.md +++ b/src/site/markdown/dependency-check-gradle/configuration.md @@ -20,6 +20,7 @@ format | The report format to be generated (HTML, XML, VULN, ALL). 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) |   +hintsFile | The file path to the XML hints file \- used to suppress [false negatives](../general/hints.html) |   skipConfigurations | A list of configurations that will be skipped. This is mutually exclusive with the scanConfigurations property. | `[]` which means no configuration is skipped. scanConfigurations | A list of configurations that will be scanned, all other configurations are skipped. This is mutually exclusive with the skipConfigurations property. | `[]` which implicitly means all configurations get scanned. diff --git a/src/site/markdown/general/hints.md b/src/site/markdown/general/hints.md new file mode 100644 index 000000000..58bbf1abe --- /dev/null +++ b/src/site/markdown/general/hints.md @@ -0,0 +1,69 @@ +Resolving False Negatives +==================== +Due to how dependency-check identifies libraries, false negatives may occur (a CPE was NOT identified for a library). Identifying these false negatives can be accomplished using the HTML report. In the report, click on the "Display: Showing Vulnerable Dependencies (click to show all)" link. You can then browse the dependencies and review the CPEs that are there for accuracy. You can also review the dependencies where no CPE match was made. Using the CPE dictionary search manually to verify that there is a CPE to match is a good verification that a false negative has been found. If you identify a dependency that is missing a CPE you can add evidence to help identify the correct CPE. + +A possible reason for false negatives is re-naming of either the vendor or library name over time. Another case is when an artifact has missing info (manifest with no vendor). + +Dependency Check has a built in [hints](https://github.com/jeremylong/DependencyCheck/blob/master/dependency-check-core/src/main/resources/dependencycheck-base-hint.xml) file that is used in every check to help correct well known false negatives. + +A sample hints file that add a product name and possible vendors for Spring framework dependencies would look like: + +```xml + + + + + + + + + + + + + + + + + +``` +The above XML file will add the 4 evidence entries to any dependency that matches any one of the 3 givens. + +The following shows some other ways to add evidence + +```xml + + + + + + + + + + + + + + + + + + + + + + + + +``` + + +The full schema for hints files can be found here: [dependency-hint.xsd](https://github.com/jeremylong/DependencyCheck/blob/master/dependency-check-core/src/main/resources/schema/dependency-hint.1.1.xsd "Hint Schema") + +Please see the appropriate configuration option in each interfaces configuration guide: + +- [Command Line Tool](../dependency-check-cli/arguments.html) +- [Maven Plugin](../dependency-check-maven/configuration.html) +- [Ant Task](../dependency-check-ant/configuration.html) +- [Jenkins Plugin](../dependency-check-jenkins/index.html) diff --git a/src/site/site.xml b/src/site/site.xml index 41ccc5d47..f171acc09 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -80,6 +80,9 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. Suppressing False Positives + + Suppressing False Positives +