From ee77fccffdb23b8d8a44a2d79d2d92bd63633418 Mon Sep 17 00:00:00 2001 From: Erik Erikson Date: Tue, 3 May 2016 10:31:00 -0700 Subject: [PATCH 01/55] Align documentation with current project name specification flag When using the "--app" flag, the following warning is produced: [WARN] The 'app' argument should no longer be used; use 'project' instead. This change updates the documentation from suggesting "--app" to "--project" --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d80df5c5f..d2f2eb4be 100644 --- a/README.md +++ b/README.md @@ -22,18 +22,18 @@ The latest CLI can be downloaded from bintray's On *nix ``` $ ./bin/dependency-check.sh -h -$ ./bin/dependency-check.sh --app Testing --out . --scan [path to jar files to be scanned] +$ ./bin/dependency-check.sh --project Testing --out . --scan [path to jar files to be scanned] ``` On Windows ``` > bin/dependency-check.bat -h -> bin/dependency-check.bat --app Testing --out . --scan [path to jar files to be scanned] +> bin/dependency-check.bat --project Testing --out . --scan [path to jar files to be scanned] ``` On Mac with [Homebrew](http://brew.sh) ``` $ brew update && brew install dependency-check $ dependency-check -h -$ dependency-check --app Testing --out . --scan [path to jar files to be scanned] +$ dependency-check --project Testing --out . --scan [path to jar files to be scanned] ``` ### Maven Plugin @@ -85,13 +85,13 @@ On *nix ``` $ mvn install $ ./dependency-check-cli/target/release/bin/dependency-check.sh -h -$ ./dependency-check-cli/target/release/bin/dependency-check.sh --app Testing --out . --scan ./src/test/resources +$ ./dependency-check-cli/target/release/bin/dependency-check.sh --project Testing --out . --scan ./src/test/resources ``` On Windows ``` > mvn install > dependency-check-cli/target/release/bin/dependency-check.bat -h -> dependency-check-cli/target/release/bin/dependency-check.bat --app Testing --out . --scan ./src/test/resources +> dependency-check-cli/target/release/bin/dependency-check.bat --project Testing --out . --scan ./src/test/resources ``` Then load the resulting 'DependencyCheck-Report.html' into your favorite browser. From 30856f4a4ffaae8b4e7e094b077a9d36ca50efea Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 14 May 2016 07:19:12 -0400 Subject: [PATCH 02/55] corrected doxia version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ebfd86dbd..096ffffa9 100644 --- a/pom.xml +++ b/pom.xml @@ -337,7 +337,7 @@ Copyright (c) 2012 - Jeremy Long org.apache.maven.doxia doxia-module-markdown - 1.7.1 + 1.7 From 6f451736ba7d8c0aade2c2aec48dd04528475595 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 14 May 2016 07:20:53 -0400 Subject: [PATCH 03/55] Add ability to flag analyzers as experimental so that they are not always enabled --- .../owasp/dependencycheck/taskdefs/Check.java | 24 ++ .../src/site/markdown/configuration.md | 3 +- .../java/org/owasp/dependencycheck/App.java | 2 + .../org/owasp/dependencycheck/CliParser.java | 253 ++++++++++++------ .../src/site/markdown/arguments.md | 2 +- .../org/owasp/dependencycheck/Engine.java | 5 +- .../analyzer/AnalyzerService.java | 37 ++- .../analyzer/AutoconfAnalyzer.java | 1 + .../analyzer/CMakeAnalyzer.java | 1 + .../analyzer/Experimental.java | 34 +++ .../analyzer/NodePackageAnalyzer.java | 1 + .../main/resources/dependencycheck.properties | 9 +- .../analyzer/AnalyzerServiceTest.java | 36 ++- .../test/resources/dependencycheck.properties | 8 +- .../maven/BaseDependencyCheckMojo.java | 141 ++++++---- .../src/site/markdown/configuration.md | 7 +- .../owasp/dependencycheck/utils/Settings.java | 30 ++- 17 files changed, 412 insertions(+), 182 deletions(-) create mode 100644 dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/Experimental.java 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 cfefeb27c..fc4fc9d3b 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 @@ -361,6 +361,29 @@ public class Check extends Update { this.showSummary = showSummary; } + /** + * Whether experimental analyzers are enabled. + */ + private Boolean enableExperimental; + + /** + * Get the value of enableExperimental. + * + * @return the value of enableExperimental + */ + public Boolean isEnableExperimental() { + return enableExperimental; + } + + /** + * Set the value of enableExperimental. + * + * @param enableExperimental new value of enableExperimental + */ + public void setEnableExperimental(Boolean enableExperimental) { + this.enableExperimental = enableExperimental; + } + /** * Whether or not the Jar Analyzer is enabled. */ @@ -854,6 +877,7 @@ public class Check extends Update { super.populateSettings(); Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); + 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); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); diff --git a/dependency-check-ant/src/site/markdown/configuration.md b/dependency-check-ant/src/site/markdown/configuration.md index dafc18355..a58b73716 100644 --- a/dependency-check-ant/src/site/markdown/configuration.md +++ b/dependency-check-ant/src/site/markdown/configuration.md @@ -27,7 +27,7 @@ the project's dependencies. Configuration: dependency-check Task -------------------- -The following properties can be set on the dependency-check-update task. +The following properties can be set on the dependency-check task. Property | Description | Default Value ----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------- @@ -43,6 +43,7 @@ proxyPort | The Proxy Port. proxyUsername | Defines the proxy user name. |   proxyPassword | Defines the proxy password. |   connectionTimeout | The URL Connection Timeout. |   +enableExperimental | Enable the experimental analyzers. | false Analyzer Configuration ==================== 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 f34108383..c8bc71cd6 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 @@ -280,6 +280,7 @@ public class App { final String cveBase12 = cli.getBaseCve12Url(); final String cveBase20 = cli.getBaseCve20Url(); final Integer cveValidForHours = cli.getCveValidForHours(); + final boolean experimentalEnabled = cli.isExperimentalEnabled(); if (propertiesFile != null) { try { @@ -318,6 +319,7 @@ public class App { Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); //File Type Analyzer Settings + Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled); Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled()); Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled()); Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled()); 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 33ffc841b..d2e522834 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 @@ -58,7 +58,8 @@ public final class CliParser { * Parses the arguments passed in and captures the results for later use. * * @param args the command line arguments - * @throws FileNotFoundException is thrown when a 'file' argument does not point to a file that exists. + * @throws FileNotFoundException is thrown when a 'file' argument does not + * point to a file that exists. * @throws ParseException is thrown when a Parse Exception occurs. */ public void parse(String[] args) throws FileNotFoundException, ParseException { @@ -85,9 +86,10 @@ public final class CliParser { /** * Validates that the command line arguments are valid. * - * @throws FileNotFoundException if there is a file specified by either the SCAN or CPE command line arguments that does not - * exist. - * @throws ParseException is thrown if there is an exception parsing the command line. + * @throws FileNotFoundException if there is a file specified by either the + * SCAN or CPE command line arguments that does not exist. + * @throws ParseException is thrown if there is an exception parsing the + * command line. */ private void validateArgs() throws FileNotFoundException, ParseException { if (isUpdateOnly() || isRunScan()) { @@ -141,12 +143,14 @@ public final class CliParser { } /** - * Validates whether or not the path(s) points at a file that exists; if the path(s) does not point to an existing file a - * FileNotFoundException is thrown. + * Validates whether or not the path(s) points at a file that exists; if the + * path(s) does not point to an existing file a FileNotFoundException is + * thrown. * * @param paths the paths to validate if they exists * @param optType the option being validated (e.g. scan, out, etc.) - * @throws FileNotFoundException is thrown if one of the paths being validated does not exist. + * @throws FileNotFoundException is thrown if one of the paths being + * validated does not exist. */ private void validatePathExists(String[] paths, String optType) throws FileNotFoundException { for (String path : paths) { @@ -155,12 +159,14 @@ public final class CliParser { } /** - * Validates whether or not the path points at a file that exists; if the path does not point to an existing file a - * FileNotFoundException is thrown. + * Validates whether or not the path points at a file that exists; if the + * path does not point to an existing file a FileNotFoundException is + * thrown. * * @param path the paths to validate if they exists * @param argumentName the argument being validated (e.g. scan, out, etc.) - * @throws FileNotFoundException is thrown if the path being validated does not exist. + * @throws FileNotFoundException is thrown if the path being validated does + * not exist. */ private void validatePathExists(String path, String argumentName) throws FileNotFoundException { if (path == null) { @@ -181,12 +187,10 @@ public final class CliParser { throw new FileNotFoundException(msg); } } - } else { - if (!f.exists()) { - isValid = false; - final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); - throw new FileNotFoundException(msg); - } + } else if (!f.exists()) { + isValid = false; + final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); + throw new FileNotFoundException(msg); } } else if (path.startsWith("//") || path.startsWith("\\\\")) { isValid = false; @@ -196,7 +200,8 @@ public final class CliParser { } /** - * Generates an Options collection that is used to parse the command line and to display the help message. + * Generates an Options collection that is used to parse the command line + * and to display the help message. * * @return the command line options used for parsing the command line */ @@ -272,6 +277,10 @@ public final class CliParser { .desc("The number of hours to wait before checking for new updates from the NVD.") .build(); + final Option experimentalEnabled = Option.builder().longOpt(ARGUMENT.EXPERIMENTAL) + .desc("Enables the experimental analzers.") + .build(); + //This is an option group because it can be specified more then once. final OptionGroup og = new OptionGroup(); og.addOption(path); @@ -292,12 +301,14 @@ public final class CliParser { .addOption(props) .addOption(verboseLog) .addOption(suppressionFile) - .addOption(cveValidForHours); + .addOption(cveValidForHours) + .addOption(experimentalEnabled); } /** - * Adds the advanced command line options to the given options collection. These are split out for purposes of being able to - * display two different help messages. + * Adds the advanced command line options to the given options collection. + * These are split out for purposes of being able to display two different + * help messages. * * @param options a collection of command line arguments * @throws IllegalArgumentException thrown if there is an exception @@ -466,8 +477,10 @@ public final class CliParser { } /** - * Adds the deprecated command line options to the given options collection. These are split out for purposes of not including - * them in the help message. We need to add the deprecated options so as not to break existing scripts. + * Adds the deprecated command line options to the given options collection. + * These are split out for purposes of not including them in the help + * message. We need to add the deprecated options so as not to break + * existing scripts. * * @param options a collection of command line arguments * @throws IllegalArgumentException thrown if there is an exception @@ -514,7 +527,8 @@ public final class CliParser { } /** - * Returns the symbolic link depth (how deeply symbolic links will be followed). + * Returns the symbolic link depth (how deeply symbolic links will be + * followed). * * @return the symbolic link depth */ @@ -534,7 +548,8 @@ public final class CliParser { /** * Returns true if the disableJar command line argument was specified. * - * @return true if the disableJar command line argument was specified; otherwise false + * @return true if the disableJar command line argument was specified; + * otherwise false */ public boolean isJarDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR); @@ -543,7 +558,8 @@ public final class CliParser { /** * Returns true if the disableArchive command line argument was specified. * - * @return true if the disableArchive command line argument was specified; otherwise false + * @return true if the disableArchive command line argument was specified; + * otherwise false */ public boolean isArchiveDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE); @@ -552,7 +568,8 @@ public final class CliParser { /** * Returns true if the disableNuspec command line argument was specified. * - * @return true if the disableNuspec command line argument was specified; otherwise false + * @return true if the disableNuspec command line argument was specified; + * otherwise false */ public boolean isNuspecDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC); @@ -561,16 +578,19 @@ public final class CliParser { /** * Returns true if the disableAssembly command line argument was specified. * - * @return true if the disableAssembly command line argument was specified; otherwise false + * @return true if the disableAssembly command line argument was specified; + * otherwise false */ public boolean isAssemblyDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY); } /** - * Returns true if the disableBundleAudit command line argument was specified. + * Returns true if the disableBundleAudit command line argument was + * specified. * - * @return true if the disableBundleAudit command line argument was specified; otherwise false + * @return true if the disableBundleAudit command line argument was + * specified; otherwise false */ public boolean isBundleAuditDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_BUNDLE_AUDIT); @@ -579,7 +599,8 @@ public final class CliParser { /** * Returns true if the disablePyDist command line argument was specified. * - * @return true if the disablePyDist command line argument was specified; otherwise false + * @return true if the disablePyDist command line argument was specified; + * otherwise false */ public boolean isPythonDistributionDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST); @@ -588,7 +609,8 @@ public final class CliParser { /** * Returns true if the disablePyPkg command line argument was specified. * - * @return true if the disablePyPkg command line argument was specified; otherwise false + * @return true if the disablePyPkg command line argument was specified; + * otherwise false */ public boolean isPythonPackageDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG); @@ -597,7 +619,8 @@ public final class CliParser { /** * Returns whether the Ruby gemspec analyzer is disabled. * - * @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line argument was specified; otherwise false + * @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line + * argument was specified; otherwise false */ public boolean isRubyGemspecDisabled() { return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS); @@ -606,7 +629,8 @@ public final class CliParser { /** * Returns true if the disableCmake command line argument was specified. * - * @return true if the disableCmake command line argument was specified; otherwise false + * @return true if the disableCmake command line argument was specified; + * otherwise false */ public boolean isCmakeDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE); @@ -615,7 +639,8 @@ public final class CliParser { /** * Returns true if the disableAutoconf command line argument was specified. * - * @return true if the disableAutoconf command line argument was specified; otherwise false + * @return true if the disableAutoconf command line argument was specified; + * otherwise false */ public boolean isAutoconfDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF); @@ -624,7 +649,8 @@ public final class CliParser { /** * Returns true if the disableComposer command line argument was specified. * - * @return true if the disableComposer command line argument was specified; otherwise false + * @return true if the disableComposer command line argument was specified; + * otherwise false */ public boolean isComposerDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_COMPOSER); @@ -633,7 +659,8 @@ public final class CliParser { /** * Returns true if the disableNexus command line argument was specified. * - * @return true if the disableNexus command line argument was specified; otherwise false + * @return true if the disableNexus command line argument was specified; + * otherwise false */ public boolean isNexusDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS); @@ -642,7 +669,8 @@ public final class CliParser { /** * Returns true if the disableOpenSSL command line argument was specified. * - * @return true if the disableOpenSSL command line argument was specified; otherwise false + * @return true if the disableOpenSSL command line argument was specified; + * otherwise false */ public boolean isOpenSSLDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL); @@ -651,7 +679,8 @@ public final class CliParser { /** * Returns true if the disableNodeJS command line argument was specified. * - * @return true if the disableNodeJS command line argument was specified; otherwise false + * @return true if the disableNodeJS command line argument was specified; + * otherwise false */ public boolean isNodeJsDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_NODE_JS); @@ -660,7 +689,8 @@ public final class CliParser { /** * Returns true if the disableCentral command line argument was specified. * - * @return true if the disableCentral command line argument was specified; otherwise false + * @return true if the disableCentral command line argument was specified; + * otherwise false */ public boolean isCentralDisabled() { return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL); @@ -669,7 +699,8 @@ public final class CliParser { /** * Returns the url to the nexus server if one was specified. * - * @return the url to the nexus server; if none was specified this will return null; + * @return the url to the nexus server; if none was specified this will + * return null; */ public String getNexusUrl() { if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) { @@ -680,9 +711,11 @@ public final class CliParser { } /** - * Returns true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false is returned. + * Returns true if the Nexus Analyzer should use the configured proxy to + * connect to Nexus; otherwise false is returned. * - * @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false + * @return true if the Nexus Analyzer should use the configured proxy to + * connect to Nexus; otherwise false */ public boolean isNexusUsesProxy() { // If they didn't specify whether Nexus needs to use the proxy, we should @@ -722,7 +755,8 @@ public final class CliParser { } /** - * Retrieves the file command line parameter(s) specified for the 'scan' argument. + * Retrieves the file command line parameter(s) specified for the 'scan' + * argument. * * @return the file paths specified on the command line for scan */ @@ -731,7 +765,8 @@ public final class CliParser { } /** - * Retrieves the list of excluded file patterns specified by the 'exclude' argument. + * Retrieves the list of excluded file patterns specified by the 'exclude' + * argument. * * @return the excluded file patterns */ @@ -740,7 +775,8 @@ public final class CliParser { } /** - * Returns the directory to write the reports to specified on the command line. + * Returns the directory to write the reports to specified on the command + * line. * * @return the path to the reports directory. */ @@ -749,7 +785,8 @@ public final class CliParser { } /** - * Returns the path to Mono for .NET Assembly analysis on non-windows systems. + * Returns the path to Mono for .NET Assembly analysis on non-windows + * systems. * * @return the path to Mono */ @@ -767,7 +804,8 @@ public final class CliParser { } /** - * Returns the output format specified on the command line. Defaults to HTML if no format was specified. + * Returns the output format specified on the command line. Defaults to HTML + * if no format was specified. * * @return the output format name. */ @@ -934,9 +972,11 @@ public final class CliParser { } /** - * Checks if the auto update feature has been disabled. If it has been disabled via the command line this will return false. + * Checks if the auto update feature has been disabled. If it has been + * disabled via the command line this will return false. * - * @return true if auto-update is allowed; otherwise false + * @return true if auto-update is allowed; otherwise + * false */ public boolean isAutoUpdate() { return line != null && !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE); @@ -945,7 +985,8 @@ public final class CliParser { /** * Checks if the update only flag has been set. * - * @return true if the update only flag has been set; otherwise false. + * @return true if the update only flag has been set; otherwise + * false. */ public boolean isUpdateOnly() { return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY); @@ -954,14 +995,16 @@ public final class CliParser { /** * Checks if the purge NVD flag has been set. * - * @return true if the purge nvd flag has been set; otherwise false. + * @return true if the purge nvd flag has been set; otherwise + * false. */ public boolean isPurge() { return line != null && line.hasOption(ARGUMENT.PURGE_NVD); } /** - * Returns the database driver name if specified; otherwise null is returned. + * Returns the database driver name if specified; otherwise null is + * returned. * * @return the database driver name if specified; otherwise null is returned */ @@ -970,7 +1013,8 @@ public final class CliParser { } /** - * Returns the database driver path if specified; otherwise null is returned. + * Returns the database driver path if specified; otherwise null is + * returned. * * @return the database driver name if specified; otherwise null is returned */ @@ -979,34 +1023,41 @@ public final class CliParser { } /** - * Returns the database connection string if specified; otherwise null is returned. + * Returns the database connection string if specified; otherwise null is + * returned. * - * @return the database connection string if specified; otherwise null is returned + * @return the database connection string if specified; otherwise null is + * returned */ public String getConnectionString() { return line.getOptionValue(ARGUMENT.CONNECTION_STRING); } /** - * Returns the database database user name if specified; otherwise null is returned. + * Returns the database database user name if specified; otherwise null is + * returned. * - * @return the database database user name if specified; otherwise null is returned + * @return the database database user name if specified; otherwise null is + * returned */ public String getDatabaseUser() { return line.getOptionValue(ARGUMENT.DB_NAME); } /** - * Returns the database database password if specified; otherwise null is returned. + * Returns the database database password if specified; otherwise null is + * returned. * - * @return the database database password if specified; otherwise null is returned + * @return the database database password if specified; otherwise null is + * returned */ public String getDatabasePassword() { return line.getOptionValue(ARGUMENT.DB_PASSWORD); } /** - * Returns the additional Extensions if specified; otherwise null is returned. + * Returns the additional Extensions if specified; otherwise null is + * returned. * * @return the additional Extensions; otherwise null is returned */ @@ -1028,7 +1079,17 @@ public final class CliParser { } /** - * A collection of static final strings that represent the possible command line arguments. + * Returns true if the experimental analyzers are enabled. + * + * @return true if the experimental analyzers are enabled; otherwise false + */ + public boolean isExperimentalEnabled() { + return line.hasOption(ARGUMENT.EXPERIMENTAL); + } + + /** + * A collection of static final strings that represent the possible command + * line arguments. */ public static class ARGUMENT { @@ -1041,50 +1102,61 @@ public final class CliParser { */ public static final String SCAN_SHORT = "s"; /** - * The long CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated. + * The long CLI argument name specifying that the CPE/CVE/etc. data + * should not be automatically updated. */ public static final String DISABLE_AUTO_UPDATE = "noupdate"; /** - * The short CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated. + * The short CLI argument name specifying that the CPE/CVE/etc. data + * should not be automatically updated. */ public static final String DISABLE_AUTO_UPDATE_SHORT = "n"; /** - * The long CLI argument name specifying that only the update phase should be executed; no scan should be run. + * The long CLI argument name specifying that only the update phase + * should be executed; no scan should be run. */ public static final String UPDATE_ONLY = "updateonly"; /** - * The long CLI argument name specifying that only the update phase should be executed; no scan should be run. + * The long CLI argument name specifying that only the update phase + * should be executed; no scan should be run. */ public static final String PURGE_NVD = "purge"; /** - * The long CLI argument name specifying the directory to write the reports to. + * The long CLI argument name specifying the directory to write the + * reports to. */ public static final String OUT = "out"; /** - * The short CLI argument name specifying the directory to write the reports to. + * The short CLI argument name specifying the directory to write the + * reports to. */ public static final String OUT_SHORT = "o"; /** - * The long CLI argument name specifying the output format to write the reports to. + * The long CLI argument name specifying the output format to write the + * reports to. */ public static final String OUTPUT_FORMAT = "format"; /** - * The short CLI argument name specifying the output format to write the reports to. + * The short CLI argument name specifying the output format to write the + * reports to. */ public static final String OUTPUT_FORMAT_SHORT = "f"; /** - * The long CLI argument name specifying the name of the project to be scanned. + * The long CLI argument name specifying the name of the project to be + * scanned. */ public static final String PROJECT = "project"; /** - * The long CLI argument name specifying the name of the application to be scanned. + * The long CLI argument name specifying the name of the application to + * be scanned. * * @deprecated project should be used instead */ @Deprecated public static final String APP_NAME = "app"; /** - * The short CLI argument name specifying the name of the application to be scanned. + * The short CLI argument name specifying the name of the application to + * be scanned. * * @deprecated project should be used instead */ @@ -1142,11 +1214,13 @@ public final class CliParser { */ public static final String CONNECTION_TIMEOUT = "connectiontimeout"; /** - * The short CLI argument name for setting the location of an additional properties file. + * The short CLI argument name for setting the location of an additional + * properties file. */ public static final String PROP_SHORT = "P"; /** - * The CLI argument name for setting the location of an additional properties file. + * The CLI argument name for setting the location of an additional + * properties file. */ public static final String PROP = "propertyfile"; /** @@ -1170,7 +1244,8 @@ public final class CliParser { */ public static final String CVE_BASE_20 = "cveUrl20Base"; /** - * The short CLI argument name for setting the location of the data directory. + * The short CLI argument name for setting the location of the data + * directory. */ public static final String DATA_DIRECTORY_SHORT = "d"; /** @@ -1178,20 +1253,24 @@ public final class CliParser { */ public static final String VERBOSE_LOG = "log"; /** - * The short CLI argument name for setting the location of the data directory. + * The short CLI argument name for setting the location of the data + * directory. */ public static final String VERBOSE_LOG_SHORT = "l"; /** - * The CLI argument name for setting the depth of symbolic links that will be followed. + * The CLI argument name for setting the depth of symbolic links that + * will be followed. */ public static final String SYM_LINK_DEPTH = "symLink"; /** - * The CLI argument name for setting the location of the suppression file. + * The CLI argument name for setting the location of the suppression + * file. */ public static final String SUPPRESSION_FILE = "suppression"; /** - * The CLI argument name for setting the location of the suppression file. + * The CLI argument name for setting the location of the suppression + * file. */ public static final String CVE_VALID_FOR_HOURS = "cveValidForHours"; /** @@ -1259,7 +1338,8 @@ public final class CliParser { */ public static final String NEXUS_URL = "nexus"; /** - * Whether or not the defined proxy should be used when connecting to Nexus. + * Whether or not the defined proxy should be used when connecting to + * Nexus. */ public static final String NEXUS_USES_PROXY = "nexusUsesProxy"; /** @@ -1279,11 +1359,13 @@ public final class CliParser { */ public static final String DB_DRIVER = "dbDriverName"; /** - * The CLI argument name for setting the path to the database driver; in case it is not on the class path. + * The CLI argument name for setting the path to the database driver; in + * case it is not on the class path. */ public static final String DB_DRIVER_PATH = "dbDriverPath"; /** - * The CLI argument name for setting the path to mono for .NET Assembly analysis on non-windows systems. + * The CLI argument name for setting the path to mono for .NET Assembly + * analysis on non-windows systems. */ public static final String PATH_TO_MONO = "mono"; /** @@ -1295,8 +1377,13 @@ public final class CliParser { */ public static final String EXCLUDE = "exclude"; /** - * The CLI argument name for setting the path to bundle-audit for Ruby bundle analysis. + * The CLI argument name for setting the path to bundle-audit for Ruby + * bundle analysis. */ public static final String PATH_TO_BUNDLE_AUDIT = "bundleAudit"; + /** + * The CLI argument to enable the experimental analyzers. + */ + private static final String EXPERIMENTAL = "enableExperimental"; } } diff --git a/dependency-check-cli/src/site/markdown/arguments.md b/dependency-check-cli/src/site/markdown/arguments.md index 66f37af01..876eee216 100644 --- a/dependency-check-cli/src/site/markdown/arguments.md +++ b/dependency-check-cli/src/site/markdown/arguments.md @@ -18,7 +18,7 @@ Short | Argument Name   | Parameter | Description | Requir | \-\-advancedHelp | | Print the advanced help message. | Optional \-v | \-\-version | | Print the version information. | Optional | \-\-cveValidForHours | \ | The number of hours to wait before checking for new updates from the NVD. The default is 4 hours. | Optional - + | \-\-experimental | | Enable the experimental analyzers. | Optional Advanced Options ================ 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 fa120a0e8..c35a796e0 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 @@ -126,9 +126,8 @@ public class Engine implements FileFilter { } final AnalyzerService service = new AnalyzerService(serviceClassLoader); - final Iterator iterator = service.getAnalyzers(); - while (iterator.hasNext()) { - final Analyzer a = iterator.next(); + final List iterator = service.getAnalyzers(); + for (Analyzer a : iterator) { analyzers.get(a.getAnalysisPhase()).add(a); if (a instanceof FileTypeAnalyzer) { this.fileTypeAnalyzers.add((FileTypeAnalyzer) a); diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java index a794b1030..41a243021 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java @@ -17,8 +17,13 @@ */ package org.owasp.dependencycheck.analyzer; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import java.util.ServiceLoader; +import org.owasp.dependencycheck.utils.InvalidSettingException; +import org.owasp.dependencycheck.utils.Settings; +import org.slf4j.LoggerFactory; /** * The Analyzer Service Loader. This class loads all services that implement @@ -27,11 +32,15 @@ import java.util.ServiceLoader; * @author Jeremy Long */ public class AnalyzerService { + /** + * The Logger for use throughout the class. + */ + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AnalyzerService.class); /** * The service loader for analyzers. */ - private final ServiceLoader loader; + private final ServiceLoader service; /** * Creates a new instance of AnalyzerService. @@ -39,15 +48,31 @@ public class AnalyzerService { * @param classLoader the ClassLoader to use when dynamically loading Analyzer and Update services */ public AnalyzerService(ClassLoader classLoader) { - loader = ServiceLoader.load(Analyzer.class, classLoader); + service = ServiceLoader.load(Analyzer.class, classLoader); } /** - * Returns an Iterator for all instances of the Analyzer interface. + * Returns a list of all instances of the Analyzer interface. * - * @return an iterator of Analyzers. + * @return a list of Analyzers. */ - public Iterator getAnalyzers() { - return loader.iterator(); + public List getAnalyzers() { + List analyzers = new ArrayList(); + final Iterator iterator = service.iterator(); + boolean experimentalEnabled = false; + try { + experimentalEnabled = Settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false); + } catch (InvalidSettingException ex) { + LOGGER.error("invalide experimental setting", ex); + } + while (iterator.hasNext()) { + final Analyzer a = iterator.next(); + if (!experimentalEnabled && a.getClass().isAnnotationPresent(Experimental.class)) { + continue; + } + LOGGER.debug("Loaded Analyzer {}", a.getName()); + analyzers.add(a); + } + return analyzers; } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java index 04dcfcefe..cb6736134 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java @@ -42,6 +42,7 @@ import java.util.regex.Pattern; * @author Dale Visser * @see Autoconf - GNU Project - Free Software Foundation (FSF) */ +@Experimental public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java index 55a81e216..fc434370f 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java @@ -49,6 +49,7 @@ import java.util.regex.Pattern; * * @author Dale Visser */ +@Experimental public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/Experimental.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/Experimental.java new file mode 100644 index 000000000..8f5a3842a --- /dev/null +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/Experimental.java @@ -0,0 +1,34 @@ +/* + * 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) 2016 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.analyzer; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation used to flag an analyzer as experimental. + * + * @author jeremy long + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Experimental { + +} diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.java index 85326f392..52b9afe11 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.java @@ -45,6 +45,7 @@ import javax.json.JsonValue; * * @author Dale Visser */ +@Experimental public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { /** diff --git a/dependency-check-core/src/main/resources/dependencycheck.properties b/dependency-check-core/src/main/resources/dependencycheck.properties index 118b5b50f..a0a1fd3e7 100644 --- a/dependency-check-core/src/main/resources/dependencycheck.properties +++ b/dependency-check-core/src/main/resources/dependencycheck.properties @@ -63,13 +63,6 @@ cve.url-2.0.base=https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz cpe.validfordays=30 cpe.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.3.xml.gz -# file type analyzer settings: -analyzer.archive.enabled=true -analyzer.jar.enabled=true -analyzer.nuspec.enabled=true -analyzer.assembly.enabled=true -analyzer.composer.lock.enabled=true - # the URL for searching Nexus for SHA-1 hashes and whether it's enabled analyzer.nexus.enabled=true analyzer.nexus.url=https://repository.sonatype.org/service/local/ @@ -87,7 +80,7 @@ archive.scan.depth=3 # use HEAD (default) or GET as HTTP request method for query timestamp downloader.quick.query.timestamp=true - +analyzer.experimental.enabled=false analyzer.jar.enabled=true analyzer.archive.enabled=true analyzer.node.package.enabled=true diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java index befa0692c..229e61d9b 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java @@ -18,9 +18,12 @@ package org.owasp.dependencycheck.analyzer; import java.util.Iterator; +import java.util.List; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.junit.Test; import org.owasp.dependencycheck.BaseDBTestCase; +import org.owasp.dependencycheck.utils.Settings; /** * @@ -34,15 +37,42 @@ public class AnalyzerServiceTest extends BaseDBTestCase { @Test public void testGetAnalyzers() { AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); - Iterator result = instance.getAnalyzers(); + List result = instance.getAnalyzers(); boolean found = false; - while (result.hasNext()) { - Analyzer a = result.next(); + for (Analyzer a : result) { if ("Jar Analyzer".equals(a.getName())) { found = true; } } assertTrue("JarAnalyzer loaded", found); } + + /** + * Test of getAnalyzers method, of class AnalyzerService. + */ + @Test + public void testGetExperimentalAnalyzers() { + Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false); + AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); + List result = instance.getAnalyzers(); + String experimental = "CMake Analyzer"; + boolean found = false; + for (Analyzer a : result) { + if (experimental.equals(a.getName())) { + found = true; + } + } + assertFalse("Experimental analyzer loaded when set to false", found); + + Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, true); + result = instance.getAnalyzers(); + found = false; + for (Analyzer a : result) { + if (experimental.equals(a.getName())) { + found = true; + } + } + assertTrue("Experimental analyzer not loaded when set to true", found); + } } diff --git a/dependency-check-core/src/test/resources/dependencycheck.properties b/dependency-check-core/src/test/resources/dependencycheck.properties index e3862e8e7..c82d46051 100644 --- a/dependency-check-core/src/test/resources/dependencycheck.properties +++ b/dependency-check-core/src/test/resources/dependencycheck.properties @@ -58,12 +58,6 @@ cve.url-2.0.base=https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz cpe.validfordays=30 cpe.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.3.xml.gz -# file type analyzer settings: -analyzer.archive.enabled=true -analyzer.jar.enabled=true -analyzer.nuspec.enabled=true -analyzer.assembly.enabled=true -analyzer.composer.lock.enabled=true # the URL for searching Nexus for SHA-1 hashes and whether it's enabled analyzer.nexus.enabled=true @@ -82,7 +76,7 @@ archive.scan.depth=3 # use HEAD (default) or GET as HTTP request method for query timestamp downloader.quick.query.timestamp=true - +analyzer.experimental.enabled=true analyzer.jar.enabled=true analyzer.archive.enabled=true analyzer.node.package.enabled=true 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 57e8677be..1fd81babe 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 @@ -94,24 +94,32 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @Parameter(defaultValue = "${project.build.directory}", required = true) private File outputDirectory; /** - * Specifies the destination directory for the generated Dependency-Check report. This generally maps to "target/site". + * Specifies the destination directory for the generated Dependency-Check + * report. This generally maps to "target/site". */ @Parameter(property = "project.reporting.outputDirectory", required = true) private File reportOutputDirectory; /** - * 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. + * 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. */ @SuppressWarnings("CanBeFinal") @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true) private float failBuildOnCVSS = 11; /** - * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default - * is true. + * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not + * recommended that this be turned to false. Default is true. */ @SuppressWarnings("CanBeFinal") @Parameter(property = "autoUpdate") private Boolean autoUpdate; + /** + * Sets whether Experimental analyzers are enabled. Default is false. + */ + @SuppressWarnings("CanBeFinal") + @Parameter(property = "enableExperimental") + private Boolean enableExperimental; /** * Generate aggregate reports in multi-module projects. * @@ -121,8 +129,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @Deprecated private Boolean aggregate; /** - * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the - * Site plug-in unless the externalReport is set to true. Default is HTML. + * The report format to be generated (HTML, XML, VULN, ALL). This + * configuration option has no affect if using this within the Site plug-in + * unless the externalReport is set to true. Default is HTML. */ @SuppressWarnings("CanBeFinal") @Parameter(property = "format", defaultValue = "HTML", required = true) @@ -234,7 +243,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma private Boolean nexusAnalyzerEnabled; /** - * The URL of a Nexus server's REST API end point (http://domain/nexus/service/local). + * The URL of a Nexus server's REST API end point + * (http://domain/nexus/service/local). */ @Parameter(property = "nexusUrl", required = false) private String nexusUrl; @@ -268,7 +278,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @Parameter(property = "databaseDriverPath", defaultValue = "", required = false) private String databaseDriverPath; /** - * The server id in the settings.xml; used to retrieve encrypted passwords from the settings.xml. + * The server id in the settings.xml; used to retrieve encrypted passwords + * from the settings.xml. */ @Parameter(property = "serverId", defaultValue = "", required = false) private String serverId; @@ -293,7 +304,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @Parameter(property = "databasePassword", defaultValue = "", required = false) private String databasePassword; /** - * A comma-separated list of file extensions to add to analysis next to jar, zip, .... + * A comma-separated list of file extensions to add to analysis next to jar, + * zip, .... */ @Parameter(property = "zipExtensions", required = false) private String zipExtensions; @@ -347,7 +359,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @Parameter(property = "cveUrl20Base", defaultValue = "", required = false) private String cveUrl20Base; /** - * Optionally skip excessive CVE update checks for a designated duration in hours. + * Optionally skip excessive CVE update checks for a designated duration in + * hours. */ @Parameter(property = "cveValidForHours", defaultValue = "", required = false) private Integer cveValidForHours; @@ -382,7 +395,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma /** * Executes dependency-check. * - * @throws MojoExecutionException thrown if there is an exception executing the mojo + * @throws MojoExecutionException thrown if there is an exception executing + * the mojo * @throws MojoFailureException thrown if dependency-check failed the build */ @Override @@ -398,8 +412,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } /** - * Checks if the aggregate configuration parameter has been set to true. If it has a MojoExecutionException is thrown because - * the aggregate configuration parameter is no longer supported. + * Checks if the aggregate configuration parameter has been set to true. If + * it has a MojoExecutionException is thrown because the aggregate + * configuration parameter is no longer supported. * * @throws MojoExecutionException thrown if aggregate is set to true */ @@ -417,7 +432,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma * @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, java.util.Locale)} instead. + * @deprecated use + * {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)} + * instead. */ @Override @Deprecated @@ -464,17 +481,20 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } /** - * Returns the correct output directory depending on if a site is being executed or not. + * Returns the correct output directory depending on if a site is being + * executed or not. * * @return the directory to write the report(s) - * @throws MojoExecutionException thrown if there is an error loading the file path + * @throws MojoExecutionException thrown if there is an error loading the + * file path */ protected File getCorrectOutputDirectory() throws MojoExecutionException { return getCorrectOutputDirectory(this.project); } /** - * Returns the correct output directory depending on if a site is being executed or not. + * Returns the correct output directory depending on if a site is being + * executed or not. * * @param current the Maven project to get the output directory from * @return the directory to write the report(s) @@ -492,7 +512,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } /** - * Returns the correct output directory depending on if a site is being executed or not. + * Returns the correct output directory depending on if a site is being + * executed or not. * * @param current the Maven project to get the output directory from * @return the directory to write the report(s) @@ -507,16 +528,15 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma final File f = new File((String) obj); return f; } - } else { - if (getLog().isDebugEnabled()) { - getLog().debug("Context value not found"); - } + } else if (getLog().isDebugEnabled()) { + getLog().debug("Context value not found"); } return null; } /** - * Scans the project's artifacts and adds them to the engine's dependency list. + * Scans the project's artifacts and adds them to the engine's dependency + * list. * * @param project the project to scan the dependencies of * @param engine the engine to use to scan the dependencies @@ -539,12 +559,10 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma d.getDisplayFileName())); } } - } else { - if (getLog().isDebugEnabled()) { - final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'", - a.getGroupId(), a.getArtifactId(), a.getVersion()); - getLog().debug(msg); - } + } else if (getLog().isDebugEnabled()) { + final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'", + a.getGroupId(), a.getArtifactId(), a.getVersion()); + getLog().debug(msg); } } } @@ -553,8 +571,10 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma /** * Executes the dependency-check scan and generates the necassary report. * - * @throws MojoExecutionException thrown if there is an exception running the scan - * @throws MojoFailureException thrown if dependency-check is configured to fail the build + * @throws MojoExecutionException thrown if there is an exception running + * the scan + * @throws MojoFailureException thrown if dependency-check is configured to + * fail the build */ public abstract void runCheck() throws MojoExecutionException, MojoFailureException; @@ -588,7 +608,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } /** - * Returns whether this is an external report. This method always returns true. + * Returns whether this is an external report. This method always returns + * true. * * @return true */ @@ -640,8 +661,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } /** - * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties - * required to change the proxy url, port, and connection timeout. + * Takes the properties supplied and updates the dependency-check settings. + * Additionally, this sets the system properties required to change the + * proxy url, port, and connection timeout. */ protected void populateSettings() { Settings.initialize(); @@ -666,6 +688,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } } Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); + + Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); if (externalReport != null) { getLog().warn("The 'externalReport' option was set; this configuration option has been removed. " @@ -795,10 +819,12 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } /** - * Tests is the artifact should be included in the scan (i.e. is the dependency in a scope that is being scanned). + * Tests is the artifact should be included in the scan (i.e. is the + * dependency in a scope that is being scanned). * * @param a the Artifact to test - * @return true if the artifact is in an excluded scope; otherwise false + * @return true if the artifact is in an excluded scope; + * otherwise false */ protected boolean excludeFromScan(Artifact a) { if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) { @@ -814,10 +840,12 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } /** - * Returns a reference to the current project. This method is used instead of auto-binding the project via component - * annotation in concrete implementations of this. If the child has a @Component MavenProject project; defined - * then the abstract class (i.e. this class) will not have access to the current project (just the way Maven works with the - * binding). + * Returns a reference to the current project. This method is used instead + * of auto-binding the project via component annotation in concrete + * implementations of this. If the child has a + * @Component MavenProject project; defined then the abstract + * class (i.e. this class) will not have access to the current project (just + * the way Maven works with the binding). * * @return returns a reference to the current project */ @@ -886,11 +914,12 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma // /** - * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the - * configuration. + * Checks to see if a vulnerability has been identified with a CVSS score + * that is above the threshold set in the configuration. * * @param dependencies the list of dependency objects - * @throws MojoFailureException thrown if a CVSS score is found that is higher then the threshold set + * @throws MojoFailureException thrown if a CVSS score is found that is + * higher then the threshold set */ protected void checkForFailure(List dependencies) throws MojoFailureException { if (failBuildOnCVSS <= 10) { @@ -919,7 +948,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } /** - * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries. + * Generates a warning message listing a summary of dependencies and their + * associated CPE and CVE entries. * * @param mp the Maven project for which the summary is shown * @param dependencies a list of dependency objects @@ -963,8 +993,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma // // /** - * Returns the key used to store the path to the data file that is saved by writeDataFile(). This key is used in - * the MavenProject.(set|get)ContextValue. + * Returns the key used to store the path to the data file that is saved by + * writeDataFile(). This key is used in the + * MavenProject.(set|get)ContextValue. * * @return the key used to store the path to the data file */ @@ -973,8 +1004,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } /** - * Returns the key used to store the path to the output directory. When generating the report in the - * executeAggregateReport() the output directory should be obtained by using this key. + * Returns the key used to store the path to the output directory. When + * generating the report in the executeAggregateReport() the + * output directory should be obtained by using this key. * * @return the key used to store the path to the output directory */ @@ -983,7 +1015,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } /** - * Writes the scan data to disk. This is used to serialize the scan data between the "check" and "aggregate" phase. + * Writes the scan data to disk. This is used to serialize the scan data + * between the "check" and "aggregate" phase. * * @param mp the mMven project for which the data file was created * @param writeTo the directory to write the data file @@ -1037,12 +1070,12 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } /** - * Reads the serialized scan data from disk. This is used to serialize the scan data between the "check" and "aggregate" - * phase. + * Reads the serialized scan data from disk. This is used to serialize the + * scan data between the "check" and "aggregate" phase. * * @param project the Maven project to read the data file from - * @return a Engine object populated with dependencies if the serialized data file exists; otherwise - * null is returned + * @return a Engine object populated with dependencies if the + * serialized data file exists; otherwise null is returned */ protected List readDataFile(MavenProject project) { final Object oPath = project.getContextValue(this.getDataFileContextKey()); diff --git a/dependency-check-maven/src/site/markdown/configuration.md b/dependency-check-maven/src/site/markdown/configuration.md index 7e64ab216..e35574aff 100644 --- a/dependency-check-maven/src/site/markdown/configuration.md +++ b/dependency-check-maven/src/site/markdown/configuration.md @@ -21,10 +21,11 @@ format | The report format to be generated (HTML, XML, VULN, ALL). 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 -skipTestScope | Should be skip analysis for artifacts with Test Scope | true -skipProvidedScope | Should be skip analysis for artifacts with Provided Scope | false -skipRuntimeScope | Should be skip analysis for artifacts with Runtime Scope | false +skipTestScope | Skip analysis for artifacts with Test Scope | true +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) |   +enableExperimental | Enable the experimental analyzers | false Analyzer Configuration ==================== diff --git a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java index 8f1f38147..924e355cd 100644 --- a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java +++ b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java @@ -189,6 +189,10 @@ public final class Settings { * The properties key for whether the Jar Analyzer is enabled. */ public static final String ANALYZER_JAR_ENABLED = "analyzer.jar.enabled"; + /** + * The properties key for whether experimental analyzers are loaded. + */ + public static final String ANALYZER_EXPERIMENTAL_ENABLED = "analyzer.experimental.enabled"; /** * The properties key for whether the Archive analyzer is enabled. */ @@ -309,7 +313,7 @@ public final class Settings { /** * Thread local settings. */ - private static ThreadLocal localSettings = new ThreadLocal(); + private static final ThreadLocal LOCAL_SETTINGS = new ThreadLocal(); /** * The properties. */ @@ -346,7 +350,7 @@ public final class Settings { * also call Settings.cleanup() to properly release resources. */ public static void initialize() { - localSettings.set(new Settings(PROPERTIES_FILE)); + LOCAL_SETTINGS.set(new Settings(PROPERTIES_FILE)); } /** @@ -356,7 +360,7 @@ public final class Settings { * @param propertiesFilePath the path to the base properties file to load */ public static void initialize(String propertiesFilePath) { - localSettings.set(new Settings(propertiesFilePath)); + LOCAL_SETTINGS.set(new Settings(propertiesFilePath)); } /** @@ -385,7 +389,7 @@ public final class Settings { } } try { - localSettings.remove(); + LOCAL_SETTINGS.remove(); } catch (Throwable ex) { LOGGER.debug("Error cleaning up Settings", ex); } @@ -397,7 +401,7 @@ public final class Settings { * @return the Settings object */ public static Settings getInstance() { - return localSettings.get(); + return LOCAL_SETTINGS.get(); } /** @@ -406,7 +410,7 @@ public final class Settings { * @param instance the instance of the settings object to use in this thread */ public static void setInstance(Settings instance) { - localSettings.set(instance); + LOCAL_SETTINGS.set(instance); } /** @@ -452,7 +456,7 @@ public final class Settings { * @param value the value for the property */ public static void setString(String key, String value) { - localSettings.get().props.setProperty(key, value); + LOCAL_SETTINGS.get().props.setProperty(key, value); LOGGER.debug("Setting: {}='{}'", key, value); } @@ -509,7 +513,7 @@ public final class Settings { * @param value the value for the property */ public static void setInt(String key, int value) { - localSettings.get().props.setProperty(key, String.valueOf(value)); + LOCAL_SETTINGS.get().props.setProperty(key, String.valueOf(value)); LOGGER.debug("Setting: {}='{}'", key, value); } @@ -584,8 +588,8 @@ public final class Settings { * @throws IOException is thrown when there is an exception loading/merging the properties */ public static void mergeProperties(InputStream stream) throws IOException { - localSettings.get().props.load(stream); - logProperties("Properties updated via merge", localSettings.get().props); + LOCAL_SETTINGS.get().props.load(stream); + logProperties("Properties updated via merge", LOCAL_SETTINGS.get().props); } /** @@ -665,7 +669,7 @@ public final class Settings { * @return the property from the properties file */ public static String getString(String key, String defaultValue) { - final String str = System.getProperty(key, localSettings.get().props.getProperty(key, defaultValue)); + final String str = System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue)); return str; } @@ -699,7 +703,7 @@ public final class Settings { * @return the property from the properties file */ public static String getString(String key) { - return System.getProperty(key, localSettings.get().props.getProperty(key)); + return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key)); } /** @@ -708,7 +712,7 @@ public final class Settings { * @param key the property key to remove */ public static void removeProperty(String key) { - localSettings.get().props.remove(key); + LOCAL_SETTINGS.get().props.remove(key); } /** From ea942398e37663d064fd14210c9644280fb33824 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 15 May 2016 06:45:57 -0400 Subject: [PATCH 04/55] updated test case to use the correct parent class that allows for use of the database during testing --- .../dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java index 04f167703..64afd6c52 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java @@ -31,6 +31,7 @@ import org.junit.After; import org.junit.Assume; import org.junit.Before; import org.junit.Test; +import org.owasp.dependencycheck.BaseDBTestCase; import org.owasp.dependencycheck.BaseTest; import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.analyzer.exception.AnalysisException; @@ -48,7 +49,7 @@ import org.slf4j.LoggerFactory; * * @author Dale Visser */ -public class RubyBundleAuditAnalyzerTest extends BaseTest { +public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); From 6790727260212b3e27810f4521c4300e3dd04556 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 15 May 2016 07:02:18 -0400 Subject: [PATCH 05/55] ensured resources are properly closed --- .../analyzer/RubyBundleAuditAnalyzer.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java index 1d983169b..5e4f90afa 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java @@ -225,8 +225,9 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { throw new AnalysisException("bundle-audit process interrupted", ie); } BufferedReader rdr = null; + BufferedReader errReader = null; try { - BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); + errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); while (errReader.ready()) { String error = errReader.readLine(); LOGGER.warn(error); @@ -236,6 +237,13 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } catch (IOException ioe) { LOGGER.warn("bundle-audit failure", ioe); } finally { + if (errReader!= null) { + try { + errReader.close(); + } catch (IOException ioe) { + LOGGER.warn("bundle-audit close failure", ioe); + } + } if (null != rdr) { try { rdr.close(); From 353b17690f0f7beb38b0b00c50d88921b44f5989 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 15 May 2016 07:22:52 -0400 Subject: [PATCH 06/55] checkstyle/pmd/findbugs correction(s) --- .../owasp/dependencycheck/taskdefs/Check.java | 61 ++++--- .../org/slf4j/impl/StaticLoggerBinder.java | 27 ++- .../analyzer/AbstractSuppressionAnalyzer.java | 7 +- .../analyzer/AnalyzerService.java | 2 +- .../analyzer/FileNameAnalyzer.java | 6 +- .../dependencycheck/analyzer/JarAnalyzer.java | 162 +++++++++++------- .../analyzer/RubyBundleAuditAnalyzer.java | 20 ++- .../data/update/nvd/DownloadTask.java | 1 + .../suppression/SuppressionParser.java | 4 +- .../analyzer/RubyBundleAuditAnalyzerTest.java | 25 ++- .../maven/BaseDependencyCheckMojo.java | 2 +- .../org/slf4j/impl/StaticLoggerBinder.java | 14 +- 12 files changed, 197 insertions(+), 134 deletions(-) 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 fc4fc9d3b..78f6e823a 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 @@ -86,8 +86,8 @@ public class Check extends Update { } /** - * Returns the path. If the path has not been initialized yet, this class is synchronized, and will instantiate the path - * object. + * Returns the path. If the path has not been initialized yet, this class is + * synchronized, and will instantiate the path object. * * @return the path */ @@ -109,7 +109,8 @@ public class Check extends Update { } /** - * Add a reference to a Path, FileSet, DirSet, or FileList defined elsewhere. + * Add a reference to a Path, FileSet, DirSet, or FileList defined + * elsewhere. * * @param r the reference to a path, fileset, dirset or filelist. */ @@ -121,7 +122,8 @@ public class Check extends Update { } /** - * If this is a reference, this method will add the referenced resource collection to the collection of paths. + * If this is a reference, this method will add the referenced resource + * collection to the collection of paths. * * @throws BuildException if the reference is not to a resource collection */ @@ -196,7 +198,8 @@ public class Check extends Update { } /** - * Specifies the destination directory for the generated Dependency-Check report. + * Specifies the destination directory for the generated Dependency-Check + * report. */ private String reportOutputDirectory = "."; @@ -218,9 +221,11 @@ public class Check extends Update { this.reportOutputDirectory = reportOutputDirectory; } /** - * 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 and the CVSS score is set to 11. The valid range - * for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail. + * 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 and the CVSS score is set + * to 11. The valid range for the fail build on CVSS is 0 to 11, where + * anything above 10 will not cause the build to fail. */ private float failBuildOnCVSS = 11; @@ -242,8 +247,8 @@ public class Check extends Update { this.failBuildOnCVSS = failBuildOnCVSS; } /** - * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default - * is true. + * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not + * recommended that this be turned to false. Default is true. */ private Boolean autoUpdate; @@ -295,7 +300,8 @@ public class Check extends Update { } /** - * The report format to be generated (HTML, XML, VULN, ALL). Default is HTML. + * The report format to be generated (HTML, XML, VULN, ALL). Default is + * HTML. */ private String reportFormat = "HTML"; @@ -383,7 +389,7 @@ public class Check extends Update { public void setEnableExperimental(Boolean enableExperimental) { this.enableExperimental = enableExperimental; } - + /** * Whether or not the Jar Analyzer is enabled. */ @@ -644,7 +650,8 @@ public class Check extends Update { /** * Set the value of pyDistributionAnalyzerEnabled. * - * @param pyDistributionAnalyzerEnabled new value of pyDistributionAnalyzerEnabled + * @param pyDistributionAnalyzerEnabled new value of + * pyDistributionAnalyzerEnabled */ public void setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) { this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled; @@ -697,7 +704,8 @@ public class Check extends Update { } /** - * The URL of a Nexus server's REST API end point (http://domain/nexus/service/local). + * The URL of a Nexus server's REST API end point + * (http://domain/nexus/service/local). */ private String nexusUrl; @@ -742,8 +750,8 @@ public class Check extends Update { } /** - * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat like ZIP - * files. + * Additional ZIP File extensions to add analyze. This should be a + * comma-separated list of file extensions to treat like ZIP files. */ private String zipExtensions; @@ -853,7 +861,8 @@ public class Check extends Update { } /** - * Validate the configuration to ensure the parameters have been properly configured/initialized. + * Validate the configuration to ensure the parameters have been properly + * configured/initialized. * * @throws BuildException if the task was not configured correctly. */ @@ -867,8 +876,9 @@ public class Check extends Update { } /** - * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties - * required to change the proxy server, port, and connection timeout. + * Takes the properties supplied and updates the dependency-check settings. + * Additionally, this sets the system properties required to change the + * proxy server, port, and connection timeout. * * @throws BuildException thrown when an invalid setting is configured. */ @@ -899,11 +909,12 @@ public class Check extends Update { } /** - * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the - * configuration. + * Checks to see if a vulnerability has been identified with a CVSS score + * that is above the threshold set in the configuration. * * @param dependencies the list of dependency objects - * @throws BuildException thrown if a CVSS score is found that is higher then the threshold set + * @throws BuildException thrown if a CVSS score is found that is higher + * then the threshold set */ private void checkForFailure(List dependencies) throws BuildException { final StringBuilder ids = new StringBuilder(); @@ -927,7 +938,8 @@ public class Check extends Update { } /** - * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries. + * Generates a warning message listing a summary of dependencies and their + * associated CPE and CVE entries. * * @param dependencies a list of dependency objects */ @@ -967,7 +979,8 @@ public class Check extends Update { } /** - * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", etc.. + * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", + * etc.. */ public static class ReportFormats extends EnumeratedAttribute { diff --git a/dependency-check-ant/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/dependency-check-ant/src/main/java/org/slf4j/impl/StaticLoggerBinder.java index c7d3bd93b..92c87d3e1 100644 --- a/dependency-check-ant/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/dependency-check-ant/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -23,16 +23,18 @@ import org.slf4j.ILoggerFactory; import org.slf4j.spi.LoggerFactoryBinder; /** - * The binding of org.slf4j.LoggerFactory class with an actual instance of org.slf4j.ILoggerFactory is performed using information - * returned by this class. + * The binding of org.slf4j.LoggerFactory class with an actual instance of + * org.slf4j.ILoggerFactory is performed using information returned by this + * class. * * @author colezlaw */ +//CSOFF: FinalClass public class StaticLoggerBinder implements LoggerFactoryBinder { +//CSON: FinalClass /** * The unique instance of this class - * */ private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder(); @@ -46,7 +48,8 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { } /** - * Ant tasks have the log method we actually want to call. So we hang onto the task as a delegate + * Ant tasks have the log method we actually want to call. So we hang onto + * the task as a delegate */ private Task task = null; @@ -61,16 +64,24 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { } /** - * Declare the version of the SLF4J API this implementation is compiled against. The value of this filed is usually modified - * with each release. + * Declare the version of the SLF4J API this implementation is compiled + * against. The value of this filed is usually modified with each release. */ // to avoid constant folding by the compiler, this field must *not* be final + //CSOFF: StaticVariableName + //CSOFF: VisibilityModifier public static String REQUESTED_API_VERSION = "1.7.12"; // final - + //CSON: VisibilityModifier + //CSON: StaticVariableName + + /** + * The logger factory class string. + */ private static final String LOGGER_FACTORY_CLASS = AntLoggerFactory.class.getName(); /** - * The ILoggerFactory instance returned by the {@link #getLoggerFactory} method should always be the smae object + * The ILoggerFactory instance returned by the {@link #getLoggerFactory} + * method should always be the smae object */ private ILoggerFactory loggerFactory; diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java index 97c0719d5..812f70394 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java @@ -24,7 +24,6 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.List; import java.util.Set; -import java.util.logging.Level; import java.util.regex.Pattern; import org.owasp.dependencycheck.suppression.SuppressionParseException; import org.owasp.dependencycheck.suppression.SuppressionParser; @@ -38,7 +37,8 @@ import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; /** - * Abstract base suppression analyzer that contains methods for parsing the suppression xml file. + * Abstract base suppression analyzer that contains methods for parsing the + * suppression xml file. * * @author Jeremy Long */ @@ -173,7 +173,8 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { * * @param message the exception message * @param exception the cause of the exception - * @throws SuppressionParseException throws the generated SuppressionParseException + * @throws SuppressionParseException throws the generated + * SuppressionParseException */ private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException { LOGGER.warn(message); diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java index 41a243021..e27f95649 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java @@ -57,7 +57,7 @@ public class AnalyzerService { * @return a list of Analyzers. */ public List getAnalyzers() { - List analyzers = new ArrayList(); + final List analyzers = new ArrayList(); final Iterator iterator = service.iterator(); boolean experimentalEnabled = false; try { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java index b7d23a3e3..0775e8a88 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java @@ -67,11 +67,13 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer { } // - // Python init files + /** + * Python init files + */ private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[] { "__init__.py", "__init__.pyc", - "__init__.pyo" + "__init__.pyo", }); /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java index c76e8199b..18218d583 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java @@ -60,7 +60,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Used to load a JAR file and collect information that can be used to determine the associated CPE. + * Used to load a JAR file and collect information that can be used to determine + * the associated CPE. * * @author Jeremy Long */ @@ -72,7 +73,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { */ private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class); /** - * The count of directories created during analysis. This is used for creating temporary directories. + * The count of directories created during analysis. This is used for + * creating temporary directories. */ private static int dirCount = 0; /** @@ -80,7 +82,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { */ private static final String NEWLINE = System.getProperty("line.separator"); /** - * A list of values in the manifest to ignore as they only result in false positives. + * A list of values in the manifest to ignore as they only result in false + * positives. */ private static final Set IGNORE_VALUES = newHashSet( "Sun Java System Application Server"); @@ -123,7 +126,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { "ipojo-extension", "eclipse-sourcereferences"); /** - * Deprecated Jar manifest attribute, that is, nonetheless, useful for analysis. + * Deprecated Jar manifest attribute, that is, nonetheless, useful for + * analysis. */ @SuppressWarnings("deprecation") private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID @@ -203,7 +207,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { // /** - * Returns the key used in the properties file to reference the analyzer's enabled property. + * Returns the key used in the properties file to reference the analyzer's + * enabled property. * * @return the analyzer's enabled property setting key */ @@ -213,12 +218,13 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE - * information. + * Loads a specified JAR file and collects information from the manifest and + * checksums to identify the correct CPE information. * * @param dependency the dependency to analyze. * @param engine the engine that is scanning the dependencies - * @throws AnalysisException is thrown if there is an error reading the JAR file. + * @throws AnalysisException is thrown if there is an error reading the JAR + * file. */ @Override public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { @@ -242,13 +248,15 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Attempts to find a pom.xml within the JAR file. If found it extracts information and adds it to the evidence. This will - * attempt to interpolate the strings contained within the pom.properties if one exists. + * Attempts to find a pom.xml within the JAR file. If found it extracts + * information and adds it to the evidence. This will attempt to interpolate + * the strings contained within the pom.properties if one exists. * * @param dependency the dependency being analyzed * @param classes a collection of class name information * @param engine the analysis engine, used to add additional dependencies - * @throws AnalysisException is thrown if there is an exception parsing the pom + * @throws AnalysisException is thrown if there is an exception parsing the + * pom * @return whether or not evidence was added to the dependency */ protected boolean analyzePOM(Dependency dependency, List classes, Engine engine) throws AnalysisException { @@ -329,12 +337,14 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Given a path to a pom.xml within a JarFile, this method attempts to load a sibling pom.properties if one exists. + * Given a path to a pom.xml within a JarFile, this method attempts to load + * a sibling pom.properties if one exists. * * @param path the path to the pom.xml within the JarFile * @param jar the JarFile to load the pom.properties from * @return a Properties object or null if no pom.properties was found - * @throws IOException thrown if there is an exception reading the pom.properties + * @throws IOException thrown if there is an exception reading the + * pom.properties */ private Properties retrievePomProperties(String path, final JarFile jar) throws IOException { Properties pomProperties = null; @@ -361,7 +371,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Searches a JarFile for pom.xml entries and returns a listing of these entries. + * Searches a JarFile for pom.xml entries and returns a listing of these + * entries. * * @param jar the JarFile to search * @return a list of pom.xml entries @@ -388,8 +399,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { * @param jar the jar file to extract the pom from * @param dependency the dependency being analyzed * @return returns the POM object - * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM - * {@link org.owasp.dependencycheck.xml.pom.Model} object + * @throws AnalysisException is thrown if there is an exception extracting + * or parsing the POM {@link org.owasp.dependencycheck.xml.pom.Model} object */ private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException { InputStream input = null; @@ -447,9 +458,10 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { * * @param dependency the dependency to set data on * @param pom the information from the pom - * @param classes a collection of ClassNameInformation - containing data about the fully qualified class names within the JAR - * file being analyzed - * @return true if there was evidence within the pom that we could use; otherwise false + * @param classes a collection of ClassNameInformation - containing data + * about the fully qualified class names within the JAR file being analyzed + * @return true if there was evidence within the pom that we could use; + * otherwise false */ public static boolean setPomEvidence(Dependency dependency, Model pom, List classes) { boolean foundSomething = false; @@ -571,12 +583,15 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Analyzes the path information of the classes contained within the JarAnalyzer to try and determine possible vendor or - * product names. If any are found they are stored in the packageVendor and packageProduct hashSets. + * Analyzes the path information of the classes contained within the + * JarAnalyzer to try and determine possible vendor or product names. If any + * are found they are stored in the packageVendor and packageProduct + * hashSets. * * @param classNames a list of class names * @param dependency a dependency to analyze - * @param addPackagesAsEvidence a flag indicating whether or not package names should be added as evidence. + * @param addPackagesAsEvidence a flag indicating whether or not package + * names should be added as evidence. */ protected void analyzePackageNames(List classNames, Dependency dependency, boolean addPackagesAsEvidence) { @@ -611,11 +626,13 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { /** *

- * Reads the manifest from the JAR file and collects the entries. Some vendorKey entries are:

+ * Reads the manifest from the JAR file and collects the entries. Some + * vendorKey entries are:

*
  • Implementation Title
  • *
  • Implementation Version
  • Implementation Vendor
  • - *
  • Implementation VendorId
  • Bundle Name
  • Bundle Version
  • Bundle Vendor
  • Bundle - * Description
  • Main Class
+ *
  • Implementation VendorId
  • Bundle Name
  • Bundle + * Version
  • Bundle Vendor
  • Bundle Description
  • Main + * Class
  • * However, all but a handful of specific entries are read in. * * @param dependency A reference to the dependency @@ -623,7 +640,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { * @return whether evidence was identified parsing the manifest * @throws IOException if there is an issue reading the JAR file */ - protected boolean parseManifest(Dependency dependency, List classInformation) throws IOException { + protected boolean parseManifest(Dependency dependency, List classInformation) + throws IOException { boolean foundSomething = false; JarFile jar = null; try { @@ -748,21 +766,19 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { addMatchingValues(classInformation, value, productEvidence); } else if (key.contains("license")) { addLicense(dependency, value); + } else if (key.contains("description")) { + addDescription(dependency, value, "manifest", key); } else { - if (key.contains("description")) { - addDescription(dependency, value, "manifest", key); - } else { - productEvidence.addEvidence(source, key, value, Confidence.LOW); - vendorEvidence.addEvidence(source, key, value, Confidence.LOW); - addMatchingValues(classInformation, value, vendorEvidence); - addMatchingValues(classInformation, value, productEvidence); - if (value.matches(".*\\d.*")) { - final StringTokenizer tokenizer = new StringTokenizer(value, " "); - while (tokenizer.hasMoreElements()) { - final String s = tokenizer.nextToken(); - if (s.matches("^[0-9.]+$")) { - versionEvidence.addEvidence(source, key, s, Confidence.LOW); - } + productEvidence.addEvidence(source, key, value, Confidence.LOW); + vendorEvidence.addEvidence(source, key, value, Confidence.LOW); + addMatchingValues(classInformation, value, vendorEvidence); + addMatchingValues(classInformation, value, productEvidence); + if (value.matches(".*\\d.*")) { + final StringTokenizer tokenizer = new StringTokenizer(value, " "); + while (tokenizer.hasMoreElements()) { + final String s = tokenizer.nextToken(); + if (s.matches("^[0-9.]+$")) { + versionEvidence.addEvidence(source, key, s, Confidence.LOW); } } } @@ -810,15 +826,18 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Adds a description to the given dependency. If the description contains one of the following strings beyond 100 characters, - * then the description used will be trimmed to that position: - *
    • "such as"
    • "like "
    • "will use "
    • "* uses "
    + * Adds a description to the given dependency. If the description contains + * one of the following strings beyond 100 characters, then the description + * used will be trimmed to that position: + *
    • "such as"
    • "like "
    • "will use "
    • "* uses + * "
    * * @param dependency a dependency * @param description the description * @param source the source of the evidence * @param key the "name" of the evidence - * @return if the description is trimmed, the trimmed version is returned; otherwise the original description is returned + * @return if the description is trimmed, the trimmed version is returned; + * otherwise the original description is returned */ public static String addDescription(Dependency dependency, String description, String source, String key) { if (dependency.getDescription() == null) { @@ -889,7 +908,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { /** * Initializes the JarAnalyzer. * - * @throws Exception is thrown if there is an exception creating a temporary directory + * @throws Exception is thrown if there is an exception creating a temporary + * directory */ @Override public void initializeFileTypeAnalyzer() throws Exception { @@ -920,11 +940,13 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Determines if the key value pair from the manifest is for an "import" type entry for package names. + * Determines if the key value pair from the manifest is for an "import" + * type entry for package names. * * @param key the key from the manifest * @param value the value from the manifest - * @return true or false depending on if it is believed the entry is an "import" entry + * @return true or false depending on if it is believed the entry is an + * "import" entry */ private boolean isImportPackage(String key, String value) { final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$"); @@ -933,8 +955,9 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Cycles through an enumeration of JarEntries, contained within the dependency, and returns a list of the class names. This - * does not include core Java package names (i.e. java.* or javax.*). + * Cycles through an enumeration of JarEntries, contained within the + * dependency, and returns a list of the class names. This does not include + * core Java package names (i.e. java.* or javax.*). * * @param dependency the dependency being analyzed * @return an list of fully qualified class names @@ -970,12 +993,16 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Cycles through the list of class names and places the package levels 0-3 into the provided maps for vendor and product. - * This is helpful when analyzing vendor/product as many times this is included in the package name. + * Cycles through the list of class names and places the package levels 0-3 + * into the provided maps for vendor and product. This is helpful when + * analyzing vendor/product as many times this is included in the package + * name. * * @param classNames a list of class names - * @param vendor HashMap of possible vendor names from package names (e.g. owasp) - * @param product HashMap of possible product names from package names (e.g. dependencycheck) + * @param vendor HashMap of possible vendor names from package names (e.g. + * owasp) + * @param product HashMap of possible product names from package names (e.g. + * dependencycheck) */ private void analyzeFullyQualifiedClassNames(List classNames, Map vendor, Map product) { @@ -1002,8 +1029,9 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Adds an entry to the specified collection and sets the Integer (e.g. the count) to 1. If the entry already exists in the - * collection then the Integer is incremented by 1. + * Adds an entry to the specified collection and sets the Integer (e.g. the + * count) to 1. If the entry already exists in the collection then the + * Integer is incremented by 1. * * @param collection a collection of strings and their occurrence count * @param key the key to add to the collection @@ -1017,9 +1045,10 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Cycles through the collection of class name information to see if parts of the package names are contained in the provided - * value. If found, it will be added as the HIGHEST confidence evidence because we have more then one source corroborating the - * value. + * Cycles through the collection of class name information to see if parts + * of the package names are contained in the provided value. If found, it + * will be added as the HIGHEST confidence evidence because we have more + * then one source corroborating the value. * * @param classes a collection of class name information * @param value the value to check to see if it contains a package name @@ -1042,7 +1071,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Simple check to see if the attribute from a manifest is just a package name. + * Simple check to see if the attribute from a manifest is just a package + * name. * * @param key the key of the value to check * @param value the value to check @@ -1056,7 +1086,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Extracts the license information from the pom and adds it to the dependency. + * Extracts the license information from the pom and adds it to the + * dependency. * * @param pom the pom object * @param dependency the dependency to add license information too @@ -1103,9 +1134,11 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { /** *

    - * Stores information about a given class name. This class will keep the fully qualified class name and a list of the - * important parts of the package structure. Up to the first four levels of the package structure are stored, excluding a - * leading "org" or "com". Example:

    + * Stores information about a given class name. This class will keep the + * fully qualified class name and a list of the important parts of the + * package structure. Up to the first four levels of the package + * structure are stored, excluding a leading "org" or "com". + * Example:

    * ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer"); * System.out.println(obj.getName()); * for (String p : obj.getPackageStructure()) @@ -1164,7 +1197,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { this.name = name; } /** - * Up to the first four levels of the package structure, excluding a leading "org" or "com". + * Up to the first four levels of the package structure, excluding a + * leading "org" or "com". */ private final ArrayList packageStructure = new ArrayList(); diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java index 5e4f90afa..940d50cbf 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java @@ -17,6 +17,15 @@ */ package org.owasp.dependencycheck.analyzer; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.apache.commons.io.FileUtils; import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.analyzer.exception.AnalysisException; @@ -30,9 +39,6 @@ import org.owasp.dependencycheck.utils.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.*; -import java.util.*; -import java.util.logging.Level; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; /** @@ -62,10 +68,8 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { public static final String ADVISORY = "Advisory: "; public static final String CRITICALITY = "Criticality: "; - public CveDB cvedb; - //instance.open(); - //Vulnerability result = instance.getVulnerability("CVE-2015-3225"); - + private CveDB cvedb; + /** * @return a filter that accepts files named Gemfile.lock */ @@ -237,7 +241,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } catch (IOException ioe) { LOGGER.warn("bundle-audit failure", ioe); } finally { - if (errReader!= null) { + if (errReader != null) { try { errReader.close(); } catch (IOException ioe) { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/nvd/DownloadTask.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/nvd/DownloadTask.java index 1ec66a517..020c2263c 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/nvd/DownloadTask.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/nvd/DownloadTask.java @@ -261,6 +261,7 @@ public class DownloadTask implements Callable> { try { is.close(); } catch (IOException ex) { + LOGGER.debug("Error closing stream", ex); } } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParser.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParser.java index e4956ed1b..4d368fb3c 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParser.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParser.java @@ -25,7 +25,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.List; -import java.util.logging.Level; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -110,7 +109,8 @@ public class SuppressionParser { * * @param inputStream an InputStream containing suppression rues * @return a list of suppression rules - * @throws SuppressionParseException if the xml cannot be parsed + * @throws SuppressionParseException thrown if the xml cannot be parsed + * @throws SAXException thrown if the xml cannot be parsed */ public List parseSuppressionRules(InputStream inputStream) throws SuppressionParseException, SAXException { try { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java index 68436e92e..4eabdcab9 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java @@ -59,7 +59,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseTest { */ @Before public void setUp() throws Exception { - Settings.initialize(); + Settings.initialize(); analyzer = new RubyBundleAuditAnalyzer(); analyzer.setFilesMatched(true); } @@ -71,7 +71,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseTest { */ @After public void tearDown() throws Exception { - Settings.cleanup(); + Settings.cleanup(); analyzer.close(); analyzer = null; } @@ -99,7 +99,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseTest { */ @Test public void testAnalysis() throws AnalysisException, DatabaseException { - try { + try { analyzer.initialize(); final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, @@ -113,7 +113,6 @@ public class RubyBundleAuditAnalyzerTest extends BaseTest { assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); - } catch (Exception e) { LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\".", e); Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); @@ -133,7 +132,6 @@ public class RubyBundleAuditAnalyzerTest extends BaseTest { final Engine engine = new Engine(); analyzer.analyze(result, engine); - Dependency dependency = engine.getDependencies().get(0); Vulnerability vulnerability = dependency.getVulnerabilities().first(); assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0); @@ -144,7 +142,6 @@ public class RubyBundleAuditAnalyzerTest extends BaseTest { } } - /** * Test when Ruby bundle-audit is not available on the system. * @@ -152,19 +149,17 @@ public class RubyBundleAuditAnalyzerTest extends BaseTest { */ @Test public void testMissingBundleAudit() throws AnalysisException, DatabaseException { - //set a non-exist bundle-audit + //set a non-exist bundle-audit Settings.setString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, "phantom-bundle-audit"); try { //initialize should fail. - analyzer.initialize(); - } catch (Exception e) { - //expected, so ignore. - } - finally { - assertThat(analyzer.isEnabled(), is(false)); - LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); + analyzer.initialize(); + } catch (Exception e) { + //expected, so ignore. + } finally { + assertThat(analyzer.isEnabled(), is(false)); + LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); } } - } 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 1fd81babe..070c6e693 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 @@ -688,7 +688,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } } Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); - + Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); if (externalReport != null) { diff --git a/dependency-check-maven/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/dependency-check-maven/src/main/java/org/slf4j/impl/StaticLoggerBinder.java index bb9c6f538..af66c7ee3 100644 --- a/dependency-check-maven/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/dependency-check-maven/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -23,8 +23,9 @@ import org.slf4j.ILoggerFactory; import org.slf4j.spi.LoggerFactoryBinder; /** - * The binding of org.slf4j.LoggerFactory class with an actual instance of org.slf4j.ILoggerFactory is performed using information - * returned by this class. + * The binding of org.slf4j.LoggerFactory class with an actual instance of + * org.slf4j.ILoggerFactory is performed using information returned by this + * class. * * @author colezlaw */ @@ -47,7 +48,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { } /** - * Maven mojos have their own logger, so we'll use one of those + * Maven mojos have their own logger, so we'll use one of those. */ private Log log = null; @@ -62,8 +63,8 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { } /** - * Declare the version of the SLF4J API this implementation is compiled against. The value of this filed is usually modified - * with each release. + * Declare the version of the SLF4J API this implementation is compiled + * against. The value of this filed is usually modified with each release. */ // to avoid constant folding by the compiler, this field must *not* be final //CSOFF: StaticVariableName @@ -78,7 +79,8 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { private static final String LOGGER_FACTORY_CLASS = MavenLoggerFactory.class.getName(); /** - * The ILoggerFactory instance returned by the {@link #getLoggerFactory} method should always be the same object + * The ILoggerFactory instance returned by the {@link #getLoggerFactory} + * method should always be the same object */ private ILoggerFactory loggerFactory; From 0b26894112ca706d86ec73b08fb00a06826ef7d9 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 15 May 2016 07:48:26 -0400 Subject: [PATCH 08/55] checkstyle/pmd/findbugs correction(s) --- .../owasp/dependencycheck/analyzer/JarAnalyzer.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java index c43cd5c3b..4ffca8773 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java @@ -577,9 +577,9 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence()); addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); } - + String projectURL = pom.getProjectURL(); - if(projectURL != null && !projectURL.trim().isEmpty()) { + if (projectURL != null && !projectURL.trim().isEmpty()) { dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST); } @@ -645,7 +645,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { * @return whether evidence was identified parsing the manifest * @throws IOException if there is an issue reading the JAR file */ - protected boolean parseManifest(Dependency dependency, List classInformation) + protected boolean parseManifest(Dependency dependency, List classInformation) throws IOException { boolean foundSomething = false; JarFile jar = null; @@ -792,11 +792,10 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } } - final Map entries = manifest.getEntries(); - for (Iterator it = entries.keySet().iterator(); it.hasNext();) { - final String name = it.next(); + for (Map.Entry item : manifest.getEntries().entrySet()) { + final String name = item.getKey(); source = "manifest: " + name; - atts = entries.get(name); + atts = item.getValue(); for (Entry entry : atts.entrySet()) { final String key = entry.getKey().toString(); final String value = atts.getValue(key); From 7d83362a856e75a364017a300af079914cea326b Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 15 May 2016 07:49:17 -0400 Subject: [PATCH 09/55] removed stack trace from build when ruby and bundle-audit are not installed --- .../dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java index e72a672a3..756486450 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java @@ -121,7 +121,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { assertTrue(dependency.getFilePath().endsWith(resource)); assertTrue(dependency.getFileName().equals("Gemfile.lock")); } catch (Exception e) { - LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\".", e); + LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\"."); Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); } } From 425fd65bd82b6f21f63b695d85b7b893c90a2791 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 21 May 2016 07:09:08 -0400 Subject: [PATCH 10/55] added more false positive suppressions --- .../dependencycheck-base-suppression.xml | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml index 4bec87b70..f4bd0c491 100644 --- a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml +++ b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml @@ -319,4 +319,98 @@ .*\.(jar|exe|dll|ear|war|pom) cpe:/a:class:class + + + .*\.(jar|ear|war|pom) + cpe:/a:pam:pam + cpe:/a:pam_ssh:pam_ssh + + + + org\.elasticsearch:securesm:.* + cpe:/a:elasticsearch:elasticsearch + + + + org\.glassfish:javax.el:.* + cpe:/a:oracle:glassfish + + + + sslext:sslext:.* + cpe:/a:apache:struts + + + + org\.apache\.activemq:activemq-pool.* + cpe:/a:apache:activemq + + + + org\.apache\.activemq:artemis.* + cpe:/a:apache:activemq + + + + org\.springframework\.data:spring-data-mongodb.* + cpe:/a:mongodb:mongodb + + + + org\.springframework\.data:spring-data-neo4j:.* + cpe:/a:vmware:springsource_spring_framework + cpe:/a:pivotal:spring_framework + cpe:/a:neo4j:neo4j + + + + org\.springframework\.data:spring-data-solr:.* + cpe:/a:apache:solr + + + + org\.springframework\.social:spring-social-facebook:.* + cpe:/a:facebook:facebook + + + + org\.springframework\.security:spring-security-jwt.* + cpe:/a:vmware:springsource_spring_security + + + + org.eclipse.aether:aether.* + cpe:/a:eclipse:eclipse_ide + + + + .*\.(jar|ear|war|pom) + cpe:/a:services_project:services + From 2906b315b31998b2146f9ada846c6e1dd00f6c56 Mon Sep 17 00:00:00 2001 From: Tilmann H Date: Wed, 25 May 2016 11:36:09 +0200 Subject: [PATCH 11/55] Update initialize_mysql.sql lower cased "properties" in UPDATE statement --- .../src/main/resources/data/initialize_mysql.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependency-check-core/src/main/resources/data/initialize_mysql.sql b/dependency-check-core/src/main/resources/data/initialize_mysql.sql index 25bc5bd66..67e7b1a56 100644 --- a/dependency-check-core/src/main/resources/data/initialize_mysql.sql +++ b/dependency-check-core/src/main/resources/data/initialize_mysql.sql @@ -54,4 +54,4 @@ DELIMITER ; GRANT EXECUTE ON PROCEDURE dependencycheck.save_property TO 'dcuser'; -UPDATE Properties SET value='3.0' WHERE ID='version'; +UPDATE properties SET value='3.0' WHERE ID='version'; From 6a807bc002bbb0c869da9a8651935e6dc6abdf2d Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 25 May 2016 17:21:46 -0400 Subject: [PATCH 12/55] checkstyle/findbugs corrections --- .../org/slf4j/impl/StaticLoggerBinder.java | 2 +- .../analyzer/DependencyBundlingAnalyzer.java | 138 +++++++++------ .../analyzer/FileNameAnalyzer.java | 12 +- .../dependencycheck/analyzer/JarAnalyzer.java | 3 +- .../analyzer/PythonPackageAnalyzer.java | 25 +-- .../analyzer/RubyBundleAuditAnalyzer.java | 16 +- .../analyzer/RubyBundlerAnalyzer.java | 144 +++++++++------- .../analyzer/RubyGemspecAnalyzer.java | 163 +++++++++++------- .../dependency/Dependency.java | 88 ++++++---- .../owasp/dependencycheck/xml/pom/Model.java | 33 ++-- src/main/config/checkstyle-header.txt | 2 +- 11 files changed, 368 insertions(+), 258 deletions(-) diff --git a/dependency-check-ant/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/dependency-check-ant/src/main/java/org/slf4j/impl/StaticLoggerBinder.java index 92c87d3e1..3c96bb5b4 100644 --- a/dependency-check-ant/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/dependency-check-ant/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -73,7 +73,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { public static String REQUESTED_API_VERSION = "1.7.12"; // final //CSON: VisibilityModifier //CSON: StaticVariableName - + /** * The logger factory class string. */ diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java index fd6911e6f..419eacb09 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java @@ -35,11 +35,14 @@ import org.slf4j.LoggerFactory; /** *

    - * This analyzer ensures dependencies that should be grouped together, to remove excess noise from the report, are grouped. An - * example would be Spring, Spring Beans, Spring MVC, etc. If they are all for the same version and have the same relative path - * then these should be grouped into a single dependency under the core/main library.

    + * This analyzer ensures dependencies that should be grouped together, to remove + * excess noise from the report, are grouped. An example would be Spring, Spring + * Beans, Spring MVC, etc. If they are all for the same version and have the + * same relative path then these should be grouped into a single dependency + * under the core/main library.

    *

    - * Note, this grouping only works on dependencies with identified CVE entries

    + * Note, this grouping only works on dependencies with identified CVE + * entries

    * * @author Jeremy Long */ @@ -92,12 +95,14 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal // /** - * Analyzes a set of dependencies. If they have been found to have the same base path and the same set of identifiers they are - * likely related. The related dependencies are bundled into a single reportable item. + * Analyzes a set of dependencies. If they have been found to have the same + * base path and the same set of identifiers they are likely related. The + * related dependencies are bundled into a single reportable item. * * @param ignore this analyzer ignores the dependency being analyzed * @param engine the engine that is scanning the dependencies - * @throws AnalysisException is thrown if there is an error reading the JAR file. + * @throws AnalysisException is thrown if there is an error reading the JAR + * file. */ @Override public void analyze(Dependency ignore, Engine engine) throws AnalysisException { @@ -138,11 +143,11 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal mergeDependencies(nextDependency, dependency, dependenciesToRemove); break; //since we merged into the next dependency - skip forward to the next in mainIterator } - } else if ( isSameRubyGem(dependency, nextDependency) ) { - Dependency main = getMainGemspecDependency(dependency, nextDependency); - if (main == dependency) { - mergeDependencies(dependency, nextDependency, dependenciesToRemove); - } else { + } else if (isSameRubyGem(dependency, nextDependency)) { + final Dependency main = getMainGemspecDependency(dependency, nextDependency); + if (main == dependency) { + mergeDependencies(dependency, nextDependency, dependenciesToRemove); + } else { mergeDependencies(nextDependency, dependency, dependenciesToRemove); break; //since we merged into the next dependency - skip forward to the next in mainIterator } @@ -160,10 +165,11 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal * Adds the relatedDependency to the dependency's related dependencies. * * @param dependency the main dependency - * @param relatedDependency a collection of dependencies to be removed from the main analysis loop, this is the source of - * dependencies to remove - * @param dependenciesToRemove a collection of dependencies that will be removed from the main analysis loop, this function - * adds to this collection + * @param relatedDependency a collection of dependencies to be removed from + * the main analysis loop, this is the source of dependencies to remove + * @param dependenciesToRemove a collection of dependencies that will be + * removed from the main analysis loop, this function adds to this + * collection */ private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set dependenciesToRemove) { dependency.addRelatedDependency(relatedDependency); @@ -179,7 +185,8 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal } /** - * Attempts to trim a maven repo to a common base path. This is typically [drive]\[repo_location]\repository\[path1]\[path2]. + * Attempts to trim a maven repo to a common base path. This is typically + * [drive]\[repo_location]\repository\[path1]\[path2]. * * @param path the path to trim * @return a string representing the base path. @@ -204,11 +211,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal } /** - * Returns true if the file names (and version if it exists) of the two dependencies are sufficiently similar. + * Returns true if the file names (and version if it exists) of the two + * dependencies are sufficiently similar. * * @param dependency1 a dependency2 to compare * @param dependency2 a dependency2 to compare - * @return true if the identifiers in the two supplied dependencies are equal + * @return true if the identifiers in the two supplied dependencies are + * equal */ private boolean fileNameMatch(Dependency dependency1, Dependency dependency2) { if (dependency1 == null || dependency1.getFileName() == null @@ -236,11 +245,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal } /** - * Returns true if the CPE identifiers in the two supplied dependencies are equal. + * Returns true if the CPE identifiers in the two supplied dependencies are + * equal. * * @param dependency1 a dependency2 to compare * @param dependency2 a dependency2 to compare - * @return true if the identifiers in the two supplied dependencies are equal + * @return true if the identifiers in the two supplied dependencies are + * equal */ private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) { if (dependency1 == null || dependency1.getIdentifiers() == null @@ -310,37 +321,53 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal } return false; } - + /** - * Bundling Ruby gems that are identified from different .gemspec files but denote the same package path. - * This happens when Ruby bundler installs an app's dependencies by running "bundle install". + * Bundling Ruby gems that are identified from different .gemspec files but + * denote the same package path. This happens when Ruby bundler installs an + * application's dependencies by running "bundle install". + * + * @param dependency1 dependency to compare + * @param dependency2 dependency to compare + * @return true if the the dependencies being analyzed appear to be the + * same; otherwise false */ private boolean isSameRubyGem(Dependency dependency1, Dependency dependency2) { - if (dependency1 == null || dependency2 == null || - !dependency1.getFileName().endsWith(".gemspec") || - !dependency2.getFileName().endsWith(".gemspec") || - dependency1.getPackagePath() == null || - dependency2.getPackagePath() == null) { + if (dependency1 == null || dependency2 == null + || !dependency1.getFileName().endsWith(".gemspec") + || !dependency2.getFileName().endsWith(".gemspec") + || dependency1.getPackagePath() == null + || dependency2.getPackagePath() == null) { return false; } - if (dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath())) - return true; + if (dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath())) { + return true; + } - return false; + return false; } - + /** - * Ruby gems installed by "bundle install" can have zero or more *.gemspec files, all of which have the same packagePath and should be grouped. - * If one of these gemspec is from /specifications/*.gemspec, because it is a stub with fully resolved gem meta-data - * created by Ruby bundler, this dependency should be the main one. Otherwise, use dependency2 as main. - * - * This method returns null if any dependency is not from *.gemspec, or the two do not have the same packagePath. - * In this case, they should not be grouped. + * Ruby gems installed by "bundle install" can have zero or more *.gemspec + * files, all of which have the same packagePath and should be grouped. If + * one of these gemspec is from /specifications/*.gemspec, because + * it is a stub with fully resolved gem meta-data created by Ruby bundler, + * this dependency should be the main one. Otherwise, use dependency2 as + * main. + * + * This method returns null if any dependency is not from *.gemspec, or the + * two do not have the same packagePath. In this case, they should not be + * grouped. + * + * @param dependency1 dependency to compare + * @param dependency2 dependency to compare + * @return the main dependency; or null if a gemspec is not included in the + * analysis */ private Dependency getMainGemspecDependency(Dependency dependency1, Dependency dependency2) { - if (isSameRubyGem(dependency1, dependency2)) { - final File lFile = dependency1.getActualFile(); - File left = lFile.getParentFile(); + if (isSameRubyGem(dependency1, dependency2)) { + final File lFile = dependency1.getActualFile(); + final File left = lFile.getParentFile(); if (left != null && left.getName().equalsIgnoreCase("specifications")) { return dependency1; } @@ -350,12 +377,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal } /** - * This is likely a very broken attempt at determining if the 'left' dependency is the 'core' library in comparison to the - * 'right' library. + * This is likely a very broken attempt at determining if the 'left' + * dependency is the 'core' library in comparison to the 'right' library. * * @param left the dependency to test * @param right the dependency to test against - * @return a boolean indicating whether or not the left dependency should be considered the "core" version. + * @return a boolean indicating whether or not the left dependency should be + * considered the "core" version. */ boolean isCore(Dependency left, Dependency right) { final String leftName = left.getFileName().toLowerCase(); @@ -391,11 +419,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal } /** - * Compares the SHA1 hashes of two dependencies to determine if they are equal. + * Compares the SHA1 hashes of two dependencies to determine if they are + * equal. * * @param dependency1 a dependency object to compare * @param dependency2 a dependency object to compare - * @return true if the sha1 hashes of the two dependencies match; otherwise false + * @return true if the sha1 hashes of the two dependencies match; otherwise + * false */ private boolean hashesMatch(Dependency dependency1, Dependency dependency2) { if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) { @@ -405,12 +435,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal } /** - * Determines if the jar is shaded and the created pom.xml identified the same CPE as the jar - if so, the pom.xml dependency - * should be removed. + * Determines if the jar is shaded and the created pom.xml identified the + * same CPE as the jar - if so, the pom.xml dependency should be removed. * * @param dependency a dependency to check * @param nextDependency another dependency to check - * @return true if on of the dependencies is a pom.xml and the identifiers between the two collections match; otherwise false + * @return true if on of the dependencies is a pom.xml and the identifiers + * between the two collections match; otherwise false */ private boolean isShadedJar(Dependency dependency, Dependency nextDependency) { final String mainName = dependency.getFileName().toLowerCase(); @@ -424,12 +455,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal } /** - * Determines which path is shortest; if path lengths are equal then we use compareTo of the string method to determine if the - * first path is smaller. + * Determines which path is shortest; if path lengths are equal then we use + * compareTo of the string method to determine if the first path is smaller. * * @param left the first path to compare * @param right the second path to compare - * @return true if the leftPath is the shortest; otherwise false + * @return true if the leftPath is the shortest; otherwise + * false */ protected boolean firstPathIsShortest(String left, String right) { final String leftPath = left.replace('\\', '/'); diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java index d8edade74..fcaaeb102 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java @@ -70,7 +70,7 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer { /** * Python init files */ - private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[] { + private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{ "__init__.py", "__init__.pyc", "__init__.pyo", @@ -81,7 +81,8 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer { * * @param dependency the dependency to analyze. * @param engine the engine that is scanning the dependencies - * @throws AnalysisException is thrown if there is an error reading the JAR file. + * @throws AnalysisException is thrown if there is an error reading the JAR + * file. */ @Override public void analyze(Dependency dependency, Engine engine) throws AnalysisException { @@ -107,13 +108,6 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer { fileName, Confidence.MEDIUM); } - //add as vendor and product evidence -// if (fileName.contains("-")) { -// dependency.getProductEvidence().addEvidence("file", "name", -// fileName, Confidence.HIGHEST); -// dependency.getVendorEvidence().addEvidence("file", "name", -// fileName, Confidence.HIGHEST); -// } else if (!IGNORED_FILES.accept(f)) { dependency.getProductEvidence().addEvidence("file", "name", fileName, Confidence.HIGH); diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java index 4ffca8773..0423c5eeb 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -578,7 +577,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); } - String projectURL = pom.getProjectURL(); + final String projectURL = pom.getProjectURL(); if (projectURL != null && !projectURL.trim().isEmpty()) { dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST); } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java index 527892bce..9f12e0e95 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java @@ -39,7 +39,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * Used to analyze a Python package, and collect information that can be used to determine the associated CPE. + * Used to analyze a Python package, and collect information that can be used to + * determine the associated CPE. * * @author Dale Visser */ @@ -166,7 +167,8 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { * * @param dependency the dependency being analyzed * @param engine the engine being used to perform the scan - * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency + * @throws AnalysisException thrown if there is an unrecoverable error + * analyzing the dependency */ @Override protected void analyzeFileType(Dependency dependency, Engine engine) @@ -175,21 +177,20 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { final File parent = file.getParentFile(); final String parentName = parent.getName(); if (INIT_PY_FILTER.accept(file)) { - //by definition, the containing folder of __init__.py is considered the package, even the file is empty: - //"The __init__.py files are required to make Python treat the directories as containing packages" - //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html; + //by definition, the containing folder of __init__.py is considered the package, even the file is empty: + //"The __init__.py files are required to make Python treat the directories as containing packages" + //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html; dependency.setDisplayFileName(parentName + "/__init__.py"); dependency.getProductEvidence().addEvidence(file.getName(), "PackageName", parentName, Confidence.HIGHEST); - + final File[] fileList = parent.listFiles(PY_FILTER); if (fileList != null) { for (final File sourceFile : fileList) { analyzeFileContents(dependency, sourceFile); } } - } - else { + } else { // copy, alter and set in case some other thread is iterating over final List dependencies = new ArrayList( engine.getDependencies()); @@ -199,8 +200,9 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { } /** - * This should gather information from leading docstrings, file comments, and assignments to __version__, __title__, - * __summary__, __uri__, __url__, __home*page__, __author__, and their all caps equivalents. + * This should gather information from leading docstrings, file comments, + * and assignments to __version__, __title__, __summary__, __uri__, __url__, + * __home*page__, __author__, and their all caps equivalents. * * @param dependency the dependency being analyzed * @param file the file name to analyze @@ -291,7 +293,8 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Gather evidence from a Python source file using the given string assignment regex pattern. + * Gather evidence from a Python source file using the given string + * assignment regex pattern. * * @param pattern to scan contents with * @param contents of Python source file diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java index ea26ce227..003f4ed26 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java @@ -61,8 +61,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { */ private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION; - private static final FileFilter FILTER - = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build(); + private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build(); public static final String NAME = "Name: "; public static final String VERSION = "Version: "; public static final String ADVISORY = "Advisory: "; @@ -81,7 +80,9 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { /** * Launch bundle-audit. * + * @param folder directory that contains bundle audit * @return a handle to the process + * @throws AnalysisException thrown when there is an issue launching bundle audit */ private Process launchBundleAudit(File folder) throws AnalysisException { if (!folder.isDirectory()) { @@ -131,7 +132,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { throw ae; } - int exitValue = process.waitFor(); + final int exitValue = process.waitFor(); if (0 == exitValue) { LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue); setEnabled(false); @@ -236,7 +237,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { try { errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); while (errReader.ready()) { - String error = errReader.readLine(); + final String error = errReader.readLine(); LOGGER.warn(error); } rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); @@ -284,7 +285,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { dependency = map.get(gem); LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); } else if (nextLine.startsWith(VERSION)) { - vulnerability = createVulnerability(parentName, dependency, vulnerability, gem, nextLine); + vulnerability = createVulnerability(parentName, dependency, gem, nextLine); } else if (nextLine.startsWith(ADVISORY)) { setVulnerabilityName(parentName, dependency, vulnerability, nextLine); } else if (nextLine.startsWith(CRITICALITY)) { @@ -318,7 +319,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { final String url = nextLine.substring(("URL: ").length()); if (null != vulnerability) { - Reference ref = new Reference(); + final Reference ref = new Reference(); ref.setName(vulnerability.getName()); ref.setSource("bundle-audit"); ref.setUrl(url); @@ -351,7 +352,8 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); } - private Vulnerability createVulnerability(String parentName, Dependency dependency, Vulnerability vulnerability, String gem, String nextLine) { + private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) { + Vulnerability vulnerability = null; if (null != dependency) { final String version = nextLine.substring(VERSION.length()); dependency.getVersionEvidence().addEvidence( diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java index 05bfddb89..bdaafd443 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java @@ -25,20 +25,23 @@ import org.owasp.dependencycheck.analyzer.exception.AnalysisException; import org.owasp.dependencycheck.dependency.Dependency; /** - * This analyzer accepts the fully resolved .gemspec created by the Ruby bundler (http://bundler.io) - * for better evidence results. It also tries to resolve the dependency packagePath - * to where the gem is actually installed. Then during {@link AnalysisPhase.PRE_FINDING_ANALYSIS} - * {@link DependencyBundlingAnalyzer} will merge two .gemspec dependencies together if - * Dependency.getPackagePath() are the same. - * - * Ruby bundler creates new .gemspec files under a folder called "specifications" at deploy time, - * in addition to the original .gemspec files from source. The bundler generated - * .gemspec files always contain fully resolved attributes thus provide more accurate - * evidences, whereas the original .gemspec from source often contain variables for attributes - * that can't be used for evidences. - * - * Note this analyzer share the same {@link Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED} as - * {@link RubyGemspecAnalyzer}, so it will enabled/disabled with {@link RubyGemspecAnalyzer}. + * This analyzer accepts the fully resolved .gemspec created by the Ruby bundler + * (http://bundler.io) for better evidence results. It also tries to resolve the + * dependency packagePath to where the gem is actually installed. Then during {@link AnalysisPhase.PRE_FINDING_ANALYSIS} + * {@link DependencyBundlingAnalyzer} will merge two .gemspec dependencies + * together if Dependency.getPackagePath() are the same. + * + * Ruby bundler creates new .gemspec files under a folder called + * "specifications" at deploy time, in addition to the original .gemspec files + * from source. The bundler generated .gemspec files always contain fully + * resolved attributes thus provide more accurate evidences, whereas the + * original .gemspec from source often contain variables for attributes that + * can't be used for evidences. + * + * Note this analyzer share the same + * {@link Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED} as + * {@link RubyGemspecAnalyzer}, so it will enabled/disabled with + * {@link RubyGemspecAnalyzer}. * * @author Bianca Jiang (biancajiang@gmail.com) */ @@ -48,12 +51,16 @@ public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer { * The name of the analyzer. */ private static final String ANALYZER_NAME = "Ruby Bundler Analyzer"; - - //Folder name that contains .gemspec files created by "bundle install" - private static final String SPECIFICATIONS = "specifications"; - - //Folder name that contains the gems by "bundle install" - private static final String GEMS = "gems"; + + /** + * Folder name that contains .gemspec files created by "bundle install" + */ + private static final String SPECIFICATIONS = "specifications"; + + /** + * Folder name that contains the gems by "bundle install" + */ + private static final String GEMS = "gems"; /** * Returns the name of the analyzer. @@ -66,61 +73,66 @@ public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer { } /** - * Only accept *.gemspec files generated by "bundle install --deployment" under "specifications" folder. + * Only accept *.gemspec files generated by "bundle install --deployment" + * under "specifications" folder. + * + * @param pathname the path name to test + * @return true if the analyzer can process the given file; otherwise false */ - @Override + @Override public boolean accept(File pathname) { - + boolean accepted = super.accept(pathname); - if(accepted == true) { - File parentDir = pathname.getParentFile(); - accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS); + if (accepted) { + final File parentDir = pathname.getParentFile(); + accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS); } - + return accepted; } - - @Override + + @Override protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { super.analyzeFileType(dependency, engine); - + //find the corresponding gem folder for this .gemspec stub by "bundle install --deployment" - File gemspecFile = dependency.getActualFile(); - String gemFileName = gemspecFile.getName(); + final File gemspecFile = dependency.getActualFile(); + final String gemFileName = gemspecFile.getName(); final String gemName = gemFileName.substring(0, gemFileName.lastIndexOf(".gemspec")); - File specificationsDir = gemspecFile.getParentFile(); - if(specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) { - File parentDir = specificationsDir.getParentFile(); - if(parentDir != null && parentDir.exists()) { - File gemsDir = new File(parentDir, GEMS); - if(gemsDir != null && gemsDir.exists()) { - File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.equals(gemName); - } - }); - - if(matchingFiles.length > 0) { - String gemPath = matchingFiles[0].getAbsolutePath(); - if(dependency.getActualFilePath().equals(dependency.getFilePath())) { - if(gemPath != null) - dependency.setPackagePath(gemPath); - } else { - //.gemspec's actualFilePath and filePath are different when it's from a compressed file - //in which case actualFilePath is the temp directory used by decompression. - //packagePath should use the filePath of the identified gem file in "gems" folder - File gemspecStub = new File(dependency.getFilePath()); - File specDir = gemspecStub.getParentFile(); - if(specDir != null && specDir.getName().equals(SPECIFICATIONS)) { - File gemsDir2 = new File(specDir.getParentFile(), GEMS); - File packageDir = new File(gemsDir2, gemName); - dependency.setPackagePath(packageDir.getAbsolutePath()); - } - } - } - } - } - } - } + final File specificationsDir = gemspecFile.getParentFile(); + if (specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) { + final File parentDir = specificationsDir.getParentFile(); + if (parentDir != null && parentDir.exists()) { + final File gemsDir = new File(parentDir, GEMS); + if (gemsDir.exists()) { + final File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.equals(gemName); + } + }); + + if (matchingFiles != null && matchingFiles.length > 0) { + final String gemPath = matchingFiles[0].getAbsolutePath(); + if (dependency.getActualFilePath().equals(dependency.getFilePath())) { + if (gemPath != null) { + dependency.setPackagePath(gemPath); + } + } else { + //.gemspec's actualFilePath and filePath are different when it's from a compressed file + //in which case actualFilePath is the temp directory used by decompression. + //packagePath should use the filePath of the identified gem file in "gems" folder + final File gemspecStub = new File(dependency.getFilePath()); + final File specDir = gemspecStub.getParentFile(); + if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) { + final File gemsDir2 = new File(specDir.getParentFile(), GEMS); + final File packageDir = new File(gemsDir2, gemName); + dependency.setPackagePath(packageDir.getAbsolutePath()); + } + } + } + } + } + } + } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java index 8bad7cab2..2ee96b9db 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java @@ -34,15 +34,22 @@ import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.dependency.EvidenceCollection; import org.owasp.dependencycheck.utils.FileFilterBuilder; import org.owasp.dependencycheck.utils.Settings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * Used to analyze Ruby Gem specifications and collect information that can be used to determine the associated CPE. Regular - * expressions are used to parse the well-defined Ruby syntax that forms the specification. + * Used to analyze Ruby Gem specifications and collect information that can be + * used to determine the associated CPE. Regular expressions are used to parse + * the well-defined Ruby syntax that forms the specification. * * @author Dale Visser */ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { + /** + * The logger. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class); /** * The name of the analyzer. */ @@ -53,13 +60,22 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { */ private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; + /** + * The gemspec file extension. + */ private static final String GEMSPEC = "gemspec"; - private static final FileFilter FILTER - = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build(); - //TODO: support Rakefile - //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build(); + /** + * The file filter containing the list of file extensions that can be + * analyzed. + */ + private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build(); + //TODO: support Rakefile + //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build(); + /** + * The name of the version file. + */ private static final String VERSION_FILE_NAME = "VERSION"; /** @@ -96,7 +112,8 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Returns the key used in the properties file to reference the analyzer's enabled property. + * Returns the key used in the properties file to reference the analyzer's + * enabled property. * * @return the analyzer's enabled property setting key */ @@ -108,8 +125,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { /** * The capture group #1 is the block variable. */ - private static final Pattern GEMSPEC_BLOCK_INIT - = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); + private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); @Override protected void analyzeFileType(Dependency dependency, Engine engine) @@ -125,7 +141,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { if (matcher.find()) { contents = contents.substring(matcher.end()); final String blockVariable = matcher.group(1); - + final EvidenceCollection vendor = dependency.getVendorEvidence(); final EvidenceCollection product = dependency.getProductEvidence(); final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST); @@ -138,71 +154,90 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM); addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST); addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST); - - String value = addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", "version", Confidence.HIGHEST); - if(value.length() < 1) - addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence()); + + final String value = addStringEvidence(dependency.getVersionEvidence(), contents, + blockVariable, "version", "version", Confidence.HIGHEST); + if (value.length() < 1) { + addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence()); + } } - + setPackagePath(dependency); } + /** + * Adds the specified evidence to the given evidence collection. + * + * @param evidences the collection to add the evidence to + * @param contents the evidence contents + * @param blockVariable the variable + * @param field the field + * @param fieldPattern the field pattern + * @param confidence the confidence of the evidence + * @return the evidence string value added + */ private String addStringEvidence(EvidenceCollection evidences, String contents, String blockVariable, String field, String fieldPattern, Confidence confidence) { String value = ""; - - //capture array value between [ ] - final Matcher arrayMatcher = Pattern.compile( + + //capture array value between [ ] + final Matcher arrayMatcher = Pattern.compile( String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); - if(arrayMatcher.find()) { - String arrayValue = arrayMatcher.group(1); - value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes - } - //capture single value between quotes - else { - final Matcher matcher = Pattern.compile( - String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); - if (matcher.find()) { - value = matcher.group(2); - } - } - if(value.length() > 0) - evidences.addEvidence(GEMSPEC, field, value, confidence); - + if (arrayMatcher.find()) { + final String arrayValue = arrayMatcher.group(1); + value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes + } else { //capture single value between quotes + final Matcher matcher = Pattern.compile( + String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); + if (matcher.find()) { + value = matcher.group(2); + } + } + if (value.length() > 0) { + evidences.addEvidence(GEMSPEC, field, value, confidence); + } + return value; } - - private String addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) { - String value = null; - File parentDir = dependencyFile.getParentFile(); - if(parentDir != null) { - File[] matchingFiles = parentDir.listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.contains(VERSION_FILE_NAME); - } - }); - - for(int i = 0; i < matchingFiles.length; i++) { - try { - List lines = FileUtils.readLines(matchingFiles[i]); - if(lines.size() == 1) { //TODO other checking? - value = lines.get(0).trim(); - versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH); - } - - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - return value; + + /** + * Adds evidence from the version file. + * + * @param dependencyFile the dependency being analyzed + * @param versionEvidences the version evidence + */ + private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) { + final File parentDir = dependencyFile.getParentFile(); + if (parentDir != null) { + final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.contains(VERSION_FILE_NAME); + } + }); + for (File f : matchingFiles) { + try { + final List lines = FileUtils.readLines(f, Charset.defaultCharset()); + if (lines.size() == 1) { //TODO other checking? + final String value = lines.get(0).trim(); + versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH); + } + } catch (IOException e) { + LOGGER.debug("Error reading gemspec", e); + } + } + } } - + + /** + * Sets the package path on the dependency. + * + * @param dep the dependency to alter + */ private void setPackagePath(Dependency dep) { - File file = new File(dep.getFilePath()); - String parent = file.getParent(); - if(parent != null) - dep.setPackagePath(parent); + final File file = new File(dep.getFilePath()); + final String parent = file.getParent(); + if (parent != null) { + dep.setPackagePath(parent); + } } } 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 37e6c5bb1..5e0d03eed 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 @@ -36,9 +36,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * A program dependency. This object is one of the core components within DependencyCheck. It is used to collect information about - * the dependency in the form of evidence. The Evidence is then used to determine if there are any known, published, - * vulnerabilities associated with the program dependency. + * A program dependency. This object is one of the core components within + * DependencyCheck. It is used to collect information about the dependency in + * the form of evidence. The Evidence is then used to determine if there are any + * known, published, vulnerabilities associated with the program dependency. * * @author Jeremy Long */ @@ -72,17 +73,31 @@ public class Dependency implements Serializable, Comparable { * The file name of the dependency. */ private String fileName; - + + /** + * The package path. + */ private String packagePath; + + /** + * Returns the package path. + * + * @return the package path + */ public String getPackagePath() { - return packagePath; - } + return packagePath; + } - public void setPackagePath(String packagePath) { - this.packagePath = packagePath; - } + /** + * Sets the package path. + * + * @param packagePath the package path + */ + public void setPackagePath(String packagePath) { + this.packagePath = packagePath; + } - /** + /** * The md5 hash of the dependency. */ private String md5sum; @@ -144,10 +159,12 @@ public class Dependency implements Serializable, Comparable { } /** - * Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack as I - * could not get the replace to work in the template itself. + * Returns the file name of the dependency with the backslash escaped for + * use in JavaScript. This is a complete hack as I could not get the replace + * to work in the template itself. * - * @return the file name of the dependency with the backslash escaped for use in JavaScript + * @return the file name of the dependency with the backslash escaped for + * use in JavaScript */ public String getFileNameForJavaScript() { return this.fileName.replace("\\", "\\\\"); @@ -199,9 +216,9 @@ public class Dependency implements Serializable, Comparable { * @param filePath the file path of the dependency */ public void setFilePath(String filePath) { - if(this.packagePath == null || this.packagePath.equals(this.filePath)) - this.packagePath = filePath; - + if (this.packagePath == null || this.packagePath.equals(this.filePath)) { + this.packagePath = filePath; + } this.filePath = filePath; } @@ -220,7 +237,8 @@ public class Dependency implements Serializable, Comparable { } /** - * Returns the file name to display in reports; if no display file name has been set it will default to the actual file name. + * Returns the file name to display in reports; if no display file name has + * been set it will default to the actual file name. * * @return the file name to display */ @@ -235,8 +253,9 @@ public class Dependency implements Serializable, Comparable { *

    * Gets the file path of the dependency.

    *

    - * NOTE: This may not be the actual path of the file on disk. The actual path of the file on disk can be obtained via - * the getActualFilePath().

    + * NOTE: This may not be the actual path of the file on disk. The + * actual path of the file on disk can be obtained via the + * getActualFilePath().

    * * @return the file path of the dependency */ @@ -299,7 +318,8 @@ public class Dependency implements Serializable, Comparable { } /** - * Adds an entry to the list of detected Identifiers for the dependency file. + * Adds an entry to the list of detected Identifiers for the dependency + * file. * * @param type the type of identifier (such as CPE) * @param value the value of the identifier @@ -311,7 +331,8 @@ public class Dependency implements Serializable, Comparable { } /** - * Adds an entry to the list of detected Identifiers for the dependency file. + * Adds an entry to the list of detected Identifiers for the dependency + * file. * * @param type the type of identifier (such as CPE) * @param value the value of the identifier @@ -362,7 +383,8 @@ public class Dependency implements Serializable, Comparable { } /** - * Adds an entry to the list of detected Identifiers for the dependency file. + * Adds an entry to the list of detected Identifiers for the dependency + * file. * * @param identifier the identifier to add */ @@ -594,8 +616,9 @@ public class Dependency implements Serializable, Comparable { private Set relatedDependencies = new TreeSet(); /** - * Get the value of {@link #relatedDependencies}. This field is used to collect other dependencies which really represent the - * same dependency, and may be presented as one item in reports. + * Get the value of {@link #relatedDependencies}. This field is used to + * collect other dependencies which really represent the same dependency, + * and may be presented as one item in reports. * * @return the value of relatedDependencies */ @@ -654,9 +677,11 @@ public class Dependency implements Serializable, Comparable { } /** - * Adds a related dependency. The internal collection is normally a {@link java.util.TreeSet}, which relies on - * {@link #compareTo(Dependency)}. A consequence of this is that if you attempt to add a dependency with the same file path - * (modulo character case) as one that is already in the collection, it won't get added. + * Adds a related dependency. The internal collection is normally a + * {@link java.util.TreeSet}, which relies on + * {@link #compareTo(Dependency)}. A consequence of this is that if you + * attempt to add a dependency with the same file path (modulo character + * case) as one that is already in the collection, it won't get added. * * @param dependency a reference to the related dependency */ @@ -706,7 +731,8 @@ public class Dependency implements Serializable, Comparable { } /** - * Implementation of the Comparable<Dependency> interface. The comparison is solely based on the file path. + * Implementation of the Comparable<Dependency> interface. The + * comparison is solely based on the file path. * * @param o a dependency to compare * @return an integer representing the natural ordering @@ -776,12 +802,14 @@ public class Dependency implements Serializable, Comparable { } /** - * Standard toString() implementation showing the filename, actualFilePath, and filePath. + * Standard toString() implementation showing the filename, actualFilePath, + * and filePath. * * @return the string representation of the file */ @Override public String toString() { - return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "', packagePath='" + packagePath + "'}"; + return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + + "', filePath='" + filePath + "', packagePath='" + packagePath + "'}"; } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/Model.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/Model.java index 2cecff585..1a78294f7 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/Model.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/Model.java @@ -260,7 +260,7 @@ public class Model { public void addLicense(License license) { licenses.add(license); } - + /** * The project URL. */ @@ -272,17 +272,17 @@ public class Model { * @return the value of projectURL */ public String getProjectURL() { - return projectURL; - } + return projectURL; + } /** * Set the value of projectURL. * - * @param parentVersion new value of projectURL + * @param projectURL new value of projectURL */ - public void setProjectURL(String projectURL) { - this.projectURL = projectURL; - } + public void setProjectURL(String projectURL) { + this.projectURL = projectURL; + } /** * Process the Maven properties file and interpolate all properties. @@ -308,11 +308,14 @@ public class Model { /** *

    - * A utility function that will interpolate strings based on values given in the properties file. It will also interpolate the - * strings contained within the properties file so that properties can reference other properties.

    + * A utility function that will interpolate strings based on values given in + * the properties file. It will also interpolate the strings contained + * within the properties file so that properties can reference other + * properties.

    *

    - * Note: if there is no property found the reference will be removed. In other words, if the interpolated string will - * be replaced with an empty string. + * Note: if there is no property found the reference will be removed. + * In other words, if the interpolated string will be replaced with an empty + * string. *

    *

    * Example:

    @@ -329,7 +332,8 @@ public class Model { *
    * * @param text the string that contains references to properties. - * @param properties a collection of properties that may be referenced within the text. + * @param properties a collection of properties that may be referenced + * within the text. * @return the interpolated text. */ public static String interpolateString(String text, Properties properties) { @@ -340,8 +344,9 @@ public class Model { return substitutor.replace(text); } - /** - * Utility class that can provide values from a Properties object to a StrSubstitutor. + /** + * Utility class that can provide values from a Properties object to a + * StrSubstitutor. */ private static class PropertyLookup extends StrLookup { diff --git a/src/main/config/checkstyle-header.txt b/src/main/config/checkstyle-header.txt index c2ceba9ef..2e87cd304 100644 --- a/src/main/config/checkstyle-header.txt +++ b/src/main/config/checkstyle-header.txt @@ -13,6 +13,6 @@ ^ \* See the License for the specific language governing permissions and\s*$ ^ \* limitations under the License\.\s*$ ^ \*\s*$ -^ \* Copyright \(c\) 201[0-9] (Jeremy Long|Steve Springett|The OWASP Foundation|Institute for Defense Analyses)\. All Rights Reserved\.\s*$ +^ \* Copyright \(c\) 201[0-9] (Jeremy Long|Steve Springett|Bianca Jiang|The OWASP Foundation|Institute for Defense Analyses)\. All Rights Reserved\.\s*$ ^ \*/\s*$ ^package From ae5a7660921ca10dbe4e3907c2c54dcacf244ce2 Mon Sep 17 00:00:00 2001 From: Jens Hausherr Date: Fri, 27 May 2016 15:07:59 +0200 Subject: [PATCH 13/55] Limit split to fix #503 --- .../dependencycheck/dependency/VulnerableSoftware.java | 2 +- .../dependency/VulnerableSoftwareTest.java | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java index 521cff011..3b0e0d440 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java @@ -73,7 +73,7 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp public void parseName(String cpeName) throws UnsupportedEncodingException { this.name = cpeName; if (cpeName != null && cpeName.length() > 7) { - final String[] data = cpeName.substring(7).split(":"); + final String[] data = cpeName.substring(7).split(":", 4); if (data.length >= 1) { this.setVendor(urlDecode(data[0])); } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java index 5fa12af18..69e38fd15 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java @@ -78,4 +78,14 @@ public class VulnerableSoftwareTest extends BaseTest { result = instance.compareTo(vs); assertEquals(expResult, result); } + + @Test + public void testParseCPE() { + VulnerableSoftware vs = new VulnerableSoftware(); + /* Version for test taken from CVE-2008-2079 */ + vs.setCpe("cpe:/a:mysql:mysql:5.0.0:alpha"); + assertEquals("mysql", vs.getVendor()); + assertEquals("mysql", vs.getProduct()); + assertEquals("5.0.0:alpha", vs.getVersion()); + } } From 1ecde9bbc1ec68bb93272d507a85c3386dc3409a Mon Sep 17 00:00:00 2001 From: Anthony Whitford Date: Sat, 28 May 2016 08:27:39 -0700 Subject: [PATCH 14/55] maven-jar-plugin 3.0.0 released; maven-resources-plugin 3.0.0 released. --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a6cabe1eb..7c9a74b7e 100644 --- a/pom.xml +++ b/pom.xml @@ -212,7 +212,7 @@ Copyright (c) 2012 - Jeremy Long org.apache.maven.plugins maven-jar-plugin - 2.6 + 3.0.0 org.apache.maven.plugins @@ -222,7 +222,7 @@ Copyright (c) 2012 - Jeremy Long org.apache.maven.plugins maven-resources-plugin - 2.7 + 3.0.0 org.apache.maven.plugins From 05d7aa898dcbe824c745afc8e882482fbb7b3034 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 30 May 2016 07:37:44 -0400 Subject: [PATCH 15/55] minor reformatting to reduce line length (checkstyle) --- .../dependencycheck/analyzer/RubyBundleAuditAnalyzer.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java index 003f4ed26..ea321aa51 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java @@ -82,7 +82,8 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { * * @param folder directory that contains bundle audit * @return a handle to the process - * @throws AnalysisException thrown when there is an issue launching bundle audit + * @throws AnalysisException thrown when there is an issue launching bundle + * audit */ private Process launchBundleAudit(File folder) throws AnalysisException { if (!folder.isDirectory()) { @@ -295,7 +296,9 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } else if (nextLine.startsWith("Description:")) { appendToDescription = true; if (null != vulnerability) { - vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 indicates unknown). See link below for full details. *** "); + vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. " + + "Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 " + + " indicates unknown). See link below for full details. *** "); } } else if (appendToDescription) { if (null != vulnerability) { From 446222e127b1b3843f0decced6dbd4a060efa94c Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 30 May 2016 07:59:18 -0400 Subject: [PATCH 16/55] removed unnecessary exclude --- dependency-check-core/pom.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/dependency-check-core/pom.xml b/dependency-check-core/pom.xml index fcf2641d0..d136b7cef 100644 --- a/dependency-check-core/pom.xml +++ b/dependency-check-core/pom.xml @@ -83,9 +83,6 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. ${basedir}/src/test/resources - - **/mysql-connector-java-5.1.27-bin.jar - false From 0394d1a24f0aeb860becd2eca4902863b87df40a Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 30 May 2016 07:59:53 -0400 Subject: [PATCH 17/55] checkstyle correction - reduced method length --- .../org/owasp/dependencycheck/analyzer/JarAnalyzer.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java index 0423c5eeb..42ee00277 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java @@ -652,7 +652,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { jar = new JarFile(dependency.getActualFilePath()); final Manifest manifest = jar.getManifest(); if (manifest == null) { - //don't log this for javadoc or sources jar files if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar") && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar") && !dependency.getFileName().toLowerCase().endsWith("-src.jar") @@ -669,7 +668,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { String source = "Manifest"; String specificationVersion = null; boolean hasImplementationVersion = false; - Attributes atts = manifest.getMainAttributes(); for (Entry entry : atts.entrySet()) { String key = entry.getKey().toString(); @@ -700,7 +698,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { foundSomething = true; addDescription(dependency, value, "manifest", key); - //productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); addMatchingValues(classInformation, value, productEvidence); } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { foundSomething = true; @@ -719,11 +716,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { //skipping main class as if this has important information to add // it will be added during class name analysis... if other fields // have the information from the class name then they will get added... -// foundSomething = true; -// productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -// vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -// addMatchingValues(classInformation, value, vendorEvidence); -// addMatchingValues(classInformation, value, productEvidence); } else { key = key.toLowerCase(); if (!IGNORE_KEYS.contains(key) @@ -737,7 +729,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { && !value.trim().startsWith("scm:") && !isImportPackage(key, value) && !isPackage(key, value)) { - foundSomething = true; if (key.contains("version")) { if (!key.contains("specification")) { From d13bbd43f3e4c89b2d356f116150584e84acbbf0 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 30 May 2016 08:09:14 -0400 Subject: [PATCH 18/55] added experimental flag to force users to enable this and by doing so understand that these may not be as production ready as the Java analyzer (see issue #498) --- .../org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.java | 1 + .../dependencycheck/analyzer/PythonDistributionAnalyzer.java | 1 + .../owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java | 1 + .../owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java | 1 + .../org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java | 1 + .../org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java | 1 + 6 files changed, 6 insertions(+) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.java index cd354b709..df68ac8d3 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.java @@ -41,6 +41,7 @@ import java.security.MessageDigest; * * @author colezlaw */ +@Experimental public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer { /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.java index 96b6d0656..5fdadf0e6 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.java @@ -50,6 +50,7 @@ import org.owasp.dependencycheck.utils.UrlStringUtils; * * @author Dale Visser */ +@Experimental public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java index 9f12e0e95..e0b8aa9ab 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java @@ -44,6 +44,7 @@ import java.util.regex.Pattern; * * @author Dale Visser */ +@Experimental public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java index ea321aa51..e361d9815 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java @@ -47,6 +47,7 @@ import org.owasp.dependencycheck.data.nvdcve.DatabaseException; * * @author Dale Visser */ +@Experimental public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class); diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java index bdaafd443..c8c4de17c 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java @@ -45,6 +45,7 @@ import org.owasp.dependencycheck.dependency.Dependency; * * @author Bianca Jiang (biancajiang@gmail.com) */ +@Experimental public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer { /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java index 2ee96b9db..43b373d0f 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java @@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory; * * @author Dale Visser */ +@Experimental public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { /** From 5b52f01f3d20083c3bac490481b3b721d7cf7efc Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 30 May 2016 08:23:58 -0400 Subject: [PATCH 19/55] updated documentation for issue#498 --- src/site/markdown/analyzers/autoconf.md | 4 ++++ src/site/markdown/analyzers/cmake.md | 4 ++++ src/site/markdown/analyzers/composer-lock.md | 4 ++++ src/site/markdown/analyzers/nodejs.md | 6 +++++- src/site/markdown/analyzers/python.md | 4 ++++ src/site/markdown/analyzers/ruby-gemspec.md | 6 +++++- 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/site/markdown/analyzers/autoconf.md b/src/site/markdown/analyzers/autoconf.md index 1a9badb37..5388cbf4d 100644 --- a/src/site/markdown/analyzers/autoconf.md +++ b/src/site/markdown/analyzers/autoconf.md @@ -1,6 +1,10 @@ Autoconf Analyzer ================= +*Experimental*: This analyzer is considered experimental. While this analyzer may +be useful and provide valid results more testing must be completed to ensure that +the false negative/false positive rates are acceptable. + OWASP dependency-check includes an analyzer that will scan Autoconf project configuration files. The analyzer will collect as much information it can about the project. The information collected is internally referred to as diff --git a/src/site/markdown/analyzers/cmake.md b/src/site/markdown/analyzers/cmake.md index 2cc0a1889..09baffff6 100644 --- a/src/site/markdown/analyzers/cmake.md +++ b/src/site/markdown/analyzers/cmake.md @@ -1,6 +1,10 @@ CMake Analyzer ============== +*Experimental*: This analyzer is considered experimental. While this analyzer may +be useful and provide valid results more testing must be completed to ensure that +the false negative/false positive rates are acceptable. + OWASP dependency-check includes an analyzer that will scan CMake project configuration files. The analyzer will collect as much information it can about the project. The information collected is internally referred to as diff --git a/src/site/markdown/analyzers/composer-lock.md b/src/site/markdown/analyzers/composer-lock.md index 64c88808d..b37f5ebe5 100644 --- a/src/site/markdown/analyzers/composer-lock.md +++ b/src/site/markdown/analyzers/composer-lock.md @@ -1,6 +1,10 @@ Composer Lock Analyzer ============== +*Experimental*: This analyzer is considered experimental. While this analyzer may +be useful and provide valid results more testing must be completed to ensure that +the false negative/false positive rates are acceptable. + OWASP dependency-check includes an analyzer that scans composer.lock files to get exact dependency version information from PHP projects which are managed with [Composer](http://getcomposer.org/). If you're using Composer to manage your project, this will only analyze the `composer.lock` file diff --git a/src/site/markdown/analyzers/nodejs.md b/src/site/markdown/analyzers/nodejs.md index 3920ba7bb..139bb7dc1 100644 --- a/src/site/markdown/analyzers/nodejs.md +++ b/src/site/markdown/analyzers/nodejs.md @@ -1,6 +1,10 @@ Node.js Analyzer ================ +*Experimental*: This analyzer is considered experimental. While this analyzer may +be useful and provide valid results more testing must be completed to ensure that +the false negative/false positive rates are acceptable. + OWASP dependency-check includes an analyzer that will scan [Node Package Manager](https://www.npmjs.com/) package specification files. The analyzer will collect as much information as it can about the package. The information collected is internally referred to @@ -8,7 +12,7 @@ as evidence and is grouped into vendor, product, and version buckets. Other analyzers later use this evidence to identify any Common Platform Enumeration (CPE) identifiers that apply. -Note:_Consider using [Retire.js](http://retirejs.github.io/retire.js/) or the +*Note*: Consider using [Retire.js](http://retirejs.github.io/retire.js/) or the Node Security Project auditing tool, [nsp](https://nodesecurity.io/tools) instead of, or in addition to OWASP dependency-check to analyze Node.js packages. diff --git a/src/site/markdown/analyzers/python.md b/src/site/markdown/analyzers/python.md index 7ad7eeee8..002251470 100644 --- a/src/site/markdown/analyzers/python.md +++ b/src/site/markdown/analyzers/python.md @@ -1,6 +1,10 @@ Python Analyzer ============== +*Experimental*: This analyzer is considered experimental. While this analyzer may +be useful and provide valid results more testing must be completed to ensure that +the false negative/false positive rates are acceptable. + OWASP dependency-check includes an analyzer that will scan Python artifacts. The analyzer(s) will collect as much information it can about the Python artifacts. The information collected is internally referred to as evidence and diff --git a/src/site/markdown/analyzers/ruby-gemspec.md b/src/site/markdown/analyzers/ruby-gemspec.md index 04116f442..ee3925782 100644 --- a/src/site/markdown/analyzers/ruby-gemspec.md +++ b/src/site/markdown/analyzers/ruby-gemspec.md @@ -1,6 +1,10 @@ Ruby Gemspec Analyzer ===================== +*Experimental*: This analyzer is considered experimental. While this analyzer may +be useful and provide valid results more testing must be completed to ensure that +the false negative/false positive rates are acceptable. + OWASP dependency-check includes an analyzer that will scan [Ruby Gem](https://rubygems.org/) [specifications](http://guides.rubygems.org/specification-reference/). The analyzer will collect as much information as it can about the Gem. The @@ -9,7 +13,7 @@ into vendor, product, and version buckets. Other analyzers later use this evidence to identify any Common Platform Enumeration (CPE) identifiers that apply. -Note: It is highly recommended that Ruby projects use +*Note*: It is highly recommended that Ruby projects use [bundler-audit](https://github.com/rubysec/bundler-audit#readme). Files Types Scanned: Rakefile, \*.gemspec \ No newline at end of file From a6b47c7c435c99237b8dd8bde1d33c6224250b1f Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Thu, 2 Jun 2016 19:23:51 -0400 Subject: [PATCH 20/55] clarified note --- src/site/markdown/data/index.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/site/markdown/data/index.md b/src/site/markdown/data/index.md index 74a2237f8..dac9b591a 100644 --- a/src/site/markdown/data/index.md +++ b/src/site/markdown/data/index.md @@ -29,4 +29,7 @@ contained within the JAR file itself, contain evidence that is used to accuratel a library. If Central cannot be reached, it is highly recommended to setup a Nexus server within your organization and to configure dependency-check to use the local Nexus server. **Note**, even with a Nexus server setup I have seen dependency-check be -re-directed to other repositories on the Internet to download the actual POM file. +re-directed to other repositories on the Internet to download the actual POM file; this +happened due to a rare circumstance where the Nexus instance used by dependency-check +was not the instance of Nexus used to build the application (i.e. the dependencies +were not actually present in the Nexus used by dependency-check). From 3c525d8e3abe061c685564eea8b80ec2be45e8f3 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Thu, 2 Jun 2016 19:30:38 -0400 Subject: [PATCH 21/55] fixed issue #505 --- .../owasp/dependencycheck/maven/BaseDependencyCheckMojo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 070c6e693..aff052420 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 @@ -1033,7 +1033,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma file = new File(writeTo, dataFileName); } final File parent = file.getParentFile(); - if (!parent.isDirectory() && parent.mkdirs()) { + if (!parent.isDirectory() && !parent.mkdirs()) { getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.", parent.getAbsolutePath())); } From 6d70c92795e723a5b813f53f48f97849afa00e87 Mon Sep 17 00:00:00 2001 From: Jens Hausherr Date: Fri, 3 Jun 2016 09:41:48 +0200 Subject: [PATCH 22/55] Add to String-Method to Reference --- .../java/org/owasp/dependencycheck/dependency/Reference.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Reference.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Reference.java index e8db33f17..3d4b2ee26 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Reference.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Reference.java @@ -97,6 +97,11 @@ public class Reference implements Serializable, Comparable { this.source = source; } + @Override + public String toString() { + return "Reference: { name='"+this.name+"', url='"+this.url+"', source='"+this.source+"' }"; + } + @Override public boolean equals(Object obj) { if (obj == null) { From f3d3a2585696e82ede5910327baf5496be6bc94a Mon Sep 17 00:00:00 2001 From: Jens Hausherr Date: Fri, 3 Jun 2016 09:50:05 +0200 Subject: [PATCH 23/55] Add more test cases --- .../dependency/VulnerabilityTest.java | 138 ++++++++++++++++++ .../dependency/VulnerableSoftwareTest.java | 46 +++++- 2 files changed, 179 insertions(+), 5 deletions(-) create mode 100644 dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerabilityTest.java diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerabilityTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerabilityTest.java new file mode 100644 index 000000000..550540b67 --- /dev/null +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerabilityTest.java @@ -0,0 +1,138 @@ +/* + * 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) 2013 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.dependency; + +import org.junit.After; +import org.junit.AfterClass; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; + +/** + * + * @author Jens Hausherr + */ +public class VulnerabilityTest extends BaseTest { + + /** + * Test of equals method, of class VulnerableSoftware. + */ + @Test + public void testDuplicateVersions() { + Vulnerability obj = new Vulnerability(); + + obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0"); + obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.1"); + obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0"); + + assertEquals(2, obj.getVulnerableSoftware().size()); + } + + @Test + public void testDpulicateVersionsWithPreviousVersion() { + Vulnerability obj = new Vulnerability(); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.0",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.1",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.2",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.10",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.11",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.12",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.13",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.14",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.15",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.16",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.17",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.18",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.19",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.20",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.21",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.22",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.23",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.0",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.0:alpha",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.1",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.10",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.10a",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.11",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.12",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.13",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.15",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.19",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.1a",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.2",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.3",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.4",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.5.0.21",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.6",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.9",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.21",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.22",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.23",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.24",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.24a",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.25",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.30",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.32",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.33",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.36",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.37",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.38",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.3a",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.41",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.42",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.44",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.45",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.4a",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.50",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.51",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.52",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.54",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.56",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.23a","1"); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.3",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.4",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.5",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.5a",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.6",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.7",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.9",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.11",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.12",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.14",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.15",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.16",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.17",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.18",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.19",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.20",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.21",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.22",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.23",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.23a",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:6.0.0",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:6.0.1",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:6.0.2",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:6.0.3",null); + obj.addVulnerableSoftware("cpe:/a:mysql:mysql:6.0.4",null); + assertEquals(82, obj.getVulnerableSoftware().size()); + } +} diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java index 69e38fd15..8789d25d1 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java @@ -20,6 +20,8 @@ package org.owasp.dependencycheck.dependency; import org.junit.After; import org.junit.AfterClass; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -40,9 +42,20 @@ public class VulnerableSoftwareTest extends BaseTest { obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); VulnerableSoftware instance = new VulnerableSoftware(); instance.setCpe("cpe:/a:mortbay:jetty:6.1"); - boolean expResult = false; - boolean result = instance.equals(obj); - assertEquals(expResult, result); + assertFalse(instance.equals(obj)); + } + + /** + * Test of equals method, of class VulnerableSoftware. + */ + @Test + public void testEquals2() { + VulnerableSoftware obj = new VulnerableSoftware(); + obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); + VulnerableSoftware instance = new VulnerableSoftware(); + instance.setCpe("cpe:/a:mortbay:jetty:6.1.0"); + obj.setPreviousVersion("1"); + assertTrue(instance.equals(obj)); } /** @@ -79,13 +92,36 @@ public class VulnerableSoftwareTest extends BaseTest { assertEquals(expResult, result); } + @Test + public void testCompareToNonNumerical(){ + VulnerableSoftware vs = new VulnerableSoftware(); + vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); + VulnerableSoftware vs1 = new VulnerableSoftware(); + vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); + vs1.setPreviousVersion("1"); + assertEquals(0, vs.compareTo(vs1)); + assertEquals(0, vs1.compareTo(vs)); + } + + @Test + public void testEqualsPreviousVersion() { + VulnerableSoftware vs = new VulnerableSoftware(); + vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); + VulnerableSoftware vs1 = new VulnerableSoftware(); + vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); + vs1.setPreviousVersion("1"); + assertEquals(vs,vs1); + assertEquals(vs1,vs); + + } + @Test public void testParseCPE() { VulnerableSoftware vs = new VulnerableSoftware(); /* Version for test taken from CVE-2008-2079 */ - vs.setCpe("cpe:/a:mysql:mysql:5.0.0:alpha"); + vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); assertEquals("mysql", vs.getVendor()); assertEquals("mysql", vs.getProduct()); - assertEquals("5.0.0:alpha", vs.getVersion()); + assertEquals("5.1.23a", vs.getVersion()); } } From fccd683b500f81bb5d4bd26369d49d7d4d84a197 Mon Sep 17 00:00:00 2001 From: Jens Hausherr Date: Fri, 3 Jun 2016 09:52:35 +0200 Subject: [PATCH 24/55] add toString() for Vulnerability --- .../dependency/Vulnerability.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java index 9fc097401..6d7b55d0f 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java @@ -18,7 +18,6 @@ package org.owasp.dependencycheck.dependency; import java.io.Serializable; -import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; @@ -33,6 +32,7 @@ public class Vulnerability implements Serializable, Comparable { * The serial version uid. */ private static final long serialVersionUID = 307319490326651052L; + /** * The name of the vulnerability. */ @@ -383,6 +383,24 @@ public class Vulnerability implements Serializable, Comparable { return hash; } + @Override + public String toString() { + StringBuilder sb = new StringBuilder("Vulnerability "); + sb.append(this.name); + sb.append("\nReferences:\n"); + for (Iterator i = this.references.iterator(); i.hasNext();) { + sb.append("=> "); + sb.append(i.next()); + sb.append("\n"); + } + sb.append("\nSoftware:\n"); + for (Iterator i = this.vulnerableSoftware.iterator(); i.hasNext();) { + sb.append("=> "); + sb.append(i.next()); + sb.append("\n"); + } + return sb.toString(); + } /** * Compares two vulnerabilities. * From 578dc63652734dbac31f2ab6d01ee9fb51b55685 Mon Sep 17 00:00:00 2001 From: Jens Hausherr Date: Fri, 3 Jun 2016 09:54:25 +0200 Subject: [PATCH 25/55] Vulnerable Software: Compact toString() output; remove accessor calls for own properties --- .../dependencycheck/dependency/VulnerableSoftware.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java index 3b0e0d440..3e46581e6 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java @@ -73,7 +73,7 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp public void parseName(String cpeName) throws UnsupportedEncodingException { this.name = cpeName; if (cpeName != null && cpeName.length() > 7) { - final String[] data = cpeName.substring(7).split(":", 4); + final String[] data = cpeName.substring(7).split(":"); if (data.length >= 1) { this.setVendor(urlDecode(data[0])); } @@ -138,7 +138,7 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp return false; } final VulnerableSoftware other = (VulnerableSoftware) obj; - if ((this.getName() == null) ? (other.getName() != null) : !this.getName().equals(other.getName())) { + if ((this.name == null) ? (other.getName() != null) : !this.name.equals(other.getName())) { return false; } return true; @@ -152,7 +152,7 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp @Override public int hashCode() { int hash = 7; - hash = 83 * hash + (this.getName() != null ? this.getName().hashCode() : 0); + hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0); return hash; } @@ -163,7 +163,7 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp */ @Override public String toString() { - return "VulnerableSoftware{ name=" + name + ", previousVersion=" + previousVersion + '}'; + return "VulnerableSoftware{" + name + "[" + previousVersion + "]}"; } /** @@ -175,7 +175,7 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp @Override public int compareTo(VulnerableSoftware vs) { int result = 0; - final String[] left = this.getName().split(":"); + final String[] left = this.name.split(":"); final String[] right = vs.getName().split(":"); final int max = (left.length <= right.length) ? left.length : right.length; if (max > 0) { From 1ba081959ba3afda67595d229cc2b14b01311f21 Mon Sep 17 00:00:00 2001 From: Jens Hausherr Date: Fri, 3 Jun 2016 10:09:28 +0200 Subject: [PATCH 26/55] Accidentially dropped some imports --- .../org/owasp/dependencycheck/dependency/Vulnerability.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java index 6d7b55d0f..ed278076b 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java @@ -18,8 +18,10 @@ package org.owasp.dependencycheck.dependency; import java.io.Serializable; +import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import java.util.Iterator; /** * Contains the information about a vulnerability. From e79da72711dc0f326fcdce52deab89e37c0d8230 Mon Sep 17 00:00:00 2001 From: Jens Hausherr Date: Fri, 27 May 2016 14:59:23 +0200 Subject: [PATCH 27/55] Use batch update for references and vulnerable software if supported by DB. --- .../dependencycheck/data/nvdcve/CveDB.java | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java index 037da7564..bc56f21fb 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java @@ -68,6 +68,11 @@ public class CveDB { */ private ResourceBundle statementBundle = null; + /** + * Does the underlying connection support batch operations? + */ + private boolean batchSupported; + /** * Creates a new CveDB object and opens the database connection. Note, the connection must be closed by the caller by calling * the close method. @@ -80,6 +85,7 @@ public class CveDB { open(); try { final String databaseProductName = conn.getMetaData().getDatabaseProductName(); + batchSupported = conn.getMetaData().supportsBatchUpdates(); LOGGER.debug("Database dialect: {}", databaseProductName); final Locale dbDialect = new Locale(databaseProductName); statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect); @@ -380,6 +386,7 @@ public class CveDB { ResultSet rsR = null; ResultSet rsS = null; Vulnerability vuln = null; + try { psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY")); psV.setString(1, cve); @@ -484,6 +491,7 @@ public class CveDB { } DBUtils.closeResultSet(rs); rs = null; + if (vulnerabilityId != 0) { if (vuln.getDescription().contains("** REJECT **")) { deleteVulnerability.setInt(1, vulnerabilityId); @@ -525,13 +533,24 @@ public class CveDB { rs = null; } } - insertReference.setInt(1, vulnerabilityId); + for (Reference r : vuln.getReferences()) { + insertReference.setInt(1, vulnerabilityId); insertReference.setString(2, r.getName()); insertReference.setString(3, r.getUrl()); insertReference.setString(4, r.getSource()); - insertReference.execute(); + + if (batchSupported) { + insertReference.addBatch(); + } else { + insertReference.execute(); + } } + + if (batchSupported) { + insertReference.executeBatch(); + } + for (VulnerableSoftware s : vuln.getVulnerableSoftware()) { int cpeProductId = 0; selectCpeId.setString(1, s.getName()); @@ -560,12 +579,22 @@ public class CveDB { insertSoftware.setInt(1, vulnerabilityId); insertSoftware.setInt(2, cpeProductId); + if (s.getPreviousVersion() == null) { insertSoftware.setNull(3, java.sql.Types.VARCHAR); } else { insertSoftware.setString(3, s.getPreviousVersion()); } - insertSoftware.execute(); + + if (batchSupported) { + insertSoftware.addBatch(); + } else { + insertSoftware.execute(); + } + } + + if (batchSupported) { + insertSoftware.executeBatch(); } } catch (SQLException ex) { From cd5f9e2f13c935f5a76af097b09faaa322903707 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 4 Jun 2016 07:42:58 -0400 Subject: [PATCH 28/55] findbugs correction --- .../owasp/dependencycheck/maven/slf4j/MavenLoggerAdapter.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/slf4j/MavenLoggerAdapter.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/slf4j/MavenLoggerAdapter.java index c568f5e72..f1ab7b953 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/slf4j/MavenLoggerAdapter.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/slf4j/MavenLoggerAdapter.java @@ -27,10 +27,6 @@ import org.slf4j.helpers.MessageFormatter; * @author colezlaw */ public class MavenLoggerAdapter extends MarkerIgnoringBase { - /** - * The serial version UID for serialization. - */ - private static final long serialVersionUID = 1L; /** * A reference to the Maven log. From f7b534f1eefffac62cd2dfe771d3886b8f3c185f Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 4 Jun 2016 07:44:08 -0400 Subject: [PATCH 29/55] checkstyle correction --- .../java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java index 42ee00277..d6f4731bc 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java @@ -644,7 +644,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { * @return whether evidence was identified parsing the manifest * @throws IOException if there is an issue reading the JAR file */ - protected boolean parseManifest(Dependency dependency, List classInformation) + protected boolean parseManifest(Dependency dependency, + List classInformation) throws IOException { boolean foundSomething = false; JarFile jar = null; From 7f609a35beefe6e841ce210cad1864ab805bbb50 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 4 Jun 2016 07:44:42 -0400 Subject: [PATCH 30/55] added javadoc per checkstyle --- .../analyzer/OpenSSLAnalyzer.java | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java index 56e894841..bcc7728d7 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java @@ -39,6 +39,9 @@ import java.util.regex.Pattern; */ public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { + /** + * Hexadecimal. + */ private static final int HEXADECIMAL = 16; /** * Filename to analyze. All other .h files get removed from consideration. @@ -49,17 +52,47 @@ public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { * Filter that detects files named "__init__.py". */ private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build(); + /** + * Open SSL Version number pattern. + */ private static final Pattern VERSION_PATTERN = Pattern.compile( "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); + /** + * The offset of the major version number. + */ private static final int MAJOR_OFFSET = 28; + /** + * The mask for the minor version number. + */ private static final long MINOR_MASK = 0x0ff00000L; + /** + * The offset of the minor version number. + */ private static final int MINOR_OFFSET = 20; + /** + * The max for the fix version. + */ private static final long FIX_MASK = 0x000ff000L; + /** + * The offset for the fix version. + */ private static final int FIX_OFFSET = 12; + /** + * The mask for the patch version. + */ private static final long PATCH_MASK = 0x00000ff0L; + /** + * The offset for the patch version. + */ private static final int PATCH_OFFSET = 4; + /** + * Number of letters. + */ private static final int NUM_LETTERS = 26; + /** + * The status mask. + */ private static final int STATUS_MASK = 0x0000000f; /** @@ -124,7 +157,8 @@ public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { * * @param dependency the dependency being analyzed * @param engine the engine being used to perform the scan - * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency + * @throws AnalysisException thrown if there is an unrecoverable error + * analyzing the dependency */ @Override protected void analyzeFileType(Dependency dependency, Engine engine) @@ -167,6 +201,11 @@ public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { } } + /** + * Returns the setting for the analyzer enabled setting key. + * + * @return the setting for the analyzer enabled setting key + */ @Override protected String getAnalyzerEnabledSettingKey() { return Settings.KEYS.ANALYZER_OPENSSL_ENABLED; From 95939ed66cc69a079fd9e056a08519d867b088b0 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 4 Jun 2016 07:45:07 -0400 Subject: [PATCH 31/55] added javadoc per checkstyle --- .../analyzer/RubyBundleAuditAnalyzer.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java index e361d9815..2782c9968 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java @@ -206,6 +206,13 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { */ private boolean needToDisableGemspecAnalyzer = true; + /** + * Determines if the analyzer can analyze the given file type. + * + * @param dependency the dependency to determine if it can analyze + * @param engine the dependency-check engine + * @throws AnalysisException thrown if there is an analysis exception. + */ @Override protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { @@ -265,6 +272,14 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } + /** + * Processes the bundler audit output. + * + * @param original the dependency + * @param engine the dependency-check engine + * @param rdr the reader of the report + * @throws IOException thrown if the report cannot be read. + */ private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException { final String parentName = original.getActualFile().getParentFile().getName(); final String fileName = original.getFileName(); @@ -309,6 +324,14 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } } + /** + * Sets the vulnerability name. + * + * @param parentName the parent name + * @param dependency the dependency + * @param vulnerability the vulnerability + * @param nextLine the line to parse + */ private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) { final String advisory = nextLine.substring((ADVISORY.length())); if (null != vulnerability) { @@ -320,6 +343,13 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); } + /** + * Adds a reference to the vulnerability. + * + * @param parentName the parent name + * @param vulnerability the vulnerability + * @param nextLine the line to parse + */ private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { final String url = nextLine.substring(("URL: ").length()); if (null != vulnerability) { @@ -332,6 +362,13 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); } + /** + * Adds the criticality to the vulnerability + * + * @param parentName the parent name + * @param vulnerability the vulnerability + * @param nextLine the line to parse + */ private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { if (null != vulnerability) { final String criticality = nextLine.substring(CRITICALITY.length()).trim(); @@ -356,6 +393,15 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); } + /** + * Creates a vulnerability. + * + * @param parentName the parent name + * @param dependency the dependency + * @param gem the gem name + * @param nextLine the line to parse + * @return the vulnerability + */ private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) { Vulnerability vulnerability = null; if (null != dependency) { @@ -380,6 +426,17 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { return vulnerability; } + /** + * Creates the dependency based off of the gem. + * + * @param engine the engine used for scanning + * @param parentName the gem parent + * @param fileName the file name + * @param filePath the file path + * @param gem the gem name + * @return the dependency to add + * @throws IOException thrown if a temporary gem file could not be written + */ private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String filePath, String gem) throws IOException { final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock"); gemFile.createNewFile(); From 60ce02ba2867b131ca5b029ffa80dbb7fa956b65 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 4 Jun 2016 07:46:42 -0400 Subject: [PATCH 32/55] improved logging to assist in resoloving issue #503 --- .../dependencycheck/data/nvdcve/CveDB.java | 73 +++++++++++++------ 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java index 037da7564..30ab437d1 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java @@ -69,10 +69,11 @@ public class CveDB { private ResourceBundle statementBundle = null; /** - * Creates a new CveDB object and opens the database connection. Note, the connection must be closed by the caller by calling - * the close method. + * Creates a new CveDB object and opens the database connection. Note, the + * connection must be closed by the caller by calling the close method. * - * @throws DatabaseException thrown if there is an exception opening the database. + * @throws DatabaseException thrown if there is an exception opening the + * database. */ public CveDB() throws DatabaseException { super(); @@ -103,9 +104,11 @@ public class CveDB { } /** - * Opens the database connection. If the database does not exist, it will create a new one. + * Opens the database connection. If the database does not exist, it will + * create a new one. * - * @throws DatabaseException thrown if there is an error opening the database connection + * @throws DatabaseException thrown if there is an error opening the + * database connection */ public final void open() throws DatabaseException { if (!isOpen()) { @@ -114,7 +117,8 @@ public class CveDB { } /** - * Closes the DB4O database. Close should be called on this object when it is done being used. + * Closes the DB4O database. Close should be called on this object when it + * is done being used. */ public void close() { if (conn != null) { @@ -165,7 +169,8 @@ public class CveDB { super.finalize(); } /** - * Database properties object containing the 'properties' from the database table. + * Database properties object containing the 'properties' from the database + * table. */ private DatabaseProperties databaseProperties; @@ -179,11 +184,13 @@ public class CveDB { } /** - * Searches the CPE entries in the database and retrieves all entries for a given vendor and product combination. The returned - * list will include all versions of the product that are registered in the NVD CVE data. + * Searches the CPE entries in the database and retrieves all entries for a + * given vendor and product combination. The returned list will include all + * versions of the product that are registered in the NVD CVE data. * * @param vendor the identified vendor name of the dependency being analyzed - * @param product the identified name of the product of the dependency being analyzed + * @param product the identified name of the product of the dependency being + * analyzed * @return a set of vulnerable software */ public Set getCPEs(String vendor, String product) { @@ -215,7 +222,8 @@ public class CveDB { * Returns the entire list of vendor/product combinations. * * @return the entire list of vendor/product combinations - * @throws DatabaseException thrown when there is an error retrieving the data from the DB + * @throws DatabaseException thrown when there is an error retrieving the + * data from the DB */ public Set> getVendorProductList() throws DatabaseException { final Set> data = new HashSet>(); @@ -438,7 +446,8 @@ public class CveDB { } /** - * Updates the vulnerability within the database. If the vulnerability does not exist it will be added. + * Updates the vulnerability within the database. If the vulnerability does + * not exist it will be added. * * @param vuln the vulnerability to add to the database * @throws DatabaseException is thrown if the database @@ -565,12 +574,20 @@ public class CveDB { } else { insertSoftware.setString(3, s.getPreviousVersion()); } - insertSoftware.execute(); + try { + insertSoftware.execute(); + } catch (SQLException ex) { + if (ex.getMessage().contains("Duplicate entry")) { + final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName()); + LOGGER.debug(msg, ex); + } else { + throw ex; + } + } } - } catch (SQLException ex) { final String msg = String.format("Error updating '%s'", vuln.getName()); - LOGGER.debug("", ex); + LOGGER.debug(msg, ex); throw new DatabaseException(msg, ex); } finally { DBUtils.closeStatement(selectVulnerabilityId); @@ -623,8 +640,9 @@ public class CveDB { } /** - * It is possible that orphaned rows may be generated during database updates. This should be called after all updates have - * been completed to ensure orphan entries are removed. + * It is possible that orphaned rows may be generated during database + * updates. This should be called after all updates have been completed to + * ensure orphan entries are removed. */ public void cleanupDatabase() { PreparedStatement ps = null; @@ -642,13 +660,17 @@ public class CveDB { } /** - * Determines if the given identifiedVersion is affected by the given cpeId and previous version flag. A non-null, non-empty - * string passed to the previous version argument indicates that all previous versions are affected. + * Determines if the given identifiedVersion is affected by the given cpeId + * and previous version flag. A non-null, non-empty string passed to the + * previous version argument indicates that all previous versions are + * affected. * * @param vendor the vendor of the dependency being analyzed * @param product the product name of the dependency being analyzed - * @param vulnerableSoftware a map of the vulnerable software with a boolean indicating if all previous versions are affected - * @param identifiedVersion the identified version of the dependency being analyzed + * @param vulnerableSoftware a map of the vulnerable software with a boolean + * indicating if all previous versions are affected + * @param identifiedVersion the identified version of the dependency being + * analyzed * @return true if the identified version is affected, otherwise false */ Entry getMatchingSoftware(Map vulnerableSoftware, String vendor, String product, @@ -715,7 +737,8 @@ public class CveDB { } /** - * Parses the version (including revision) from a CPE identifier. If no version is identified then a '-' is returned. + * Parses the version (including revision) from a CPE identifier. If no + * version is identified then a '-' is returned. * * @param cpeStr a cpe identifier * @return a dependency version @@ -732,7 +755,8 @@ public class CveDB { } /** - * Takes a CPE and parses out the version number. If no version is identified then a '-' is returned. + * Takes a CPE and parses out the version number. If no version is + * identified then a '-' is returned. * * @param cpe a cpe object * @return a dependency version @@ -771,7 +795,8 @@ public class CveDB { } /** - * This method is only referenced in unused code and will likely break on MySQL if ever used due to the MERGE statement. + * This method is only referenced in unused code and will likely break on + * MySQL if ever used due to the MERGE statement. * * Merges CPE entries into the database. * From 8a6c940aaf7d9d1fa5fe297aac3d7757c77caaea Mon Sep 17 00:00:00 2001 From: "Alexander v. Buchholtz" Date: Sat, 4 Jun 2016 23:36:43 +0200 Subject: [PATCH 33/55] Optimized CLEANUP_ORPHANS query for H2 1.4.x Original query from dbStatements.properties writes millions of records from subselect to file system due to MAX_MEMORY_ROWS Setting http://www.h2database.com/html/grammar.html?highlight=max_memory_rows&search=MAX_MEM#set_max_memory_rows Database maintenance task therefore takes forever. The new query (copied from postgresql) works way faster. --- .../src/main/resources/data/dbStatements_h2.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/dependency-check-core/src/main/resources/data/dbStatements_h2.properties b/dependency-check-core/src/main/resources/data/dbStatements_h2.properties index aea9f986a..59b4204c5 100644 --- a/dependency-check-core/src/main/resources/data/dbStatements_h2.properties +++ b/dependency-check-core/src/main/resources/data/dbStatements_h2.properties @@ -13,3 +13,4 @@ # limitations under the License. MERGE_PROPERTY=MERGE INTO properties (id, value) KEY(id) VALUES(?, ?) +CLEANUP_ORPHANS=DELETE FROM cpeEntry WHERE id IN (SELECT id FROM cpeEntry LEFT JOIN software ON cpeEntry.id = software.CPEEntryId WHERE software.CPEEntryId IS NULL) From c4b423cb0f889d2e244d23f295a8fbff2d238eee Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 06:32:11 -0400 Subject: [PATCH 34/55] additional tests resources to fix issue #503 --- .../src/test/resources/cve-1.2-2008_4411.xml | 57 +++++++++ .../src/test/resources/cve-2.0-2008_4411.xml | 115 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 dependency-check-core/src/test/resources/cve-1.2-2008_4411.xml create mode 100644 dependency-check-core/src/test/resources/cve-2.0-2008_4411.xml diff --git a/dependency-check-core/src/test/resources/cve-1.2-2008_4411.xml b/dependency-check-core/src/test/resources/cve-1.2-2008_4411.xml new file mode 100644 index 000000000..0fad0302c --- /dev/null +++ b/dependency-check-core/src/test/resources/cve-1.2-2008_4411.xml @@ -0,0 +1,57 @@ + + + + + Cross-site scripting (XSS) vulnerability in HP System Management Homepage (SMH) before 2.1.15.210 on Linux and Windows allows remote attackers to inject arbitrary web script or HTML via unspecified vectors, a different vulnerability than CVE-2008-1663. + + + + + + + + + 31663 + smh-unspecified-xss(45754) + ADV-2008-2778 + 1021015 + 4398 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dependency-check-core/src/test/resources/cve-2.0-2008_4411.xml b/dependency-check-core/src/test/resources/cve-2.0-2008_4411.xml new file mode 100644 index 000000000..0413733de --- /dev/null +++ b/dependency-check-core/src/test/resources/cve-2.0-2008_4411.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29 + cpe:/a:hp:system_management_homepage:2.1.0-118 + cpe:/a:hp:system_management_homepage:2.1.3.132 + cpe:/a:hp:system_management_homepage:2.1.12-200 + cpe:/a:hp:system_management_homepage:2.1.2-127 + cpe:/a:hp:system_management_homepage:2.1.9 + cpe:/a:hp:system_management_homepage:2.1.10 + cpe:/a:hp:system_management_homepage:2.1.11 + cpe:/a:hp:system_management_homepage:2.1.12-118 + cpe:/a:hp:system_management_homepage:2.1.4-143 + cpe:/a:hp:system_management_homepage:2.1.0-109 + cpe:/a:hp:system_management_homepage:2.1.6-156 + cpe:/a:hp:system_management_homepage:2.1.4 + cpe:/a:hp:system_management_homepage:2.1.3 + cpe:/a:hp:system_management_homepage:2.1 + cpe:/a:hp:system_management_homepage:2.1.10-186 + cpe:/a:hp:system_management_homepage:2.1.6 + cpe:/a:hp:system_management_homepage:2.1.5 + cpe:/a:hp:system_management_homepage:2.1.5-146 + cpe:/a:hp:system_management_homepage:2.1.8 + cpe:/a:hp:system_management_homepage:2.1.7 + cpe:/a:hp:system_management_homepage:2.1.2 + cpe:/a:hp:system_management_homepage:2.0.2 + cpe:/a:hp:system_management_homepage:2.1.1 + cpe:/a:hp:system_management_homepage:2.1.8-177 + cpe:/a:hp:system_management_homepage:2.0.1 + cpe:/a:hp:system_management_homepage:2.0.0 + cpe:/a:hp:system_management_homepage:2.1.7-168 + cpe:/a:hp:system_management_homepage:2.1.0-103 + cpe:/a:hp:system_management_homepage:2.1.11-197 + cpe:/a:hp:system_management_homepage:2.1.9-178 + + CVE-2008-4411 + 2008-10-13T16:00:02.277-04:00 + 2011-03-07T22:12:25.097-05:00 + + + 4.3 + NETWORK + MEDIUM + NONE + NONE + PARTIAL + NONE + http://nvd.nist.gov + 2008-10-14T10:57:00.000-04:00 + + + + + BID + 31663 + + + XF + smh-unspecified-xss(45754) + + + VUPEN + ADV-2008-2778 + + + SECTRACK + 1021015 + + + SREASON + 4398 + + Cross-site scripting (XSS) vulnerability in HP System Management Homepage (SMH) before 2.1.15.210 on Linux and Windows allows remote attackers to inject arbitrary web script or HTML via unspecified vectors, a different vulnerability than CVE-2008-1663. + + + \ No newline at end of file From 310ca967a19e8e0b5a970fb398af6a7e1e3bfa76 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 06:32:49 -0400 Subject: [PATCH 35/55] fixed compareTo in order to resolve issue #503 --- .../data/update/nvd/NvdCve20Handler.java | 9 +- .../dependency/VulnerableSoftware.java | 13 +- .../update/nvd/NvdCve_2_0_HandlerTest.java | 33 +++ .../dependency/VulnerabilityTest.java | 195 ++++++++++-------- .../dependency/VulnerableSoftwareTest.java | 59 ++++-- 5 files changed, 191 insertions(+), 118 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.java index e2b60db7a..25fc95f9b 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.java @@ -254,17 +254,16 @@ public class NvdCve20Handler extends DefaultHandler { * @throws IOException thrown if there is an IOException with the CPE Index */ private void saveEntry(Vulnerability vuln) throws DatabaseException, CorruptIndexException, IOException { - if (cveDB == null) { - return; - } final String cveName = vuln.getName(); - if (prevVersionVulnMap.containsKey(cveName)) { + if (prevVersionVulnMap != null && prevVersionVulnMap.containsKey(cveName)) { final List vulnSoftware = prevVersionVulnMap.get(cveName); for (VulnerableSoftware vs : vulnSoftware) { vuln.updateVulnerableSoftware(vs); } } - cveDB.updateVulnerability(vuln); + if (cveDB != null) { + cveDB.updateVulnerability(vuln); + } } // diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java index 3e46581e6..05dde8126 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/VulnerableSoftware.java @@ -180,23 +180,14 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp final int max = (left.length <= right.length) ? left.length : right.length; if (max > 0) { for (int i = 0; result == 0 && i < max; i++) { - final String[] subLeft = left[i].split("\\."); - final String[] subRight = right[i].split("\\."); + final String[] subLeft = left[i].split("(\\.|-)"); + final String[] subRight = right[i].split("(\\.|-)"); final int subMax = (subLeft.length <= subRight.length) ? subLeft.length : subRight.length; if (subMax > 0) { for (int x = 0; result == 0 && x < subMax; x++) { if (isPositiveInteger(subLeft[x]) && isPositiveInteger(subRight[x])) { try { result = Long.valueOf(subLeft[x]).compareTo(Long.valueOf(subRight[x])); -// final long iLeft = Long.parseLong(subLeft[x]); -// final long iRight = Long.parseLong(subRight[x]); -// if (iLeft != iRight) { -// if (iLeft > iRight) { -// result = 2; -// } else { -// result = -2; -// } -// } } catch (NumberFormatException ex) { //ignore the exception - they obviously aren't numbers if (!subLeft[x].equalsIgnoreCase(subRight[x])) { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.java index 70257e6ed..975750d5d 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.java @@ -19,6 +19,8 @@ package org.owasp.dependencycheck.data.update.nvd; import org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler; import java.io.File; +import java.util.List; +import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.junit.After; @@ -28,6 +30,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.owasp.dependencycheck.BaseTest; +import org.owasp.dependencycheck.dependency.VulnerableSoftware; /** * @@ -49,12 +52,42 @@ public class NvdCve_2_0_HandlerTest extends BaseTest { saxParser.parse(file, instance); } catch (Throwable ex) { + ex.printStackTrace(); results = ex; } assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); if (results != null) { System.err.println(results); } + } + @Test + public void testParserWithPreviousVersion() { + Throwable results = null; + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + SAXParser saxParser = factory.newSAXParser(); + + File file12 = BaseTest.getResourceAsFile(this, "cve-1.2-2008_4411.xml"); + + final NvdCve12Handler cve12Handler = new NvdCve12Handler(); + saxParser.parse(file12, cve12Handler); + final Map> prevVersionVulnMap = cve12Handler.getVulnerabilities(); + + //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); + File file20 = BaseTest.getResourceAsFile(this, "cve-2.0-2008_4411.xml"); + + NvdCve20Handler instance = new NvdCve20Handler(); + instance.setPrevVersionVulnMap(prevVersionVulnMap); + saxParser.parse(file20, instance); + + assertTrue(instance.getTotalNumberOfEntries()==1); + } catch (Throwable ex) { + results = ex; + } + assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); + if (results != null) { + System.err.println(results); + } } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerabilityTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerabilityTest.java index 550540b67..e4849f1bb 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerabilityTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerabilityTest.java @@ -17,6 +17,7 @@ */ package org.owasp.dependencycheck.dependency; +import java.util.Set; import org.junit.After; import org.junit.AfterClass; import static org.junit.Assert.assertEquals; @@ -31,7 +32,7 @@ import org.owasp.dependencycheck.BaseTest; * * @author Jens Hausherr */ -public class VulnerabilityTest extends BaseTest { +public class VulnerabilityTest extends BaseTest { /** * Test of equals method, of class VulnerableSoftware. @@ -49,90 +50,112 @@ public class VulnerabilityTest extends BaseTest { @Test public void testDpulicateVersionsWithPreviousVersion() { - Vulnerability obj = new Vulnerability(); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.0",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.1",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.2",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.10",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.11",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.12",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.13",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.14",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.15",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.16",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.17",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.18",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.19",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.20",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.21",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.22",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:4.1.23",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.0",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.0:alpha",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.1",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.10",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.10a",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.11",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.12",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.13",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.15",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.19",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.1a",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.2",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.3",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.4",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.5.0.21",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.6",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.9",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.21",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.22",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.23",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.24",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.24a",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.25",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.30",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.32",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.33",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.36",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.37",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.38",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.3a",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.41",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.42",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.44",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.45",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.4a",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.50",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.51",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.52",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.54",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.0.56",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.23a","1"); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.3",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.4",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.5",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.5a",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.6",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.7",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.9",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.11",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.12",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.14",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.15",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.16",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.17",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.18",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.19",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.20",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.21",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.22",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.23",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:5.1.23a",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:6.0.0",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:6.0.1",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:6.0.2",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:6.0.3",null); - obj.addVulnerableSoftware("cpe:/a:mysql:mysql:6.0.4",null); - assertEquals(82, obj.getVulnerableSoftware().size()); + Vulnerability obj = new Vulnerability(); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", "1"); + assertEquals(31, obj.getVulnerableSoftware().size()); } + + @Test + public void testSoftwareSorting() { + Vulnerability obj = new Vulnerability(); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null); + obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null); + + Set software = obj.getVulnerableSoftware(); + VulnerableSoftware vs[] = software.toArray(new VulnerableSoftware[software.size()]); + + assertTrue("cpe:/a:hp:system_management_homepage:2.0.0".equals(vs[0].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.0.1".equals(vs[1].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.0.2".equals(vs[2].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1".equals(vs[3].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103".equals(vs[4].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29".equals(vs[5].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-109".equals(vs[6].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-118".equals(vs[7].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.1".equals(vs[8].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.2".equals(vs[9].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.2-127".equals(vs[10].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.3".equals(vs[11].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.3.132".equals(vs[12].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.4".equals(vs[13].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.4-143".equals(vs[14].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.5".equals(vs[15].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.5-146".equals(vs[16].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.6".equals(vs[17].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.6-156".equals(vs[18].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.7".equals(vs[19].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.7-168".equals(vs[20].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.8".equals(vs[21].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.8-177".equals(vs[22].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.9".equals(vs[23].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.9-178".equals(vs[24].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.10".equals(vs[25].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.10-186".equals(vs[26].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.11".equals(vs[27].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.11-197".equals(vs[28].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-118".equals(vs[29].getName())); + assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-200".equals(vs[30].getName())); + + } + } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java index 8789d25d1..91ed83373 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java @@ -31,7 +31,7 @@ import org.owasp.dependencycheck.BaseTest; * * @author Jeremy Long */ -public class VulnerableSoftwareTest extends BaseTest { +public class VulnerableSoftwareTest extends BaseTest { /** * Test of equals method, of class VulnerableSoftware. @@ -93,25 +93,52 @@ public class VulnerableSoftwareTest extends BaseTest { } @Test - public void testCompareToNonNumerical(){ - VulnerableSoftware vs = new VulnerableSoftware(); - vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); - VulnerableSoftware vs1 = new VulnerableSoftware(); - vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); - vs1.setPreviousVersion("1"); - assertEquals(0, vs.compareTo(vs1)); - assertEquals(0, vs1.compareTo(vs)); + public void testCompareToNonNumerical() { + VulnerableSoftware vs = new VulnerableSoftware(); + vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); + VulnerableSoftware vs1 = new VulnerableSoftware(); + vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); + vs1.setPreviousVersion("1"); + assertEquals(0, vs.compareTo(vs1)); + assertEquals(0, vs1.compareTo(vs)); + } + + @Test + public void testCompareToComplex() { + VulnerableSoftware vs = new VulnerableSoftware(); + VulnerableSoftware vs1 = new VulnerableSoftware(); + + vs.setCpe("2.1"); + vs1.setCpe("2.1.10"); + assertTrue(vs.compareTo(vs1) < 0); + + vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.1"); + vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); + assertTrue(vs.compareTo(vs1) < 0); + + vs.setCpe("10"); + vs1.setCpe("10-186"); + assertTrue(vs.compareTo(vs1) < 0); + + vs.setCpe("2.1.10"); + vs1.setCpe("2.1.10-186"); + assertTrue(vs.compareTo(vs1) < 0); + + vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); + vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10-186"); + assertTrue(vs.compareTo(vs1) < 0); + //assertTrue(vs1.compareTo(vs)>0); } @Test public void testEqualsPreviousVersion() { - VulnerableSoftware vs = new VulnerableSoftware(); - vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); - VulnerableSoftware vs1 = new VulnerableSoftware(); - vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); - vs1.setPreviousVersion("1"); - assertEquals(vs,vs1); - assertEquals(vs1,vs); + VulnerableSoftware vs = new VulnerableSoftware(); + vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); + VulnerableSoftware vs1 = new VulnerableSoftware(); + vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); + vs1.setPreviousVersion("1"); + assertEquals(vs, vs1); + assertEquals(vs1, vs); } From a2187205e08d22e0c18fcb2363b99a9390c3a545 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 06:45:13 -0400 Subject: [PATCH 36/55] only update last checked after updates were performed without errors --- .../owasp/dependencycheck/data/update/NvdCveUpdater.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java index 0a3bd196f..94d814e15 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java @@ -79,6 +79,7 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { if (updateable.isUpdateNeeded()) { performUpdate(updateable); } + getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); } } catch (MalformedURLException ex) { LOGGER.warn( @@ -115,9 +116,7 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0")); final long now = System.currentTimeMillis(); proceed = (now - lastChecked) > msValid; - if (proceed) { - getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(now)); - } else { + if (!proceed) { LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours); LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.", lastChecked, now, msValid); @@ -339,5 +338,4 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { } return updates; } - } From 06b59cf79b1f23d6c852789ef4a34db7cfa9d5f7 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 07:49:59 -0400 Subject: [PATCH 37/55] initial --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..230cb83e0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,2 @@ +language: java +jdk: oraclejdk7 From f43589589d55fb4cefe6cf72ad94ba6bec46b7a9 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 08:04:45 -0400 Subject: [PATCH 38/55] fixed setup to call super --- .../dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java index 756486450..5676fa2d6 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java @@ -65,7 +65,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { */ @Before public void setUp() throws Exception { - Settings.initialize(); + super.setUp(); analyzer = new RubyBundleAuditAnalyzer(); analyzer.setFilesMatched(true); } @@ -77,7 +77,6 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { */ @After public void tearDown() throws Exception { - Settings.cleanup(); analyzer.close(); analyzer = null; } From f6b80630dd5cab7ec79712cc7a7e836245b56eb6 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 08:30:22 -0400 Subject: [PATCH 39/55] temporary travis debugging code --- .../analyzer/RubyBundleAuditAnalyzerTest.java | 68 ++++++++++--------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java index 5676fa2d6..4d7b962cd 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java @@ -113,7 +113,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { int size = engine.getDependencies().size(); assertTrue(size >= 1); - + Dependency dependency = engine.getDependencies().get(0); assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); @@ -175,45 +175,51 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { */ @Test public void testDependenciesPath() throws AnalysisException, DatabaseException { - + final Engine engine = new Engine(); engine.scan(BaseTest.getResourceAsFile(this, "ruby/vulnerable/gems/rails-4.1.15/")); - engine.analyzeDependencies(); + + try { + engine.analyzeDependencies(); + } catch (NullPointerException ex) { + LOGGER.error("NPE", ex); + throw ex; + } List dependencies = engine.getDependencies(); LOGGER.info(dependencies.size() + " dependencies found."); Iterator dIterator = dependencies.iterator(); - while(dIterator.hasNext()) { - Dependency dept = dIterator.next(); - LOGGER.info("dept path: " + dept.getActualFilePath()); + while (dIterator.hasNext()) { + Dependency dept = dIterator.next(); + LOGGER.info("dept path: " + dept.getActualFilePath()); - Set identifiers = dept.getIdentifiers(); - Iterator idIterator = identifiers.iterator(); - while(idIterator.hasNext()) { - Identifier id = idIterator.next(); - LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf="+ id.getConfidence()); - } - - Set prodEv = dept.getProductEvidence().getEvidence(); - Iterator it = prodEv.iterator(); - while(it.hasNext()) { - Evidence e = it.next(); - LOGGER.info(" prod: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); - } - Set versionEv = dept.getVersionEvidence().getEvidence(); - Iterator vIt = versionEv.iterator(); - while(vIt.hasNext()) { - Evidence e = vIt.next(); - LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); - } + Set identifiers = dept.getIdentifiers(); + Iterator idIterator = identifiers.iterator(); + while (idIterator.hasNext()) { + Identifier id = idIterator.next(); + LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence()); + } - Set vendorEv = dept.getVendorEvidence().getEvidence(); - Iterator vendorIt = vendorEv.iterator(); - while(vendorIt.hasNext()) { - Evidence e = vendorIt.next(); - LOGGER.info(" vendor: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); - } + Set prodEv = dept.getProductEvidence().getEvidence(); + Iterator it = prodEv.iterator(); + while (it.hasNext()) { + Evidence e = it.next(); + LOGGER.info(" prod: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); + } + Set versionEv = dept.getVersionEvidence().getEvidence(); + Iterator vIt = versionEv.iterator(); + while (vIt.hasNext()) { + Evidence e = vIt.next(); + LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); + } + + Set vendorEv = dept.getVendorEvidence().getEvidence(); + Iterator vendorIt = vendorEv.iterator(); + while (vendorIt.hasNext()) { + Evidence e = vendorIt.next(); + LOGGER.info(" vendor: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); + } } } } From ef4a260615de861545ed105d1abd168a06cceb13 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 17:16:05 -0400 Subject: [PATCH 40/55] fixed build issue with CveDB being closed before saving the property --- .../org/owasp/dependencycheck/data/update/NvdCveUpdater.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java index 94d814e15..763f35b70 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java @@ -76,10 +76,10 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { } if (autoUpdate && checkUpdate()) { final UpdateableNvdCve updateable = getUpdatesNeeded(); + getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); if (updateable.isUpdateNeeded()) { performUpdate(updateable); - } - getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); + } } } catch (MalformedURLException ex) { LOGGER.warn( From b01ae2c6d3a7d04b1d5692582acbfc5a45986ede Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 17:16:43 -0400 Subject: [PATCH 41/55] updated to speed-up the unit test --- .../analyzer/RubyBundleAuditAnalyzerTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java index 4d7b962cd..f8d2fe8d2 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java @@ -66,6 +66,9 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { @Before public void setUp() throws Exception { super.setUp(); + Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); + Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); + Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); analyzer = new RubyBundleAuditAnalyzer(); analyzer.setFilesMatched(true); } @@ -175,12 +178,9 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { */ @Test public void testDependenciesPath() throws AnalysisException, DatabaseException { - final Engine engine = new Engine(); engine.scan(BaseTest.getResourceAsFile(this, "ruby/vulnerable/gems/rails-4.1.15/")); - - try { engine.analyzeDependencies(); } catch (NullPointerException ex) { From ec6471e8c7526acf9c00afa7a6a9c2d011611669 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 17:17:38 -0400 Subject: [PATCH 42/55] added notes for future enhancment --- .../org/owasp/dependencycheck/analyzer/CPEAnalyzer.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java index dc53ee3cd..6b4caef8e 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java @@ -512,10 +512,11 @@ public class CPEAnalyzer implements Analyzer { Confidence bestGuessConf = null; boolean hasBroadMatch = false; final List collected = new ArrayList(); + + //TODO the following algorithm incorrectly identifies things as a lower version + // if there lower confidence evidence when the current (highest) version number + // is newer then anything in the NVD. for (Confidence conf : Confidence.values()) { -// if (conf.compareTo(currentConfidence) > 0) { -// break; -// } for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) { final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue()); if (evVer == null) { From 78becffb2ee2e310c0bdb3d2de3d6a68384f2d57 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 17:29:29 -0400 Subject: [PATCH 43/55] updated CI build status url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d2f2eb4be..45e549db7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://dependency-check.ci.cloudbees.com/buildStatus/icon?job=dependency-check)](https://dependency-check.ci.cloudbees.com/job/dependency-check/) +[![Build Status](https://travis-ci.org/jeremylong/DependencyCheck.svg?branch=master)](https://travis-ci.org/jeremylong/DependencyCheck) Dependency-Check ================ From 1ba368145746685d7086170429d78d40e4df9cf1 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 17:32:57 -0400 Subject: [PATCH 44/55] updated the ci --- pom.xml | 4 ++-- src/site/site.xml | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 7c9a74b7e..496ab2fdd 100644 --- a/pom.xml +++ b/pom.xml @@ -100,8 +100,8 @@ Copyright (c) 2012 - Jeremy Long https://github.com/jeremylong/DependencyCheck/issues - Cloudbees - https://dependency-check.ci.cloudbees.com/ + travis-ci + https://travis-ci.org/jeremylong/DependencyCheck diff --git a/src/site/site.xml b/src/site/site.xml index b896867c3..41ccc5d47 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -57,10 +57,6 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. title="developed using" width="170px" alt="developed using" img="http://jeremylong.github.io/DependencyCheck/images/logos/logo_intellij_idea.png"/> - From 59a4825c70ac6716d67691dc2b839cf58edb5a42 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 5 Jun 2016 17:40:42 -0400 Subject: [PATCH 45/55] added license --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 45e549db7..33d31804b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/jeremylong/DependencyCheck.svg?branch=master)](https://travis-ci.org/jeremylong/DependencyCheck) +[![Build Status](https://travis-ci.org/jeremylong/DependencyCheck.svg?branch=master)](https://travis-ci.org/jeremylong/DependencyCheck) [![Apache 2.0 License](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0.txt) Dependency-Check ================ From 6fd831e688f5225730321008d4511e5612789d12 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 6 Jun 2016 06:44:42 -0400 Subject: [PATCH 46/55] corrected JavaDoc links --- .../owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java index c8c4de17c..32e39b6b9 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java @@ -27,7 +27,7 @@ import org.owasp.dependencycheck.dependency.Dependency; /** * This analyzer accepts the fully resolved .gemspec created by the Ruby bundler * (http://bundler.io) for better evidence results. It also tries to resolve the - * dependency packagePath to where the gem is actually installed. Then during {@link AnalysisPhase.PRE_FINDING_ANALYSIS} + * dependency packagePath to where the gem is actually installed. Then during {@link org.owasp.dependencycheck.analyzer.AnalysisPhase#PRE_FINDING_ANALYSIS} * {@link DependencyBundlingAnalyzer} will merge two .gemspec dependencies * together if Dependency.getPackagePath() are the same. * @@ -39,7 +39,7 @@ import org.owasp.dependencycheck.dependency.Dependency; * can't be used for evidences. * * Note this analyzer share the same - * {@link Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED} as + * {@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_RUBY_GEMSPEC_ENABLED} as * {@link RubyGemspecAnalyzer}, so it will enabled/disabled with * {@link RubyGemspecAnalyzer}. * From 7909bbbbe9231567002149816aa9577883b209a0 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 6 Jun 2016 06:45:33 -0400 Subject: [PATCH 47/55] corrected remaining merge conflicts that were missed earlier as they were in comments --- .../java/org/owasp/dependencycheck/data/nvdcve/CveDB.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java index f00f4b8cd..82e738b0c 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java @@ -69,7 +69,7 @@ public class CveDB { private ResourceBundle statementBundle = null; /** - * <<<<<<< HEAD Creates a new CveDB object and opens the database + * Creates a new CveDB object and opens the database * connection. Note, the connection must be closed by the caller by calling * the close method. ======= Does the underlying connection support batch * operations? @@ -79,8 +79,7 @@ public class CveDB { /** * Creates a new CveDB object and opens the database connection. Note, the * connection must be closed by the caller by calling the close method. - * >>>>>>> e79da72711dc0f326fcdce52deab89e37c0d8230 - * + * * @throws DatabaseException thrown if there is an exception opening the * database. */ From 4e4417c7af720c0673d7f0893c4145f206a4e928 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 6 Jun 2016 18:45:39 -0400 Subject: [PATCH 48/55] checkstyle corrections --- .../dependencycheck/analyzer/CPEAnalyzer.java | 139 +++++++++++------- .../dependencycheck/analyzer/JarAnalyzer.java | 2 +- .../analyzer/RubyBundleAuditAnalyzer.java | 19 ++- .../data/update/NvdCveUpdater.java | 51 ++++--- .../dependencycheck/dependency/Reference.java | 5 +- .../dependency/Vulnerability.java | 2 +- 6 files changed, 140 insertions(+), 78 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java index 6b4caef8e..43528d863 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java @@ -51,8 +51,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * CPEAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated CPE. It uses - * the evidence contained within the dependency to search the Lucene index. + * CPEAnalyzer is a utility class that takes a project dependency and attempts + * to discern if there is an associated CPE. It uses the evidence contained + * within the dependency to search the Lucene index. * * @author Jeremy Long */ @@ -71,15 +72,18 @@ public class CPEAnalyzer implements Analyzer { */ static final String WEIGHTING_BOOST = "^5"; /** - * A string representation of a regular expression defining characters utilized within the CPE Names. + * A string representation of a regular expression defining characters + * utilized within the CPE Names. */ static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]"; /** - * A string representation of a regular expression used to remove all but alpha characters. + * A string representation of a regular expression used to remove all but + * alpha characters. */ static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*"; /** - * The additional size to add to a new StringBuilder to account for extra data that will be written into the string. + * The additional size to add to a new StringBuilder to account for extra + * data that will be written into the string. */ static final int STRING_BUILDER_BUFFER = 20; /** @@ -129,9 +133,10 @@ public class CPEAnalyzer implements Analyzer { /** * Opens the data source. * - * @throws IOException when the Lucene directory to be queried does not exist or is corrupt. - * @throws DatabaseException when the database throws an exception. This usually occurs when the database is in use by another - * process. + * @throws IOException when the Lucene directory to be queried does not + * exist or is corrupt. + * @throws DatabaseException when the database throws an exception. This + * usually occurs when the database is in use by another process. */ public void open() throws IOException, DatabaseException { if (!isOpen()) { @@ -170,8 +175,9 @@ public class CPEAnalyzer implements Analyzer { } /** - * Searches the data store of CPE entries, trying to identify the CPE for the given dependency based on the evidence contained - * within. The dependency passed in is updated with any identified CPE values. + * Searches the data store of CPE entries, trying to identify the CPE for + * the given dependency based on the evidence contained within. The + * dependency passed in is updated with any identified CPE values. * * @param dependency the dependency to search for CPE entries on. * @throws CorruptIndexException is thrown when the Lucene index is corrupt. @@ -215,9 +221,10 @@ public class CPEAnalyzer implements Analyzer { } /** - * Returns the text created by concatenating the text and the values from the EvidenceCollection (filtered for a specific - * confidence). This attempts to prevent duplicate terms from being added.
    Note, if the evidence is longer then 200 - * characters it will be truncated. + * Returns the text created by concatenating the text and the values from + * the EvidenceCollection (filtered for a specific confidence). This + * attempts to prevent duplicate terms from being added.
    Note, if + * the evidence is longer then 200 characters it will be truncated. * * @param text the base text. * @param ec an EvidenceCollection @@ -248,17 +255,19 @@ public class CPEAnalyzer implements Analyzer { /** *

    - * Searches the Lucene CPE index to identify possible CPE entries associated with the supplied vendor, product, and - * version.

    + * Searches the Lucene CPE index to identify possible CPE entries associated + * with the supplied vendor, product, and version.

    * *

    - * If either the vendorWeightings or productWeightings lists have been populated this data is used to add weighting factors to - * the search.

    + * If either the vendorWeightings or productWeightings lists have been + * populated this data is used to add weighting factors to the search.

    * * @param vendor the text used to search the vendor field * @param product the text used to search the product field - * @param vendorWeightings a list of strings to use to add weighting factors to the vendor field - * @param productWeightings Adds a list of strings that will be used to add weighting factors to the product search + * @param vendorWeightings a list of strings to use to add weighting factors + * to the vendor field + * @param productWeightings Adds a list of strings that will be used to add + * weighting factors to the product search * @return a list of possible CPE values */ protected List searchCPE(String vendor, String product, @@ -297,16 +306,20 @@ public class CPEAnalyzer implements Analyzer { /** *

    - * Builds a Lucene search string by properly escaping data and constructing a valid search query.

    + * Builds a Lucene search string by properly escaping data and constructing + * a valid search query.

    * *

    - * If either the possibleVendor or possibleProducts lists have been populated this data is used to add weighting factors to - * the search string generated.

    + * If either the possibleVendor or possibleProducts lists have been + * populated this data is used to add weighting factors to the search string + * generated.

    * * @param vendor text to search the vendor field * @param product text to search the product field - * @param vendorWeighting a list of strings to apply to the vendor to boost the terms weight - * @param productWeightings a list of strings to apply to the product to boost the terms weight + * @param vendorWeighting a list of strings to apply to the vendor to boost + * the terms weight + * @param productWeightings a list of strings to apply to the product to + * boost the terms weight * @return the Lucene query */ protected String buildSearch(String vendor, String product, @@ -327,13 +340,17 @@ public class CPEAnalyzer implements Analyzer { } /** - * This method constructs a Lucene query for a given field. The searchText is split into separate words and if the word is - * within the list of weighted words then an additional weighting is applied to the term as it is appended into the query. + * This method constructs a Lucene query for a given field. The searchText + * is split into separate words and if the word is within the list of + * weighted words then an additional weighting is applied to the term as it + * is appended into the query. * * @param sb a StringBuilder that the query text will be appended to. - * @param field the field within the Lucene index that the query is searching. + * @param field the field within the Lucene index that the query is + * searching. * @param searchText text used to construct the query. - * @param weightedText a list of terms that will be considered higher importance when searching. + * @param weightedText a list of terms that will be considered higher + * importance when searching. * @return if the append was successful. */ private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set weightedText) { @@ -379,7 +396,8 @@ public class CPEAnalyzer implements Analyzer { } /** - * Removes characters from the input text that are not used within the CPE index. + * Removes characters from the input text that are not used within the CPE + * index. * * @param text is the text to remove the characters from. * @return the text having removed some characters. @@ -389,7 +407,8 @@ public class CPEAnalyzer implements Analyzer { } /** - * Compares two strings after lower casing them and removing the non-alpha characters. + * Compares two strings after lower casing them and removing the non-alpha + * characters. * * @param l string one to compare. * @param r string two to compare. @@ -406,8 +425,9 @@ public class CPEAnalyzer implements Analyzer { } /** - * Ensures that the CPE Identified matches the dependency. This validates that the product, vendor, and version information - * for the CPE are contained within the dependencies evidence. + * Ensures that the CPE Identified matches the dependency. This validates + * that the product, vendor, and version information for the CPE are + * contained within the dependencies evidence. * * @param entry a CPE entry. * @param dependency the dependency that the CPE entries could be for. @@ -474,11 +494,13 @@ public class CPEAnalyzer implements Analyzer { } /** - * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency. + * Analyzes a dependency and attempts to determine if there are any CPE + * identifiers for this dependency. * * @param dependency The Dependency to analyze. * @param engine The analysis engine - * @throws AnalysisException is thrown if there is an issue analyzing the dependency. + * @throws AnalysisException is thrown if there is an issue analyzing the + * dependency. */ @Override public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException { @@ -494,15 +516,19 @@ public class CPEAnalyzer implements Analyzer { } /** - * Retrieves a list of CPE values from the CveDB based on the vendor and product passed in. The list is then validated to find - * only CPEs that are valid for the given dependency. It is possible that the CPE identified is a best effort "guess" based on - * the vendor, product, and version information. + * Retrieves a list of CPE values from the CveDB based on the vendor and + * product passed in. The list is then validated to find only CPEs that are + * valid for the given dependency. It is possible that the CPE identified is + * a best effort "guess" based on the vendor, product, and version + * information. * * @param dependency the Dependency being analyzed * @param vendor the vendor for the CPE being analyzed * @param product the product for the CPE being analyzed - * @param currentConfidence the current confidence being used during analysis - * @return true if an identifier was added to the dependency; otherwise false + * @param currentConfidence the current confidence being used during + * analysis + * @return true if an identifier was added to the dependency; + * otherwise false * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported */ protected boolean determineIdentifiers(Dependency dependency, String vendor, String product, @@ -512,7 +538,7 @@ public class CPEAnalyzer implements Analyzer { Confidence bestGuessConf = null; boolean hasBroadMatch = false; final List collected = new ArrayList(); - + //TODO the following algorithm incorrectly identifies things as a lower version // if there lower confidence evidence when the current (highest) version number // is newer then anything in the NVD. @@ -538,15 +564,13 @@ public class CPEAnalyzer implements Analyzer { final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); collected.add(match); - } else { - //TODO the following isn't quite right is it? need to think about this guessing game a bit more. - if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() - && evVer.matchesAtLeastThreeLevels(dbVer)) { - if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { - if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { - bestGuess = dbVer; - bestGuessConf = conf; - } + } else //TODO the following isn't quite right is it? need to think about this guessing game a bit more. + if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() + && evVer.matchesAtLeastThreeLevels(dbVer)) { + if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { + if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { + bestGuess = dbVer; + bestGuessConf = conf; } } } @@ -605,14 +629,16 @@ public class CPEAnalyzer implements Analyzer { */ BEST_GUESS, /** - * The entire vendor/product group must be added (without a guess at version) because there is a CVE with a VS that only - * specifies vendor/product. + * The entire vendor/product group must be added (without a guess at + * version) because there is a CVE with a VS that only specifies + * vendor/product. */ BROAD_MATCH } /** - * A simple object to hold an identifier and carry information about the confidence in the identifier. + * A simple object to hold an identifier and carry information about the + * confidence in the identifier. */ private static class IdentifierMatch implements Comparable { @@ -622,8 +648,10 @@ public class CPEAnalyzer implements Analyzer { * @param type the type of identifier (such as CPE) * @param value the value of the identifier * @param url the URL of the identifier - * @param identifierConfidence the confidence in the identifier: best guess or exact match - * @param evidenceConfidence the confidence of the evidence used to find the identifier + * @param identifierConfidence the confidence in the identifier: best + * guess or exact match + * @param evidenceConfidence the confidence of the evidence used to find + * the identifier */ IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) { this.identifier = new Identifier(type, value, url); @@ -754,7 +782,8 @@ public class CPEAnalyzer implements Analyzer { //
    /** - * Standard implementation of compareTo that compares identifier confidence, evidence confidence, and then the identifier. + * Standard implementation of compareTo that compares identifier + * confidence, evidence confidence, and then the identifier. * * @param o the IdentifierMatch to compare to * @return the natural ordering of IdentifierMatch diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java index d6f4731bc..da6fb6078 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java @@ -644,7 +644,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { * @return whether evidence was identified parsing the manifest * @throws IOException if there is an issue reading the JAR file */ - protected boolean parseManifest(Dependency dependency, + protected boolean parseManifest(Dependency dependency, List classInformation) throws IOException { boolean foundSomething = false; diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java index 2782c9968..087184bdd 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java @@ -61,13 +61,30 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { * The phase that this analyzer is intended to run in. */ private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION; - + /** + * The filter defining which files will be analyzed. + */ private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build(); + /** + * Name. + */ public static final String NAME = "Name: "; + /** + * Version. + */ public static final String VERSION = "Version: "; + /** + * Advisory. + */ public static final String ADVISORY = "Advisory: "; + /** + * Criticality. + */ public static final String CRITICALITY = "Criticality: "; + /** + * The DAL. + */ private CveDB cvedb; /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java index 763f35b70..8aa06c797 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java @@ -60,9 +60,11 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { /** *

    - * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database.

    + * Downloads the latest NVD CVE XML file from the web and imports it into + * the current CVE Database.

    * - * @throws UpdateException is thrown if there is an error updating the database + * @throws UpdateException is thrown if there is an error updating the + * database */ @Override public void update() throws UpdateException { @@ -79,7 +81,7 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); if (updateable.isUpdateNeeded()) { performUpdate(updateable); - } + } } } catch (MalformedURLException ex) { LOGGER.warn( @@ -99,12 +101,15 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { } /** - * Checks if the NVD CVE XML files were last checked recently. As an optimization, we can avoid repetitive checks against the - * NVD. Setting CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before checking again. A database property - * stores the timestamp of the last check. + * Checks if the NVD CVE XML files were last checked recently. As an + * optimization, we can avoid repetitive checks against the NVD. Setting + * CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before + * checking again. A database property stores the timestamp of the last + * check. * * @return true to proceed with the check, or false to skip. - * @throws UpdateException thrown when there is an issue checking for updates. + * @throws UpdateException thrown when there is an issue checking for + * updates. */ private boolean checkUpdate() throws UpdateException { boolean proceed = true; @@ -146,11 +151,13 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { } /** - * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database. + * Downloads the latest NVD CVE XML file from the web and imports it into + * the current CVE Database. * - * @param updateable a collection of NVD CVE data file references that need to be downloaded and processed to update the + * @param updateable a collection of NVD CVE data file references that need + * to be downloaded and processed to update the database + * @throws UpdateException is thrown if there is an error updating the * database - * @throws UpdateException is thrown if there is an error updating the database */ public void performUpdate(UpdateableNvdCve updateable) throws UpdateException { int maxUpdates = 0; @@ -244,13 +251,18 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { } /** - * Determines if the index needs to be updated. This is done by fetching the NVD CVE meta data and checking the last update - * date. If the data needs to be refreshed this method will return the NvdCveUrl for the files that need to be updated. + * Determines if the index needs to be updated. This is done by fetching the + * NVD CVE meta data and checking the last update date. If the data needs to + * be refreshed this method will return the NvdCveUrl for the files that + * need to be updated. * * @return the collection of files that need to be updated - * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta data is incorrect - * @throws DownloadFailedException is thrown if there is an error. downloading the NVD CVE download data file - * @throws UpdateException Is thrown if there is an issue with the last updated properties file + * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta + * data is incorrect + * @throws DownloadFailedException is thrown if there is an error. + * downloading the NVD CVE download data file + * @throws UpdateException Is thrown if there is an issue with the last + * updated properties file */ protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException { UpdateableNvdCve updates = null; @@ -314,9 +326,12 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { * Retrieves the timestamps from the NVD CVE meta data file. * * @return the timestamp from the currently published nvdcve downloads page - * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data is incorrect. - * @throws DownloadFailedException thrown if there is an error downloading the nvd cve meta data file - * @throws InvalidDataException thrown if there is an exception parsing the timestamps + * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data + * is incorrect. + * @throws DownloadFailedException thrown if there is an error downloading + * the nvd cve meta data file + * @throws InvalidDataException thrown if there is an exception parsing the + * timestamps * @throws InvalidSettingException thrown if the settings are invalid */ private UpdateableNvdCve retrieveCurrentTimestampsFromWeb() diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Reference.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Reference.java index 3d4b2ee26..5be391a27 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Reference.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Reference.java @@ -20,7 +20,8 @@ package org.owasp.dependencycheck.dependency; import java.io.Serializable; /** - * An external reference for a vulnerability. This contains a name, URL, and a source. + * An external reference for a vulnerability. This contains a name, URL, and a + * source. * * @author Jeremy Long */ @@ -99,7 +100,7 @@ public class Reference implements Serializable, Comparable { @Override public String toString() { - return "Reference: { name='"+this.name+"', url='"+this.url+"', source='"+this.source+"' }"; + return "Reference: { name='" + this.name + "', url='" + this.url + "', source='" + this.source + "' }"; } @Override diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java index ed278076b..3de3f99ee 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java @@ -387,7 +387,7 @@ public class Vulnerability implements Serializable, Comparable { @Override public String toString() { - StringBuilder sb = new StringBuilder("Vulnerability "); + final StringBuilder sb = new StringBuilder("Vulnerability "); sb.append(this.name); sb.append("\nReferences:\n"); for (Iterator i = this.references.iterator(); i.hasNext();) { From 8680ecd033b991b32033433ec92e570fcdffa36c Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 8 Jun 2016 06:40:07 -0400 Subject: [PATCH 49/55] updated documentation for experimental analyzers --- .../src/site/markdown/configuration.md | 34 +++++++++---------- .../src/site/markdown/arguments.md | 18 +++++----- .../src/site/markdown/configuration.md | 22 ++++++------ .../dependency-check-gradle/configuration.md | 15 ++++---- 4 files changed, 45 insertions(+), 44 deletions(-) diff --git a/dependency-check-ant/src/site/markdown/configuration.md b/dependency-check-ant/src/site/markdown/configuration.md index a58b73716..e613c45af 100644 --- a/dependency-check-ant/src/site/markdown/configuration.md +++ b/dependency-check-ant/src/site/markdown/configuration.md @@ -43,7 +43,7 @@ proxyPort | The Proxy Port. proxyUsername | Defines the proxy user name. |   proxyPassword | Defines the proxy password. |   connectionTimeout | The URL Connection Timeout. |   -enableExperimental | Enable the experimental analyzers. | false +enableExperimental | Enable the experimental analyzers. If not enabled the *experimental* analyzers (see below) will not be loaded or used. | false Analyzer Configuration ==================== @@ -53,26 +53,26 @@ Note, that specific analyzers will automatically disable themselves if no file types that they support are detected - so specifically disabling them may not be needed. -Property | Description | Default Value -------------------------------|---------------------------------------------------------------------------|------------------ -archiveAnalyzerEnabled | Sets whether the Archive Analyzer will be used. | true +Property | Description | Default Value +------------------------------|-----------------------------------------------------------------------------------|------------------ +archiveAnalyzerEnabled | Sets whether the Archive Analyzer will be used. | true zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |   -jarAnalyzer | Sets whether the Jar Analyzer will be used. | true +jarAnalyzer | Sets whether the Jar Analyzer will be used. | true centralAnalyzerEnabled | Sets whether the Central Analyzer will be used. **Disabling this analyzer is not recommended as it could lead to false negatives (e.g. libraries that have vulnerabilities may not be reported correctly).** If this analyzer is being disabled there is a good chance you also want to disable the Nexus Analyzer (see below). | true nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. This analyzer is superceded by the Central Analyzer; however, you can configure this to run against a Nexus Pro installation. | true nexusUrl | Defines the Nexus web service endpoint (example http://domain.enterprise/nexus/service/local/). If not set the Nexus Analyzer will be disabled. |   -nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true -pyDistributionAnalyzerEnabled | Sets whether the Python Distribution Analyzer will be used. | true -pyPackageAnalyzerEnabled | Sets whether the Python Package Analyzer will be used. | true -rubygemsAnalyzerEnabled | Sets whether the Ruby Gemspec Analyzer will be used. | true -opensslAnalyzerEnabled | Sets whether or not the openssl Analyzer should be used. | true -cmakeAnalyzerEnabled | Sets whether or not the CMake Analyzer should be used. | true -autoconfAnalyzerEnabled | Sets whether or not the autoconf Analyzer should be used. | true -composerAnalyzerEnabled | Sets whether or not the PHP Composer Lock File Analyzer should be used. | true -nodeAnalyzerEnabled | Sets whether or not the Node.js Analyzer should 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. |   +nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true +pyDistributionAnalyzerEnabled | Sets whether the *experimental* Python Distribution Analyzer will be used. | true +pyPackageAnalyzerEnabled | Sets whether the *experimental* Python Package Analyzer will be used. | true +rubygemsAnalyzerEnabled | Sets whether the *experimental* Ruby Gemspec Analyzer will be used. | true +opensslAnalyzerEnabled | Sets whether the openssl Analyzer should be used. | true +cmakeAnalyzerEnabled | Sets whether the *experimental* CMake Analyzer should be used. | true +autoconfAnalyzerEnabled | Sets whether the *experimental* autoconf Analyzer should be used. | true +composerAnalyzerEnabled | Sets whether the *experimental* PHP Composer Lock File Analyzer should be used. | true +nodeAnalyzerEnabled | Sets whether the *experimental* Node.js Analyzer should be used. | true +nuspecAnalyzerEnabled | Sets whether the .NET Nuget Nuspec Analyzer will be used. | true +assemblyAnalyzerEnabled | Sets whether the .NET Assembly Analyzer should be used. | true +pathToMono | The path to Mono for .NET assembly analysis on non-windows systems. |   Advanced Configuration ==================== diff --git a/dependency-check-cli/src/site/markdown/arguments.md b/dependency-check-cli/src/site/markdown/arguments.md index 876eee216..5cd86379c 100644 --- a/dependency-check-cli/src/site/markdown/arguments.md +++ b/dependency-check-cli/src/site/markdown/arguments.md @@ -18,7 +18,7 @@ Short | Argument Name   | Parameter | Description | Requir | \-\-advancedHelp | | Print the advanced help message. | Optional \-v | \-\-version | | Print the version information. | Optional | \-\-cveValidForHours | \ | The number of hours to wait before checking for new updates from the NVD. The default is 4 hours. | Optional - | \-\-experimental | | Enable the experimental analyzers. | Optional + | \-\-experimental | | Enable the experimental analyzers. If not set the analyzers marked as experimental below will not be loaded or used. | Optional Advanced Options ================ @@ -30,18 +30,18 @@ Short | Argument Name        | Paramete | \-\-cveUrl20Base | \ | Base URL for each year's CVE 2.0, the %d will be replaced with the year | https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz \-P | \-\-propertyfile | \ | Specifies a file that contains properties to use instead of applicaion defaults. |   | \-\-updateonly | | If set only the update phase of dependency-check will be executed; no scan will be executed and no report will be generated. |   - | \-\-disablePyDist | | Sets whether the Python Distribution Analyzer will be used. | false - | \-\-disablePyPkg | | Sets whether the Python Package Analyzer will be used. | false - | \-\-disableNodeJS | | Sets whether the Node.js Package Analyzer will be used. | false - | \-\-disableRubygems | | Sets whether the Ruby Gemspec Analyzer will be used. | false - | \-\-disableBundleAudit | | Sets whether the Ruby Bundler Audit Analyzer will be used. | false - | \-\-disableAutoconf | | Sets whether the Autoconf Analyzer will be used. | false + | \-\-disablePyDist | | Sets whether the *experimental* Python Distribution Analyzer will be used. | false + | \-\-disablePyPkg | | Sets whether the *experimental* Python Package Analyzer will be used. | false + | \-\-disableNodeJS | | Sets whether the *experimental* Node.js Package Analyzer will be used. | false + | \-\-disableRubygems | | Sets whether the *experimental* Ruby Gemspec Analyzer will be used. | false + | \-\-disableBundleAudit | | Sets whether the *experimental* Ruby Bundler Audit Analyzer will be used. | false + | \-\-disableAutoconf | | Sets whether the *experimental* Autoconf Analyzer will be used. | false | \-\-disableOpenSSL | | Sets whether the OpenSSL Analyzer will be used. | false - | \-\-disableCmake | | Sets whether the Cmake Analyzer will be disabled. | false + | \-\-disableCmake | | Sets whether the *experimental* Cmake Analyzer will be disabled. | false | \-\-disableArchive | | Sets whether the Archive Analyzer will be disabled. | false | \-\-zipExtensions | \ | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |   | \-\-disableJar | | Sets whether the Jar Analyzer will be disabled. | false - | \-\-disableComposer | | Sets whether the PHP Composer Lock File Analyzer will be disabled. | false + | \-\-disableComposer | | Sets whether the *experimental* PHP Composer Lock File Analyzer will be disabled. | false | \-\-disableCentral | | Sets whether the Central Analyzer will be used. **Disabling this analyzer is not recommended as it could lead to false negatives (e.g. libraries that have vulnerabilities may not be reported correctly).** If this analyzer is being disabled there is a good chance you also want to disable the Nexus Analyzer. | false | \-\-disableNexus | | Sets whether the Nexus Analyzer will be used. Note, this has been superceded by the Central Analyzer. However, you can configure the Nexus URL to utilize an internally hosted Nexus Pro server. | false | \-\-nexus | \ | The url to the Nexus Server's web service end point (example: http://domain.enterprise/nexus/service/local/). If not set the Nexus Analyzer will be disabled. |   diff --git a/dependency-check-maven/src/site/markdown/configuration.md b/dependency-check-maven/src/site/markdown/configuration.md index e35574aff..efc44c27a 100644 --- a/dependency-check-maven/src/site/markdown/configuration.md +++ b/dependency-check-maven/src/site/markdown/configuration.md @@ -25,7 +25,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) |   -enableExperimental | Enable the experimental analyzers | false +enableExperimental | Enable the experimental analyzers. If not enabled the *experimental* analyzers (see below) will not be loaded or used. | false Analyzer Configuration ==================== @@ -44,16 +44,16 @@ centralAnalyzerEnabled | Sets whether Central Analyzer will be used. If t nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. This analyzer is superceded by the Central Analyzer; however, you can configure this to run against a Nexus Pro installation. | true nexusUrl | Defines the Nexus Server's web service end point (example http://domain.enterprise/service/local/). If not set the Nexus Analyzer will be disabled. |   nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true -pyDistributionAnalyzerEnabled | Sets whether the Python Distribution Analyzer will be used. | true -pyPackageAnalyzerEnabled | Sets whether the Python Package Analyzer will be used. | true -rubygemsAnalyzerEnabled | Sets whether the Ruby Gemspec Analyzer will be used. | true -opensslAnalyzerEnabled | Sets whether or not the openssl Analyzer should be used. | true -cmakeAnalyzerEnabled | Sets whether or not the CMake Analyzer should be used. | true -autoconfAnalyzerEnabled | Sets whether or not the autoconf Analyzer should be used. | true -composerAnalyzerEnabled | Sets whether or not the PHP Composer Lock File Analyzer should be used. | true -nodeAnalyzerEnabled | Sets whether or not the Node.js Analyzer should 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 +pyDistributionAnalyzerEnabled | Sets whether the *experimental* Python Distribution Analyzer will be used. | true +pyPackageAnalyzerEnabled | Sets whether the *experimental* Python Package Analyzer will be used. | true +rubygemsAnalyzerEnabled | Sets whether the *experimental* Ruby Gemspec Analyzer will be used. | true +opensslAnalyzerEnabled | Sets whether the openssl Analyzer should be used. | true +cmakeAnalyzerEnabled | Sets whether the *experimental* CMake Analyzer should be used. | true +autoconfAnalyzerEnabled | Sets whether the *experimental* autoconf Analyzer should be used. | true +composerAnalyzerEnabled | Sets whether the *experimental* PHP Composer Lock File Analyzer should be used. | true +nodeAnalyzerEnabled | Sets whether the *experimental* Node.js Analyzer should be used. | true +nuspecAnalyzerEnabled | Sets whether the .NET Nuget Nuspec Analyzer will be used. | true +assemblyAnalyzerEnabled | Sets whether the .NET Assembly Analyzer should be used. | true pathToMono | The path to Mono for .NET assembly analysis on non-windows systems. |   Advanced Configuration diff --git a/src/site/markdown/dependency-check-gradle/configuration.md b/src/site/markdown/dependency-check-gradle/configuration.md index 7d2516118..06ecfb673 100644 --- a/src/site/markdown/dependency-check-gradle/configuration.md +++ b/src/site/markdown/dependency-check-gradle/configuration.md @@ -87,6 +87,7 @@ analyzers is likely not needed. Property | Description | Default Value ----------------------|---------------------------------------------------------------------------|------------------ +experimentalEnabled | Sets whether the experimental analyzers will be used. If not set to true the analyzers marked as experimental (see below) will not be used | false archiveEnabled | Sets whether the Archive Analyzer will be used. | true zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |   jarEnabled | Sets whether Jar Analyzer will be used. | true @@ -94,14 +95,14 @@ centralEnabled | Sets whether Central Analyzer will be used. If this anal nexusEnabled | Sets whether Nexus Analyzer will be used. This analyzer is superceded by the Central Analyzer; however, you can configure this to run against a Nexus Pro installation. | true nexusUrl | Defines the Nexus Server's web service end point (example http://domain.enterprise/service/local/). If not set the Nexus Analyzer will be disabled. |   nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true -pyDistributionEnabled | Sets whether the Python Distribution Analyzer will be used. | true -pyPackageEnabled | Sets whether the Python Package Analyzer will be used. | true -rubygemsEnabled | Sets whether the Ruby Gemspec Analyzer will be used. | true +pyDistributionEnabled | Sets whether the *experimental* Python Distribution Analyzer will be used. | true +pyPackageEnabled | Sets whether the *experimental* Python Package Analyzer will be used. | true +rubygemsEnabled | Sets whether the *experimental* Ruby Gemspec Analyzer will be used. | true opensslEnabled | Sets whether or not the openssl Analyzer should be used. | true -cmakeEnabled | Sets whether or not the CMake Analyzer should be used. | true -autoconfEnabled | Sets whether or not the autoconf Analyzer should be used. | true -composerEnabled | Sets whether or not the PHP Composer Lock File Analyzer should be used. | true -nodeEnabled | Sets whether or not the Node.js Analyzer should be used. | true +cmakeEnabled | Sets whether or not the *experimental* CMake Analyzer should be used. | true +autoconfEnabled | Sets whether or not the *experimental* autoconf Analyzer should be used. | true +composerEnabled | Sets whether or not the *experimental* PHP Composer Lock File Analyzer should be used. | true +nodeEnabled | Sets whether or not the *experimental* Node.js Analyzer should be used. | true nuspecEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true assemblyEnabled | 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. |   From 7e8749146e7dc6fa9bcad0f23e3f60fa8eb89ca8 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 11 Jun 2016 08:12:09 -0400 Subject: [PATCH 50/55] updated documentation --- src/site/markdown/index.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index fb1931477..81273af65 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -2,11 +2,14 @@ About ==================== OWASP dependency-check is an open source solution the OWASP Top 10 2013 entry: [A9 - Using Components with Known Vulnerabilities](https://www.owasp.org/index.php/Top_10_2013-A9-Using_Components_with_Known_Vulnerabilities). -Dependency-check can currently be used to scan Java, .NET, Python, Ruby (gemspec), PHP (composer), and -Node.js applications (and their dependent libraries) to identify known -vulnerable components. In addition, Dependency-check can be used to scan some -source code, including OpenSSL source code and projects that use -[Autoconf](https://www.gnu.org/software/autoconf/) or +Dependency-check can currently be used to scan Java and .NET applications to +identify the use of known vulnerable components. Experimental analyzers for +Python, Ruby, PHP (composer), and Node.js applications; these are experimental +due to the possible false positive and false negative rates. To use the experimental +analyzers they must be specifically enabled via the appropriate _experimental_ +configuration. In addition, dependency-check has experimental analyzers that can +be used to scan some C/C++ source code, including OpenSSL source code and projects +that use [Autoconf](https://www.gnu.org/software/autoconf/) or [CMake](http://www.cmake.org/overview/). The problem with using known vulnerable components was covered in a paper by @@ -30,3 +33,10 @@ OWASP dependency-check's core analysis engine can be used as: - [Ant Task](dependency-check-ant/index.html) - [Gradle Plugin](dependency-check-gradle/index.html) - [Jenkins Plugin](dependency-check-jenkins/index.html) + +For help with dependency-check the following resource can be used: + +- Post to the [google group](https://groups.google.com/forum/#!forum/dependency-check): +[subscribe](mailto://dependency-check+subscribe@googlegroups.com), +[post](mailto://dependency-check@googlegroups.com), +- Open a [github issue](https://github.com/jeremylong/DependencyCheck/issues) \ No newline at end of file From c34dc97bd4b12dea25b44856e524786318660d08 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 11 Jun 2016 08:13:14 -0400 Subject: [PATCH 51/55] updated snapshot version --- dependency-check-ant/pom.xml | 2 +- dependency-check-cli/pom.xml | 2 +- dependency-check-core/pom.xml | 2 +- dependency-check-maven/pom.xml | 2 +- dependency-check-utils/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dependency-check-ant/pom.xml b/dependency-check-ant/pom.xml index 74cd4e634..03b758834 100644 --- a/dependency-check-ant/pom.xml +++ b/dependency-check-ant/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.3.7-SNAPSHOT + 1.4.0-SNAPSHOT dependency-check-ant diff --git a/dependency-check-cli/pom.xml b/dependency-check-cli/pom.xml index 33b10ec80..aa2e2faef 100644 --- a/dependency-check-cli/pom.xml +++ b/dependency-check-cli/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.3.7-SNAPSHOT + 1.4.0-SNAPSHOT dependency-check-cli diff --git a/dependency-check-core/pom.xml b/dependency-check-core/pom.xml index d136b7cef..df94d7f5b 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.3.7-SNAPSHOT + 1.4.0-SNAPSHOT dependency-check-core diff --git a/dependency-check-maven/pom.xml b/dependency-check-maven/pom.xml index 65286b6aa..88798e3e9 100644 --- a/dependency-check-maven/pom.xml +++ b/dependency-check-maven/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.3.7-SNAPSHOT + 1.4.0-SNAPSHOT dependency-check-maven diff --git a/dependency-check-utils/pom.xml b/dependency-check-utils/pom.xml index dbf44cd64..f75420f2d 100644 --- a/dependency-check-utils/pom.xml +++ b/dependency-check-utils/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.3.7-SNAPSHOT + 1.4.0-SNAPSHOT dependency-check-utils diff --git a/pom.xml b/pom.xml index 496ab2fdd..c73cc7db3 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long org.owasp dependency-check-parent - 1.3.7-SNAPSHOT + 1.4.0-SNAPSHOT pom From a2309e1c2efa5b5d1dd2e6f6c869755316647477 Mon Sep 17 00:00:00 2001 From: Michal Srb Date: Tue, 14 Jun 2016 21:34:04 +0200 Subject: [PATCH 52/55] Correctly apply weightings when searching for CPEs --- .../java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java | 4 ++-- .../dependencycheck/analyzer/CPEAnalyzerIntegrationTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java index 43528d863..d2fcfb14a 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java @@ -198,8 +198,8 @@ public class CPEAnalyzer implements Analyzer { LOGGER.debug("product search: {}", products); } if (!vendors.isEmpty() && !products.isEmpty()) { - final List entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(), - dependency.getVendorEvidence().getWeighting()); + final List entries = searchCPE(vendors, products, dependency.getVendorEvidence().getWeighting(), + dependency.getProductEvidence().getWeighting()); if (entries == null) { continue; } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.java index 36c6e7478..7eb339eff 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.java @@ -240,7 +240,7 @@ public class CPEAnalyzerIntegrationTest extends BaseDBTestCase { Set vendorWeightings = Collections.singleton("apache"); - List result = instance.searchCPE(vendor, product, productWeightings, vendorWeightings); + List result = instance.searchCPE(vendor, product, vendorWeightings, productWeightings); instance.close(); boolean found = false; From 6be161a546cd9477f02877872ed8a07bf1101b91 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 15 Jun 2016 06:19:06 -0400 Subject: [PATCH 53/55] updated experimental documentation --- .../src/site/markdown/configuration.md | 16 +++++++------- .../src/site/markdown/arguments.md | 18 +++++++-------- .../src/site/markdown/configuration.md | 16 +++++++------- src/site/markdown/analyzers/index.md | 22 ++++++++++++++----- .../dependency-check-gradle/configuration.md | 16 +++++++------- 5 files changed, 49 insertions(+), 39 deletions(-) diff --git a/dependency-check-ant/src/site/markdown/configuration.md b/dependency-check-ant/src/site/markdown/configuration.md index e613c45af..e37ceeda1 100644 --- a/dependency-check-ant/src/site/markdown/configuration.md +++ b/dependency-check-ant/src/site/markdown/configuration.md @@ -43,7 +43,7 @@ proxyPort | The Proxy Port. proxyUsername | Defines the proxy user name. |   proxyPassword | Defines the proxy password. |   connectionTimeout | The URL Connection Timeout. |   -enableExperimental | Enable the experimental analyzers. If not enabled the *experimental* analyzers (see below) will not be loaded or used. | false +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 ==================== @@ -62,14 +62,14 @@ centralAnalyzerEnabled | Sets whether the Central Analyzer will be used. nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. This analyzer is superceded by the Central Analyzer; however, you can configure this to run against a Nexus Pro installation. | true nexusUrl | Defines the Nexus web service endpoint (example http://domain.enterprise/nexus/service/local/). If not set the Nexus Analyzer will be disabled. |   nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true -pyDistributionAnalyzerEnabled | Sets whether the *experimental* Python Distribution Analyzer will be used. | true -pyPackageAnalyzerEnabled | Sets whether the *experimental* Python Package Analyzer will be used. | true -rubygemsAnalyzerEnabled | Sets whether the *experimental* Ruby Gemspec Analyzer will be used. | true +pyDistributionAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Python Distribution Analyzer will be used. | true +pyPackageAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Python Package Analyzer will be used. | true +rubygemsAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Ruby Gemspec Analyzer will be used. | true opensslAnalyzerEnabled | Sets whether the openssl Analyzer should be used. | true -cmakeAnalyzerEnabled | Sets whether the *experimental* CMake Analyzer should be used. | true -autoconfAnalyzerEnabled | Sets whether the *experimental* autoconf Analyzer should be used. | true -composerAnalyzerEnabled | Sets whether the *experimental* PHP Composer Lock File Analyzer should be used. | true -nodeAnalyzerEnabled | Sets whether the *experimental* Node.js Analyzer should be used. | true +cmakeAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) CMake Analyzer should be used. | true +autoconfAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) autoconf Analyzer should be used. | true +composerAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) PHP Composer Lock File Analyzer should be used. | true +nodeAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Node.js Analyzer should be used. | true nuspecAnalyzerEnabled | Sets whether the .NET Nuget Nuspec Analyzer will be used. | true assemblyAnalyzerEnabled | Sets whether the .NET Assembly Analyzer should be used. | true pathToMono | The path to Mono for .NET assembly analysis on non-windows systems. |   diff --git a/dependency-check-cli/src/site/markdown/arguments.md b/dependency-check-cli/src/site/markdown/arguments.md index 5cd86379c..83a8ab37c 100644 --- a/dependency-check-cli/src/site/markdown/arguments.md +++ b/dependency-check-cli/src/site/markdown/arguments.md @@ -18,7 +18,7 @@ Short | Argument Name   | Parameter | Description | Requir | \-\-advancedHelp | | Print the advanced help message. | Optional \-v | \-\-version | | Print the version information. | Optional | \-\-cveValidForHours | \ | The number of hours to wait before checking for new updates from the NVD. The default is 4 hours. | Optional - | \-\-experimental | | Enable the experimental analyzers. If not set the analyzers marked as experimental below will not be loaded or used. | Optional + | \-\-experimental | | Enable the [experimental analyzers](../analyzers/index.html). If not set the analyzers marked as experimental below will not be loaded or used. | Optional Advanced Options ================ @@ -30,18 +30,18 @@ Short | Argument Name        | Paramete | \-\-cveUrl20Base | \ | Base URL for each year's CVE 2.0, the %d will be replaced with the year | https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz \-P | \-\-propertyfile | \ | Specifies a file that contains properties to use instead of applicaion defaults. |   | \-\-updateonly | | If set only the update phase of dependency-check will be executed; no scan will be executed and no report will be generated. |   - | \-\-disablePyDist | | Sets whether the *experimental* Python Distribution Analyzer will be used. | false - | \-\-disablePyPkg | | Sets whether the *experimental* Python Package Analyzer will be used. | false - | \-\-disableNodeJS | | Sets whether the *experimental* Node.js Package Analyzer will be used. | false - | \-\-disableRubygems | | Sets whether the *experimental* Ruby Gemspec Analyzer will be used. | false - | \-\-disableBundleAudit | | Sets whether the *experimental* Ruby Bundler Audit Analyzer will be used. | false - | \-\-disableAutoconf | | Sets whether the *experimental* Autoconf Analyzer will be used. | false + | \-\-disablePyDist | | Sets whether the [experimental](../analyzers/index.html) Python Distribution Analyzer will be used. | false + | \-\-disablePyPkg | | Sets whether the [experimental](../analyzers/index.html) Python Package Analyzer will be used. | false + | \-\-disableNodeJS | | Sets whether the [experimental](../analyzers/index.html) Node.js Package Analyzer will be used. | false + | \-\-disableRubygems | | Sets whether the [experimental](../analyzers/index.html) Ruby Gemspec Analyzer will be used. | false + | \-\-disableBundleAudit | | Sets whether the [experimental](../analyzers/index.html) Ruby Bundler Audit Analyzer will be used. | false + | \-\-disableAutoconf | | Sets whether the [experimental](../analyzers/index.html) Autoconf Analyzer will be used. | false | \-\-disableOpenSSL | | Sets whether the OpenSSL Analyzer will be used. | false - | \-\-disableCmake | | Sets whether the *experimental* Cmake Analyzer will be disabled. | false + | \-\-disableCmake | | Sets whether the [experimental](../analyzers/index.html) Cmake Analyzer will be disabled. | false | \-\-disableArchive | | Sets whether the Archive Analyzer will be disabled. | false | \-\-zipExtensions | \ | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |   | \-\-disableJar | | Sets whether the Jar Analyzer will be disabled. | false - | \-\-disableComposer | | Sets whether the *experimental* PHP Composer Lock File Analyzer will be disabled. | false + | \-\-disableComposer | | Sets whether the [experimental](../analyzers/index.html) PHP Composer Lock File Analyzer will be disabled. | false | \-\-disableCentral | | Sets whether the Central Analyzer will be used. **Disabling this analyzer is not recommended as it could lead to false negatives (e.g. libraries that have vulnerabilities may not be reported correctly).** If this analyzer is being disabled there is a good chance you also want to disable the Nexus Analyzer. | false | \-\-disableNexus | | Sets whether the Nexus Analyzer will be used. Note, this has been superceded by the Central Analyzer. However, you can configure the Nexus URL to utilize an internally hosted Nexus Pro server. | false | \-\-nexus | \ | The url to the Nexus Server's web service end point (example: http://domain.enterprise/nexus/service/local/). If not set the Nexus Analyzer will be disabled. |   diff --git a/dependency-check-maven/src/site/markdown/configuration.md b/dependency-check-maven/src/site/markdown/configuration.md index efc44c27a..e310883d4 100644 --- a/dependency-check-maven/src/site/markdown/configuration.md +++ b/dependency-check-maven/src/site/markdown/configuration.md @@ -25,7 +25,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) |   -enableExperimental | Enable the experimental analyzers. If not enabled the *experimental* analyzers (see below) will not be loaded or used. | false +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 ==================== @@ -44,14 +44,14 @@ centralAnalyzerEnabled | Sets whether Central Analyzer will be used. If t nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. This analyzer is superceded by the Central Analyzer; however, you can configure this to run against a Nexus Pro installation. | true nexusUrl | Defines the Nexus Server's web service end point (example http://domain.enterprise/service/local/). If not set the Nexus Analyzer will be disabled. |   nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true -pyDistributionAnalyzerEnabled | Sets whether the *experimental* Python Distribution Analyzer will be used. | true -pyPackageAnalyzerEnabled | Sets whether the *experimental* Python Package Analyzer will be used. | true -rubygemsAnalyzerEnabled | Sets whether the *experimental* Ruby Gemspec Analyzer will be used. | true +pyDistributionAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Python Distribution Analyzer will be used. | true +pyPackageAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Python Package Analyzer will be used. | true +rubygemsAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Ruby Gemspec Analyzer will be used. | true opensslAnalyzerEnabled | Sets whether the openssl Analyzer should be used. | true -cmakeAnalyzerEnabled | Sets whether the *experimental* CMake Analyzer should be used. | true -autoconfAnalyzerEnabled | Sets whether the *experimental* autoconf Analyzer should be used. | true -composerAnalyzerEnabled | Sets whether the *experimental* PHP Composer Lock File Analyzer should be used. | true -nodeAnalyzerEnabled | Sets whether the *experimental* Node.js Analyzer should be used. | true +cmakeAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) CMake Analyzer should be used. | true +autoconfAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) autoconf Analyzer should be used. | true +composerAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) PHP Composer Lock File Analyzer should be used. | true +nodeAnalyzerEnabled | Sets whether the [experimental](../analyzers/index.html) Node.js Analyzer should be used. | true nuspecAnalyzerEnabled | Sets whether the .NET Nuget Nuspec Analyzer will be used. | true assemblyAnalyzerEnabled | Sets whether the .NET Assembly Analyzer should be used. | true pathToMono | The path to Mono for .NET assembly analysis on non-windows systems. |   diff --git a/src/site/markdown/analyzers/index.md b/src/site/markdown/analyzers/index.md index a4ffedb4b..f0aed77b2 100644 --- a/src/site/markdown/analyzers/index.md +++ b/src/site/markdown/analyzers/index.md @@ -7,14 +7,24 @@ to extract identification information from the files analyzed. | -------- | ------------------ | --------------- | | [Archive](./archive-analyzer.html) | Zip archive format (\*.zip, \*.ear, \*.war, \*.jar, \*.sar, \*.apk, \*.nupkg); Tape Archive Format (\*.tar); Gzip format (\*.gz, \*.tgz); Bzip2 format (\*.bz2, \*.tbz2) | Extracts archive contents, then scans contents with all available analyzers. | | [Assembly](./assembly-analyzer.html) | .NET Assemblies (\*.exe, \*.dll) | Uses [GrokAssembly.exe](https://github.com/colezlaw/GrokAssembly), which requires .NET Framework or Mono runtime to be installed. | -| [Autoconf](./autoconf.html) | Autoconf project configuration files (configure, configure.in, configure.ac) | [Regex](https://en.wikipedia.org/wiki/Regular_expression) scan for AC_INIT metadata, including in generated configuration script. | -| [Central](./central-analyzer.html) | Java archive files (\*.jar) | Searches Maven Central or a configured Nexus repository for the file's SHA1 hash. | | [CMake](./cmake.html) | CMake project files (CMakeLists.txt) and scripts (\*.cmake) | Regex scan for project initialization and version setting commands. | -| [Composer Lock](./composer-lock.html) | PHP [Composer](http://getcomposer.org) Lock files (composer.lock) | Parses PHP [Composer](http://getcomposer.org) lock files for exact versions of dependencies. | | [Jar](./jar-analyzer.html) | Java archive files (\*.jar); Web application archive (\*.war) | Examines archive manifest metadata, and Maven Project Object Model files (pom.xml). | -| [Nexus](./nexus-analyzer.html) | Java archive files (\*.jar) | Searches Sonatype or a configured Nexus repository for the file's SHA1 hash. In most cases, superceded by Central . | -| [Node.js](./nodejs.html) | NPM package specification files (package.json) | Parse JSON format for metadata. | | [Nuspec](./nuspec-analyzer.html) | Nuget package specification file (\*.nuspec) | Uses XPath to parse specification XML. | | [OpenSSL](./openssl.html) | OpenSSL Version Source Header File (opensslv.h) | Regex parse of the OPENSSL_VERSION_NUMBER macro definition. | + +Experimental Analyzers +---------------------- +The following analyzers can be enabled by enabling the _experimental_ configuration +option; see the documentation for the CLI, Ant, Maven, etc. for more information. +These analyzers are considered experimental due to the higher false positive and +false negative rates. Even though these are marked as experimental +several teams have found them useful in their current state. + +| Analyzer | File Types Scanned | Analysis Method | +| -------- | ------------------ | --------------- | +| [Autoconf](./autoconf.html) | Autoconf project configuration files (configure, configure.in, configure.ac) | [Regex](https://en.wikipedia.org/wiki/Regular_expression) scan for AC_INIT metadata, including in generated configuration script. | +| [CMake](./cmake.html) | CMake project files (CMakeLists.txt) and scripts (\*.cmake) | Regex scan for project initialization and version setting commands. | +| [Composer Lock](./composer-lock.html) | PHP [Composer](http://getcomposer.org) Lock files (composer.lock) | Parses PHP [Composer](http://getcomposer.org) lock files for exact versions of dependencies. | +| [Node.js](./nodejs.html) | NPM package specification files (package.json) | Parse JSON format for metadata. | | [Python](./python.html) | Python source files (\*.py); Package metadata files (PKG-INFO, METADATA); Package Distribution Files (\*.whl, \*.egg, \*.zip) | Regex scan of Python source files for setuptools metadata; Parse RFC822 header format for metadata in all other artifacts. | -| [Ruby Gemspec](./ruby-gemspec.html) | Ruby makefiles (Rakefile); Ruby Gemspec files (\*.gemspec) | Regex scan Gemspec initialization blocks for metadata. | \ No newline at end of file +| [Ruby Gemspec](./ruby-gemspec.html) | Ruby makefiles (Rakefile); Ruby Gemspec files (\*.gemspec) | Regex scan Gemspec initialization blocks for metadata. | diff --git a/src/site/markdown/dependency-check-gradle/configuration.md b/src/site/markdown/dependency-check-gradle/configuration.md index 06ecfb673..2b769df12 100644 --- a/src/site/markdown/dependency-check-gradle/configuration.md +++ b/src/site/markdown/dependency-check-gradle/configuration.md @@ -87,7 +87,7 @@ analyzers is likely not needed. Property | Description | Default Value ----------------------|---------------------------------------------------------------------------|------------------ -experimentalEnabled | Sets whether the experimental analyzers will be used. If not set to true the analyzers marked as experimental (see below) will not be used | false +experimentalEnabled | Sets whether the [experimental analyzers](../analyzers/index.html) will be used. If not set to true the analyzers marked as experimental (see below) will not be used | false archiveEnabled | Sets whether the Archive Analyzer will be used. | true zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |   jarEnabled | Sets whether Jar Analyzer will be used. | true @@ -95,14 +95,14 @@ centralEnabled | Sets whether Central Analyzer will be used. If this anal nexusEnabled | Sets whether Nexus Analyzer will be used. This analyzer is superceded by the Central Analyzer; however, you can configure this to run against a Nexus Pro installation. | true nexusUrl | Defines the Nexus Server's web service end point (example http://domain.enterprise/service/local/). If not set the Nexus Analyzer will be disabled. |   nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true -pyDistributionEnabled | Sets whether the *experimental* Python Distribution Analyzer will be used. | true -pyPackageEnabled | Sets whether the *experimental* Python Package Analyzer will be used. | true -rubygemsEnabled | Sets whether the *experimental* Ruby Gemspec Analyzer will be used. | true +pyDistributionEnabled | Sets whether the [experimental](../analyzers/index.html) Python Distribution Analyzer will be used. | true +pyPackageEnabled | Sets whether the [experimental](../analyzers/index.html) Python Package Analyzer will be used. | true +rubygemsEnabled | Sets whether the [experimental](../analyzers/index.html) Ruby Gemspec Analyzer will be used. | true opensslEnabled | Sets whether or not the openssl Analyzer should be used. | true -cmakeEnabled | Sets whether or not the *experimental* CMake Analyzer should be used. | true -autoconfEnabled | Sets whether or not the *experimental* autoconf Analyzer should be used. | true -composerEnabled | Sets whether or not the *experimental* PHP Composer Lock File Analyzer should be used. | true -nodeEnabled | Sets whether or not the *experimental* Node.js Analyzer should be used. | true +cmakeEnabled | Sets whether or not the [experimental](../analyzers/index.html) CMake Analyzer should be used. | true +autoconfEnabled | Sets whether or not the [experimental](../analyzers/index.html) autoconf Analyzer should be used. | true +composerEnabled | Sets whether or not the [experimental](../analyzers/index.html) PHP Composer Lock File Analyzer should be used. | true +nodeEnabled | Sets whether or not the [experimental](../analyzers/index.html) Node.js Analyzer should be used. | true nuspecEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true assemblyEnabled | 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. |   From 8324287bd64727c8947f965719abc67400e3c350 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 15 Jun 2016 06:50:45 -0400 Subject: [PATCH 54/55] updated proxy configuration information --- .../src/site/markdown/configuration.md | 2 +- .../src/site/markdown/configuration.md | 3 ++- src/site/markdown/data/proxy.md | 22 +++++++++++++++++++ .../dependency-check-gradle/configuration.md | 2 +- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/dependency-check-ant/src/site/markdown/configuration.md b/dependency-check-ant/src/site/markdown/configuration.md index e37ceeda1..e2bf57a24 100644 --- a/dependency-check-ant/src/site/markdown/configuration.md +++ b/dependency-check-ant/src/site/markdown/configuration.md @@ -38,7 +38,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) |   -proxyServer | The Proxy Server. |   +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. |   diff --git a/dependency-check-maven/src/site/markdown/configuration.md b/dependency-check-maven/src/site/markdown/configuration.md index e310883d4..44b68a512 100644 --- a/dependency-check-maven/src/site/markdown/configuration.md +++ b/dependency-check-maven/src/site/markdown/configuration.md @@ -79,7 +79,8 @@ metaFileName | Sets the name of the file to use for storing the metadata Proxy Configuration ==================== -Use [Maven's settings](https://maven.apache.org/settings.html#Proxies) to configure a proxy server. If multiple proxies +Use [Maven's settings](https://maven.apache.org/settings.html#Proxies) to configure a proxy server. Please see the +dependency-check [proxy configuration](../data/proxy.html) page for additional problem solving techniques. 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 diff --git a/src/site/markdown/data/proxy.md b/src/site/markdown/data/proxy.md index e6fdf6a63..b67fcacf8 100644 --- a/src/site/markdown/data/proxy.md +++ b/src/site/markdown/data/proxy.md @@ -9,3 +9,25 @@ to use a proxy to connect to the Internet. See the configuration settings for ea Note, it may also be possible to use the core [Java proxy](https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html) system properties instead of the configuration above. + +Certificate Errors +------------------ +In some cases if you setup a proxy the connection may still fail due to certificate +errors (see the log file from dependency-check). If you know which cert it's failing +on (either your proxy or NVD/CVE) you can either add the certificate itself or the +signing chain to your trust store. If you don't have access to modify the system +trust store (in $JAVA_HOME/lib/security/cacerts) you can copy it elsewhere and +import it using keytool, then specify that trust store on the command line +(`mvn -Djavax.net.ssl.trustStore=/path/to/cacerts`) or if you need to always +have that set, you can set the environment variable `JAVA_TOOL_OPTIONS` to have +`-Djavax.net.ssl.trustStore=/path/to/cacerts`. + +Still failing? +-------------- +In some cases the proxy is configured to block `HEAD` requests. While an attempt +is made by dependency-check to identify this situation it does not appear to be +100% successful. As such, the last thing to try is to add the property +`mvn -Ddownloader.quick.query.timestamp=false`. + +If trying the above and it still fails please open a ticket in the +[github repo](https://github.com/jeremylong/DependencyCheck/issues). \ No newline at end of file diff --git a/src/site/markdown/dependency-check-gradle/configuration.md b/src/site/markdown/dependency-check-gradle/configuration.md index 2b769df12..5234be304 100644 --- a/src/site/markdown/dependency-check-gradle/configuration.md +++ b/src/site/markdown/dependency-check-gradle/configuration.md @@ -34,7 +34,7 @@ dependencyCheck { Property | Description | Default Value ------------------|------------------------------------|------------------ -server | The proxy server. |   +server | The proxy server; see the [proxy configuration](../data/proxy.html) page for more information. |   port | The proxy port. |   username | Defines the proxy user name. |   password | Defines the proxy password. |   From d89b1fdc6a416362290ed1fdd2fe6dbdfa22f984 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 15 Jun 2016 06:51:05 -0400 Subject: [PATCH 55/55] updated proxy configuration information --- dependency-check-cli/src/site/markdown/arguments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependency-check-cli/src/site/markdown/arguments.md b/dependency-check-cli/src/site/markdown/arguments.md index 83a8ab37c..486acadfd 100644 --- a/dependency-check-cli/src/site/markdown/arguments.md +++ b/dependency-check-cli/src/site/markdown/arguments.md @@ -50,7 +50,7 @@ Short | Argument Name        | Paramete | \-\-disableAssembly | | Sets whether or not the .NET Assembly Analyzer should be used. | false | \-\-mono | \ | The path to Mono for .NET Assembly analysis on non-windows systems. |   | \-\-bundleAudit | | The path to the bundle-audit executable. |   - | \-\-proxyserver | \ | The proxy server to use when downloading resources. |   + | \-\-proxyserver | \ | The proxy server to use when downloading resources; see the [proxy configuration](../data/proxy.html) page for more information. |   | \-\-proxyport | \ | The proxy port to use when downloading resources. |   | \-\-connectiontimeout | \ | The connection timeout (in milliseconds) to use when downloading resources. |   | \-\-proxypass | \ | The proxy password to use when downloading resources. |