From f2778e5d28f926533ca948813a840a2870183b63 Mon Sep 17 00:00:00 2001 From: Anthony Whitford Date: Wed, 21 Oct 2015 23:19:57 -0700 Subject: [PATCH 1/5] Adding a setting to suppress repetitive NVD checks. --- .../main/java/org/owasp/dependencycheck/utils/Settings.java | 4 ++++ 1 file changed, 4 insertions(+) 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 6e600d9db..99baefe5e 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 @@ -117,6 +117,10 @@ public final class Settings { * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days). */ public static final String CVE_MODIFIED_VALID_FOR_DAYS = "cve.url.modified.validfordays"; + /** + * The properties key to control the skipping of the check for CVE updates. + */ + public static final String CVE_CHECK_VALID_FOR_HOURS = "cve.check.validforhours"; /** * The properties key for the telling us how many cve.url.* URLs exists. This is used in combination with CVE_BASE_URL to * be able to retrieve the URLs for all of the files that make up the NVD CVE listing. From cd5bf85245e6b0ad1e1994cf3d9769c5ba607e92 Mon Sep 17 00:00:00 2001 From: Anthony Whitford Date: Wed, 21 Oct 2015 23:21:25 -0700 Subject: [PATCH 2/5] Added a database property for recording the last time the NVD CVE was checked. --- .../owasp/dependencycheck/data/nvdcve/DatabaseProperties.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.java index f3ae9b50c..ad1cf8434 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.java @@ -45,6 +45,10 @@ public class DatabaseProperties { * updates).. */ public static final String MODIFIED = "Modified"; + /** + * The properties file key for the last checked field - used to store the last check time of the Modified NVD CVE xml file. + */ + public static final String LAST_CHECKED = "NVD CVE Checked"; /** * The properties file key for the last updated field - used to store the last updated time of the Modified NVD CVE xml file. */ From 1f6168366bf508e8ed7c86931468dd0091f1b24e Mon Sep 17 00:00:00 2001 From: Anthony Whitford Date: Wed, 21 Oct 2015 23:23:47 -0700 Subject: [PATCH 3/5] Added logic to optionally prevent overly repetitive checks for NVD CVE changes. --- .../data/update/NvdCveUpdater.java | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 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 570c542ea..3b3215e94 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 @@ -66,9 +66,11 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { public void update() throws UpdateException { try { openDataStores(); - final UpdateableNvdCve updateable = getUpdatesNeeded(); - if (updateable.isUpdateNeeded()) { - performUpdate(updateable); + if (checkUpdate()) { + final UpdateableNvdCve updateable = getUpdatesNeeded(); + if (updateable.isUpdateNeeded()) { + performUpdate(updateable); + } } } catch (MalformedURLException ex) { LOGGER.warn( @@ -87,6 +89,35 @@ 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. + * + * @return true to proceed with the check, or false to skip. + */ + private boolean checkUpdate () throws UpdateException { + boolean proceed = true; + // If the valid setting has not been specified, then we proceed to check... + final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0); + if (0 < validForHours) { + // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec + final long msValid = validForHours * 60L * 60L * 1000L; + 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 { + 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); + } + } + return proceed; + } + /** * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database. * From ccb03f2763e1ee7964842f2f9398576665bd359f Mon Sep 17 00:00:00 2001 From: Anthony Whitford Date: Wed, 21 Oct 2015 23:25:18 -0700 Subject: [PATCH 4/5] Added cveValidForHours parameter that can suppress redundant and repetitive checks for NVD CVE changes. --- .../dependencycheck/maven/BaseDependencyCheckMojo.java | 8 ++++++++ 1 file changed, 8 insertions(+) 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 1f67556cb..b5e05bd13 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 @@ -289,6 +289,11 @@ 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. + */ + @Parameter(property = "cveValidForHours", defaultValue = "", required = false) + private String cveValidForHours; /** * The path to mono for .NET Assembly analysis on non-windows systems. @@ -678,6 +683,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) { Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); } + if (cveValidForHours != null && !cveValidForHours.isEmpty()) { + Settings.setString(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); + } } /** From cef3bb742424ab7c7640fdeab3bbb88bc20efe73 Mon Sep 17 00:00:00 2001 From: Anthony Whitford Date: Wed, 21 Oct 2015 23:27:03 -0700 Subject: [PATCH 5/5] Reworked withinDateRange to avoid type conversion between doubles and longs; expressed in long integer math. --- .../java/org/owasp/dependencycheck/utils/DateUtil.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/DateUtil.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/DateUtil.java index 9fbd33a4c..782b32379 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/DateUtil.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/DateUtil.java @@ -36,11 +36,12 @@ public final class DateUtil { * * @param date the date to be checked. * @param compareTo the date to compare to. - * @param range the range in days to be considered valid. + * @param dayRange the range in days to be considered valid. * @return whether or not the date is within the range. */ - public static boolean withinDateRange(long date, long compareTo, int range) { - final double differenceInDays = (compareTo - date) / 1000.0 / 60.0 / 60.0 / 24.0; - return differenceInDays < range; + public static boolean withinDateRange(long date, long compareTo, int dayRange) { + // ms = dayRange x 24 hours/day x 60 min/hour x 60 sec/min x 1000 ms/sec + final long msRange = dayRange * 24L * 60L * 60L * 1000L; + return (compareTo - date) < msRange; } }