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 1077dca5b..9c15f48d2 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 @@ -274,12 +274,6 @@ public class Engine implements FileFilter, AutoCloseable { for (AnalysisPhase phase : mode.getPhases()) { analyzers.put(phase, new ArrayList()); } - boolean loadExperimental = false; - try { - loadExperimental = settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false); - } catch (InvalidSettingException ex) { - LOGGER.trace("Experimenal setting not configured; defaulting to false"); - } final AnalyzerService service = new AnalyzerService(serviceClassLoader, settings); final List iterator = service.getAnalyzers(mode.getPhases()); for (Analyzer a : iterator) { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java index a5f66ebae..80451650b 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java @@ -868,7 +868,8 @@ public class DependencyCheckScanAgent { // /** - * Executes the Dependency-Check on the dependent libraries. + * Executes the Dependency-Check on the dependent libraries. Note, the engine + * object returned from this method must be closed by calling `close()` * * @return the Engine used to scan the dependencies. * @throws ExceptionCollection a collection of one or more exceptions that @@ -887,6 +888,8 @@ public class DependencyCheckScanAgent { engine.doUpdates(); } catch (UpdateException ex) { throw new ExceptionCollection("Unable to perform update", ex); + } finally { + engine.close(); } } else { engine.setDependencies(this.dependencies); 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 836cffd07..9f525ba08 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 @@ -44,7 +44,7 @@ import org.xml.sax.SAXException; /** * Abstract base suppression analyzer that contains methods for parsing the - * suppression xml file. + * suppression XML file. * * @author Jeremy Long */ @@ -88,7 +88,7 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { public synchronized void prepareAnalyzer(Engine engine) throws InitializationException { if (rules == null) { try { - rules = loadSuppressionData(); + loadSuppressionData(); } catch (SuppressionParseException ex) { throw new InitializationException("Error initializing the suppression analyzer: " + ex.getLocalizedMessage(), ex); } @@ -108,10 +108,9 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { /** * Loads all the suppression rules files configured in the {@link Settings}. * - * @return the array of rules that were loaded * @throws SuppressionParseException thrown if the XML cannot be parsed. */ - private SuppressionRule[] loadSuppressionData() throws SuppressionParseException { + private void loadSuppressionData() throws SuppressionParseException { List ruleList; final SuppressionParser parser = new SuppressionParser(); try { @@ -121,14 +120,29 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { throw new SuppressionParseException("Unable to parse the base suppression data file", ex); } final String[] suppressionFilePaths = getSettings().getArray(Settings.KEYS.SUPPRESSION_FILE); + List failedLoadingFiles = new ArrayList<>(); if (suppressionFilePaths != null && suppressionFilePaths.length > 0) { + // Load all the suppression file paths for (final String suppressionFilePath : suppressionFilePaths) { - ruleList.addAll(loadSuppressionFile(parser, suppressionFilePath)); + try { + ruleList.addAll(loadSuppressionFile(parser, suppressionFilePath)); + } catch (SuppressionParseException ex) { + final String msg = String.format("Failed to load %s, caused by %s. ", suppressionFilePath, ex.getMessage()); + failedLoadingFiles.add(msg); + } } } + rules = ruleList.toArray(new SuppressionRule[ruleList.size()]); LOGGER.debug("{} suppression rules were loaded.", ruleList.size()); - return ruleList.toArray(new SuppressionRule[ruleList.size()]); + if (!failedLoadingFiles.isEmpty()) { + LOGGER.debug("{} suppression files failed to load.", failedLoadingFiles.size()); + final StringBuilder sb = new StringBuilder(); + for (String item : failedLoadingFiles) { + sb.append(item); + } + throw new SuppressionParseException(sb.toString()); + } } /** 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 90bc44c04..53775aab0 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 @@ -535,13 +535,13 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { foundSomething = true; dependency.addEvidence(EvidenceType.VENDOR, "pom", "groupid", groupid, Confidence.HIGHEST); dependency.addEvidence(EvidenceType.PRODUCT, "pom", "groupid", groupid, Confidence.LOW); - addMatchingVendorValues(classes, groupid, dependency); - addMatchingProductValues(classes, groupid, dependency); + addMatchingValues(classes, groupid, dependency,EvidenceType.VENDOR); + addMatchingValues(classes, groupid, dependency,EvidenceType.PRODUCT); if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) { dependency.addEvidence(EvidenceType.VENDOR, "pom", "parent-groupid", parentGroupId, Confidence.MEDIUM); dependency.addEvidence(EvidenceType.PRODUCT, "pom", "parent-groupid", parentGroupId, Confidence.LOW); - addMatchingVendorValues(classes, parentGroupId, dependency); - addMatchingProductValues(classes, parentGroupId, dependency); + addMatchingValues(classes, parentGroupId, dependency,EvidenceType.VENDOR); + addMatchingValues(classes, parentGroupId, dependency,EvidenceType.PRODUCT); } } else { addAsIdentifier = false; @@ -551,13 +551,13 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { foundSomething = true; dependency.addEvidence(EvidenceType.PRODUCT, "pom", "artifactid", artifactid, Confidence.HIGHEST); dependency.addEvidence(EvidenceType.VENDOR, "pom", "artifactid", artifactid, Confidence.LOW); - addMatchingVendorValues(classes, artifactid, dependency); - addMatchingProductValues(classes, artifactid, dependency); + addMatchingValues(classes, artifactid, dependency,EvidenceType.VENDOR); + addMatchingValues(classes, artifactid, dependency,EvidenceType.PRODUCT); if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) { dependency.addEvidence(EvidenceType.PRODUCT, "pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM); dependency.addEvidence(EvidenceType.VENDOR, "pom", "parent-artifactid", parentArtifactId, Confidence.LOW); - addMatchingProductValues(classes, parentArtifactId, dependency); - addMatchingProductValues(classes, parentArtifactId, dependency); + addMatchingValues(classes, parentArtifactId, dependency,EvidenceType.VENDOR); + addMatchingValues(classes, parentArtifactId, dependency,EvidenceType.PRODUCT); } } else { addAsIdentifier = false; @@ -582,8 +582,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { if (org != null && !org.isEmpty()) { dependency.addEvidence(EvidenceType.VENDOR, "pom", "organization name", org, Confidence.HIGH); dependency.addEvidence(EvidenceType.PRODUCT, "pom", "organization name", org, Confidence.LOW); - addMatchingVendorValues(classes, org, dependency); - addMatchingProductValues(classes, org, dependency); + addMatchingValues(classes, org, dependency,EvidenceType.VENDOR); + addMatchingValues(classes, org, dependency,EvidenceType.PRODUCT); } // org name String orgUrl = pom.getOrganizationUrl(); @@ -603,8 +603,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { foundSomething = true; dependency.addEvidence(EvidenceType.PRODUCT, "pom", "name", pomName, Confidence.HIGH); dependency.addEvidence(EvidenceType.VENDOR, "pom", "name", pomName, Confidence.HIGH); - addMatchingVendorValues(classes, pomName, dependency); - addMatchingProductValues(classes, pomName, dependency); + addMatchingValues(classes, pomName, dependency,EvidenceType.VENDOR); + addMatchingValues(classes, pomName, dependency,EvidenceType.PRODUCT); } //Description @@ -612,8 +612,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) { foundSomething = true; final String trimmedDescription = addDescription(dependency, description, "pom", "description"); - addMatchingVendorValues(classes, trimmedDescription, dependency); - addMatchingProductValues(classes, trimmedDescription, dependency); + addMatchingValues(classes, trimmedDescription, dependency,EvidenceType.VENDOR); + addMatchingValues(classes, trimmedDescription, dependency,EvidenceType.PRODUCT); } String projectURL = pom.getProjectURL(); @@ -723,7 +723,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { foundSomething = true; dependency.addEvidence(EvidenceType.PRODUCT, source, key, value, Confidence.HIGH); - addMatchingProductValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency,EvidenceType.PRODUCT); } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { hasImplementationVersion = true; foundSomething = true; @@ -733,19 +733,19 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { foundSomething = true; dependency.addEvidence(EvidenceType.VENDOR, source, key, value, Confidence.HIGH); - addMatchingVendorValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency,EvidenceType.VENDOR); } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) { foundSomething = true; dependency.addEvidence(EvidenceType.VENDOR, source, key, value, Confidence.MEDIUM); - addMatchingVendorValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency,EvidenceType.VENDOR); } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { foundSomething = true; addDescription(dependency, value, "manifest", key); - addMatchingProductValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency,EvidenceType.PRODUCT); } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { foundSomething = true; dependency.addEvidence(EvidenceType.PRODUCT, source, key, value, Confidence.MEDIUM); - addMatchingProductValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency,EvidenceType.PRODUCT); // //the following caused false positives. // } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) { } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) { @@ -785,19 +785,19 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { dependency.addEvidence(EvidenceType.VERSION, source, key, value, Confidence.MEDIUM); } else if (key.contains("title")) { dependency.addEvidence(EvidenceType.PRODUCT, source, key, value, Confidence.MEDIUM); - addMatchingProductValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency,EvidenceType.PRODUCT); } else if (key.contains("vendor")) { if (key.contains("specification")) { dependency.addEvidence(EvidenceType.VENDOR, source, key, value, Confidence.LOW); } else { dependency.addEvidence(EvidenceType.VENDOR, source, key, value, Confidence.MEDIUM); - addMatchingVendorValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency,EvidenceType.VENDOR); } } else if (key.contains("name")) { dependency.addEvidence(EvidenceType.PRODUCT, source, key, value, Confidence.MEDIUM); dependency.addEvidence(EvidenceType.VENDOR, source, key, value, Confidence.MEDIUM); - addMatchingVendorValues(classInformation, value, dependency); - addMatchingProductValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency,EvidenceType.VENDOR); + addMatchingValues(classInformation, value, dependency,EvidenceType.PRODUCT); } else if (key.contains("license")) { addLicense(dependency, value); } else if (key.contains("description")) { @@ -805,8 +805,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { } else { dependency.addEvidence(EvidenceType.PRODUCT, source, key, value, Confidence.LOW); dependency.addEvidence(EvidenceType.VENDOR, source, key, value, Confidence.LOW); - addMatchingVendorValues(classInformation, value, dependency); - addMatchingProductValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency, EvidenceType.VERSION); + addMatchingValues(classInformation, value, dependency, EvidenceType.PRODUCT); if (value.matches(".*\\d.*")) { final StringTokenizer tokenizer = new StringTokenizer(value, " "); while (tokenizer.hasMoreElements()) { @@ -830,18 +830,18 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { foundSomething = true; dependency.addEvidence(EvidenceType.PRODUCT, source, key, value, Confidence.MEDIUM); - addMatchingProductValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency, EvidenceType.PRODUCT); } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { foundSomething = true; dependency.addEvidence(EvidenceType.VERSION, source, key, value, Confidence.MEDIUM); } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { foundSomething = true; dependency.addEvidence(EvidenceType.VENDOR, source, key, value, Confidence.MEDIUM); - addMatchingVendorValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency, EvidenceType.VENDOR); } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) { foundSomething = true; dependency.addEvidence(EvidenceType.PRODUCT, source, key, value, Confidence.MEDIUM); - addMatchingProductValues(classInformation, value, dependency); + addMatchingValues(classInformation, value, dependency, EvidenceType.PRODUCT); } } } @@ -1081,7 +1081,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { * @param value the value to check to see if it contains a package name * @param dep the dependency to add new entries too */ - private static void addMatchingVendorValues(List classes, String value, Dependency dep) { + private static void addMatchingValues(List classes, String value, Dependency dep, EvidenceType type) { if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { return; } @@ -1091,33 +1091,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { final Pattern p = Pattern.compile("\b" + key + "\b"); if (p.matcher(text).find()) { //if (text.contains(key)) { //note, package structure elements are already lowercase. - dep.addEvidence(EvidenceType.VENDOR, "jar", "package name", key, Confidence.HIGHEST); - } - } - } - } - - /** - * 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 - * @param dep the dependency to add new entries too - */ - private static void addMatchingProductValues(List classes, String value, Dependency dep) { - if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { - return; - } - final String text = value.toLowerCase(); - for (ClassNameInformation cni : classes) { - for (String key : cni.getPackageStructure()) { - final Pattern p = Pattern.compile("\b" + key + "\b"); - if (p.matcher(text).find()) { - //if (text.contains(key)) { //note, package structure elements are already lowercase. - dep.addEvidence(EvidenceType.PRODUCT, "jar", "package name", key, Confidence.HIGHEST); + dep.addEvidence(type, "jar", "package name", key, Confidence.HIGHEST); } } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/H2DBLock.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/H2DBLock.java index 001d9141c..ff67ce54d 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/H2DBLock.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/H2DBLock.java @@ -209,7 +209,7 @@ public class H2DBLock { private double getFileAge(File file) { final Date d = new Date(); final long modified = file.lastModified(); - final double time = (d.getTime() - modified) / 1000 / 60; + final double time = (d.getTime() - modified) / 1000.0 / 60.0; LOGGER.debug("Lock file age is {} minutes", time); return time; }