diff --git a/dependency-check-core/pom.xml b/dependency-check-core/pom.xml index be1c2cd6e..fb93e391f 100644 --- a/dependency-check-core/pom.xml +++ b/dependency-check-core/pom.xml @@ -164,6 +164,10 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. + + com.vdurmont + semver4j + joda-time diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.java index e208803a0..87c99d558 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.java @@ -85,6 +85,14 @@ public abstract class AbstractAnalyzer implements Analyzer { @Override public void initialize(Settings settings) { this.settings = settings; + final String key = getAnalyzerEnabledSettingKey(); + try { + this.setEnabled(settings.getBoolean(key, true)); + } catch (InvalidSettingException ex) { + final String msg = String.format("Invalid setting for property '%s'", key); + LOGGER.warn(msg); + LOGGER.debug(msg, ex); + } } /** @@ -95,15 +103,6 @@ public abstract class AbstractAnalyzer implements Analyzer { */ @Override public final void prepare(Engine engine) throws InitializationException { - final String key = getAnalyzerEnabledSettingKey(); - try { - this.setEnabled(settings.getBoolean(key, true)); - } catch (InvalidSettingException ex) { - final String msg = String.format("Invalid setting for property '%s'", key); - LOGGER.warn(msg); - LOGGER.debug(msg, ex); - } - if (isEnabled()) { prepareAnalyzer(engine); } else { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractNpmAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractNpmAnalyzer.java new file mode 100644 index 000000000..e61ea8106 --- /dev/null +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractNpmAnalyzer.java @@ -0,0 +1,289 @@ +/* + * 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) 2017 Steve Springett. All Rights Reserved. + */ +package org.owasp.dependencycheck.analyzer; + +import org.owasp.dependencycheck.Engine; +import org.owasp.dependencycheck.dependency.Confidence; +import org.owasp.dependencycheck.dependency.Dependency; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.IOException; +import java.util.Map; +import javax.annotation.concurrent.ThreadSafe; +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; +import javax.json.JsonString; +import javax.json.JsonValue; +import org.owasp.dependencycheck.dependency.EvidenceType; +import org.owasp.dependencycheck.utils.Checksum; + +/** + * An abstract NPM analyzer that contains common methods for concrete + * implementations. + * + * @author Steve Springett + */ +@ThreadSafe +public abstract class AbstractNpmAnalyzer extends AbstractFileTypeAnalyzer { + + /** + * The logger. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractNpmAnalyzer.class); + + /** + * A descriptor for the type of dependencies processed or added by this + * analyzer. + */ + public static final String NPM_DEPENDENCY_ECOSYSTEM = "npm"; + /** + * The file name to scan. + */ + private static final String PACKAGE_JSON = "package.json"; + + /** + * Determines if the file can be analyzed by the analyzer. + * + * @param pathname the path to the file + * @return true if the file can be analyzed by the given analyzer; otherwise + * false + */ + @Override + public boolean accept(File pathname) { + boolean accept = super.accept(pathname); + if (accept) { + try { + // Do not scan the node_modules directory + if (pathname.getCanonicalPath().contains(File.separator + "node_modules" + File.separator)) { + LOGGER.debug("Skipping analysis of node module: " + pathname.getCanonicalPath()); + accept = false; + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + return accept; + } + + /** + * Construct a dependency object. + * + * @param dependency the parent dependency + * @param name the name of the dependency to create + * @param version the version of the dependency to create + * @param scope the scope of the dependency being created + * @return the generated dependency + */ + protected Dependency createDependency(Dependency dependency, String name, String version, String scope) { + final Dependency nodeModule = new Dependency(new File(dependency.getActualFile() + "?" + name), true); + nodeModule.setEcosystem(NPM_DEPENDENCY_ECOSYSTEM); + //this is virtual - the sha1 is purely for the hyperlink in the final html report + nodeModule.setSha1sum(Checksum.getSHA1Checksum(String.format("%s:%s", name, version))); + nodeModule.setMd5sum(Checksum.getMD5Checksum(String.format("%s:%s", name, version))); + nodeModule.addEvidence(EvidenceType.PRODUCT, "package.json", "name", name, Confidence.HIGHEST); + nodeModule.addEvidence(EvidenceType.VENDOR, "package.json", "name", name, Confidence.HIGH); + nodeModule.addEvidence(EvidenceType.VERSION, "package.json", "version", version, Confidence.HIGHEST); + nodeModule.addProjectReference(dependency.getName() + ": " + scope); + nodeModule.setName(name); + nodeModule.setVersion(version); + nodeModule.addIdentifier("npm", String.format("%s:%s", name, version), null, Confidence.HIGHEST); + return nodeModule; + } + + /** + * Processes a part of package.json (as defined by JsonArray) and update the + * specified dependency with relevant info. + * + * @param engine the dependency-check engine + * @param dependency the Dependency to update + * @param jsonArray the jsonArray to parse + * @param depType the dependency type + */ + protected void processPackage(Engine engine, Dependency dependency, JsonArray jsonArray, String depType) { + final JsonObjectBuilder builder = Json.createObjectBuilder(); + for (JsonString str : jsonArray.getValuesAs(JsonString.class)) { + builder.add(str.toString(), ""); + } + final JsonObject jsonObject = builder.build(); + processPackage(engine, dependency, jsonObject, depType); + } + + /** + * Processes a part of package.json (as defined by JsonObject) and update + * the specified dependency with relevant info. + * + * @param engine the dependency-check engine + * @param dependency the Dependency to update + * @param jsonObject the jsonObject to parse + * @param depType the dependency type + */ + protected void processPackage(Engine engine, Dependency dependency, JsonObject jsonObject, String depType) { + for (int i = 0; i < jsonObject.size(); i++) { + for (Map.Entry entry : jsonObject.entrySet()) { + + final String name = entry.getKey(); + String version = ""; + if (entry.getValue() != null && entry.getValue().getValueType() == JsonValue.ValueType.STRING) { + version = ((JsonString) entry.getValue()).getString(); + } + final Dependency existing = findDependency(engine, name, version); + if (existing == null) { + final Dependency nodeModule = createDependency(dependency, name, version, depType); + engine.addDependency(nodeModule); + } else { + existing.addProjectReference(dependency.getName() + ": " + depType); + } + } + } + } + + /** + * Adds information to an evidence collection from the node json + * configuration. + * + * @param dep the dependency to add the evidence + * @param t the type of evidence to add + * @param json information from node.js + * @return the actual string set into evidence + * @param key the key to obtain the data from the json information + */ + private static String addToEvidence(Dependency dep, EvidenceType t, JsonObject json, String key) { + String evidenceStr = null; + if (json.containsKey(key)) { + final JsonValue value = json.get(key); + if (value instanceof JsonString) { + evidenceStr = ((JsonString) value).getString(); + dep.addEvidence(t, PACKAGE_JSON, key, evidenceStr, Confidence.HIGHEST); + } else if (value instanceof JsonObject) { + final JsonObject jsonObject = (JsonObject) value; + for (final Map.Entry entry : jsonObject.entrySet()) { + final String property = entry.getKey(); + final JsonValue subValue = entry.getValue(); + if (subValue instanceof JsonString) { + evidenceStr = ((JsonString) subValue).getString(); + dep.addEvidence(t, PACKAGE_JSON, + String.format("%s.%s", key, property), + evidenceStr, + Confidence.HIGHEST); + } else { + LOGGER.warn("JSON sub-value not string as expected: {}", subValue); + } + } + } else { + LOGGER.warn("JSON value not string or JSON object as expected: {}", value); + } + } + return evidenceStr; + } + + /** + * Locates the dependency from the list of dependencies that have been + * scanned by the engine. + * + * @param engine the dependency-check engine + * @param name the name of the dependency to find + * @param version the version of the dependency to find + * @return the identified dependency; otherwise null + */ + protected Dependency findDependency(Engine engine, String name, String version) { + for (Dependency d : engine.getDependencies()) { + if (NPM_DEPENDENCY_ECOSYSTEM.equals(d.getEcosystem()) && name.equals(d.getName()) && version != null && d.getVersion() != null) { + String dependencyVersion = d.getVersion(); + if (DependencyBundlingAnalyzer.npmVersionsMatch(version, dependencyVersion)) { + return d; + } +// if (dependencyVersion.startsWith("^") || dependencyVersion.startsWith("~")) { +// dependencyVersion = dependencyVersion.substring(1); +// } +// +// if (version.equals(dependencyVersion)) { +// return d; +// } +// if (version.startsWith("^") || version.startsWith("~") || version.contains("*")) { +// String type; +// String tmp; +// if (version.startsWith("^") || version.startsWith("~")) { +// type = version.substring(0, 1); +// tmp = version.substring(1); +// } else { +// type = "*"; +// tmp = version; +// } +// final String[] v = tmp.split(" ")[0].split("\\."); +// final String[] depVersion = dependencyVersion.split("\\."); +// +// if ("^".equals(type) && v[0].equals(depVersion[0])) { +// return d; +// } else if ("~".equals(type) && v.length >= 2 && depVersion.length >= 2 +// && v[0].equals(depVersion[0]) && v[1].equals(depVersion[1])) { +// return d; +// } else if (v[0].equals("*") +// || (v.length >= 2 && v[0].equals(depVersion[0]) && v[1].equals("*")) +// || (v.length >= 3 && depVersion.length >= 2 && v[0].equals(depVersion[0]) +// && v[1].equals(depVersion[1]) && v[2].equals("*"))) { +// return d; +// } +// } + } + } + return null; + } + + /** + * Collects evidence from the given JSON for the associated dependency. + * + * @param json the JSON that contains the evidence to collect + * @param dependency the dependency to add the evidence too + */ + public void gatherEvidence(final JsonObject json, Dependency dependency) { + if (json.containsKey("name")) { + final Object value = json.get("name"); + if (value instanceof JsonString) { + final String valueString = ((JsonString) value).getString(); + dependency.setName(valueString); + dependency.setPackagePath(valueString); + dependency.addEvidence(EvidenceType.PRODUCT, PACKAGE_JSON, "name", valueString, Confidence.HIGHEST); + dependency.addEvidence(EvidenceType.VENDOR, PACKAGE_JSON, "name", valueString, Confidence.HIGH); + } else { + LOGGER.warn("JSON value not string as expected: {}", value); + } + } + final String desc = addToEvidence(dependency, EvidenceType.PRODUCT, json, "description"); + dependency.setDescription(desc); + addToEvidence(dependency, EvidenceType.VENDOR, json, "author"); + final String version = addToEvidence(dependency, EvidenceType.VERSION, json, "version"); + if (version != null) { + dependency.setVersion(version); + dependency.addIdentifier("npm", String.format("%s:%s", dependency.getName(), version), null, Confidence.HIGHEST); + } + + // Adds the license if defined in package.json + if (json.containsKey("license")) { + final Object value = json.get("license"); + if (value instanceof JsonString) { + dependency.setLicense(json.getString("license")); + } else { + dependency.setLicense(json.getJsonObject("license").getString("type")); + } + } + } +} 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 7d6a03b9e..fce847893 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 @@ -17,6 +17,9 @@ */ package org.owasp.dependencycheck.analyzer; +import com.vdurmont.semver4j.Semver; +import com.vdurmont.semver4j.Semver.SemverType; +import com.vdurmont.semver4j.SemverException; import java.io.File; import java.util.Set; import java.util.regex.Matcher; @@ -135,10 +138,11 @@ public class DependencyBundlingAnalyzer extends AbstractDependencyComparingAnaly mergeDependencies(nextDependency, dependency, dependenciesToRemove); return true; //since we merged into the next dependency - skip forward to the next in mainIterator } - } else if (ecoSystemIs(NspAnalyzer.DEPENDENCY_ECOSYSTEM, dependency, nextDependency) + } else if (ecoSystemIs(AbstractNpmAnalyzer.NPM_DEPENDENCY_ECOSYSTEM, dependency, nextDependency) && namesAreEqual(dependency, nextDependency) - && versionsAreEqual(dependency, nextDependency)) { - if (dependency.isVirtual()) { + && npmVersionsMatch(dependency.getVersion(), nextDependency.getVersion())) { + + if (!dependency.isVirtual()) { DependencyMergingAnalyzer.mergeDependencies(dependency, nextDependency, dependenciesToRemove); } else { DependencyMergingAnalyzer.mergeDependencies(nextDependency, dependency, dependenciesToRemove); @@ -158,7 +162,7 @@ public class DependencyBundlingAnalyzer extends AbstractDependencyComparingAnaly * removed from the main analysis loop, this function adds to this * collection */ - private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set dependenciesToRemove) { + public static void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set dependenciesToRemove) { dependency.addRelatedDependency(relatedDependency); for (Dependency d : relatedDependency.getRelatedDependencies()) { dependency.addRelatedDependency(d); @@ -167,7 +171,9 @@ public class DependencyBundlingAnalyzer extends AbstractDependencyComparingAnaly if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) { dependency.addAllProjectReferences(relatedDependency.getProjectReferences()); } - dependenciesToRemove.add(relatedDependency); + if (dependenciesToRemove != null) { + dependenciesToRemove.add(relatedDependency); + } } /** @@ -487,14 +493,72 @@ public class DependencyBundlingAnalyzer extends AbstractDependencyComparingAnaly /** * Determine if the dependency version is equal in the given dependencies. + * This method attempts to evaluate version range checks. * - * @param dependency a dependency to compare - * @param nextDependency a dependency to compare + * @param current a dependency version to compare + * @param nextDependency a dependency version to compare * @return true if the version is equal in both dependencies; otherwise * false */ - private boolean versionsAreEqual(Dependency dependency, Dependency nextDependency) { - return dependency.getVersion() != null && dependency.getVersion().equals(nextDependency.getVersion()); + public static boolean npmVersionsMatch(String current, String next) { + String left = current; + String right = next; + if (left == null || right == null) { + return false; + } + if (left.equals(right) || "*".equals(left) || "*".equals(right)) { + return true; + } + if (left.contains(" ")) { // we have a version string from package.json + if (right.contains(" ")) { // we can't evaluate this ">=1.5.4 <2.0.0" vs "2 || 3" + return false; + } + if (!right.matches("^\\d.*$")) { + right = stripLeadingNonNumeric(right); + if (right == null) { + return false; + } + } + try { + Semver v = new Semver(right, SemverType.NPM); + return v.satisfies(left); + } catch (SemverException ex) { + LOGGER.trace("ignore", ex); + } + } else { + if (!left.matches("^\\d.*$")) { + left = stripLeadingNonNumeric(left); + if (left == null) { + return false; + } + } + try { + Semver v = new Semver(left, SemverType.NPM); + if (v.satisfies(right)) { + return true; + } + if (!right.contains((" "))) { + left = current; + right = stripLeadingNonNumeric(right); + if (right != null) { + v = new Semver(right, SemverType.NPM); + return v.satisfies(left); + } + } + } catch (SemverException ex) { + LOGGER.trace("ignore", ex); + } + } + return false; + } + + private static String stripLeadingNonNumeric(String str) { + for (int x = 0; x < str.length(); x++) { + if (Character.isDigit(str.codePointAt(x))) { + return str.substring(x); + } + } + return null; } } diff --git a/dependency-check-core/src/main/resources/dependencycheck.properties b/dependency-check-core/src/main/resources/dependencycheck.properties index ed7e23256..259c724d4 100644 --- a/dependency-check-core/src/main/resources/dependencycheck.properties +++ b/dependency-check-core/src/main/resources/dependencycheck.properties @@ -128,4 +128,4 @@ updater.nvdcve.enabled=true updater.versioncheck.enabled=true analyzer.versionfilter.enabled=true -ecosystem.skip.nvdcve=npm \ No newline at end of file +ecosystem.skip.cpeanalyzer=npm \ No newline at end of file diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzerTest.java index 9b0cc2b41..578b39e17 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzerTest.java @@ -43,6 +43,9 @@ public class NodePackageAnalyzerTest extends BaseTest { * The analyzer to test. */ private NodePackageAnalyzer analyzer; + /** + * A reference to the engine. + */ private Engine engine; /** @@ -87,7 +90,8 @@ public class NodePackageAnalyzerTest extends BaseTest { */ @Test public void testSupportsFiles() { - assertThat(analyzer.accept(new File("package.json")), is(true)); + assertThat(analyzer.accept(new File("package-lock.json")), is(true)); + assertThat(analyzer.accept(new File("shrinkwrap.json")), is(true)); } /** @@ -96,10 +100,12 @@ public class NodePackageAnalyzerTest extends BaseTest { * @throws AnalysisException is thrown when an exception occurs. */ @Test - public void testAnalyzePackageJson() throws AnalysisException { - final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, - "nodejs/node_modules/dns-sync/package.json")); - analyzer.analyze(result, null); + public void testAnalyzeShrinkwrapJson() throws AnalysisException { + final Dependency toScan = new Dependency(BaseTest.getResourceAsFile(this, + "nodejs/shrinkwrap.json")); + analyzer.analyze(toScan, engine); + assertEquals("Expected 1 dependency", engine.getDependencies().length, 1); + final Dependency result = engine.getDependencies()[0]; final String vendorString = result.getEvidence(EvidenceType.VENDOR).toString(); assertThat(vendorString, containsString("Sanjeev Koranga")); assertThat(vendorString, containsString("dns-sync")); @@ -109,4 +115,24 @@ public class NodePackageAnalyzerTest extends BaseTest { assertEquals("dns-sync", result.getName()); assertEquals("0.1.0", result.getVersion()); } + + /** + * Test of inspect method, of class PythonDistributionAnalyzer. + * + * @throws AnalysisException is thrown when an exception occurs. + */ + @Test + public void testAnalyzePackageJsonWithShrinkwrap() throws AnalysisException { + final Dependency packageLock = new Dependency(BaseTest.getResourceAsFile(this, + "nodejs/package-lock.json")); + final Dependency shrinkwrap = new Dependency(BaseTest.getResourceAsFile(this, + "nodejs/shrinkwrap.json")); + engine.addDependency(packageLock); + engine.addDependency(shrinkwrap); + assertEquals(2, engine.getDependencies().length); + analyzer.analyze(packageLock, engine); + assertEquals(1, engine.getDependencies().length); //package-lock was removed without analysis + analyzer.analyze(shrinkwrap, engine); + assertEquals(1, engine.getDependencies().length); //shrinkwrap was removed with analysis adding 1 dependency + } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/NspAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/NspAnalyzerTest.java index 508b58d0d..edb56b113 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/NspAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/NspAnalyzerTest.java @@ -1,7 +1,5 @@ package org.owasp.dependencycheck.analyzer; -import org.junit.After; -import org.junit.Before; import org.junit.Test; import org.owasp.dependencycheck.BaseTest; import org.owasp.dependencycheck.analyzer.exception.AnalysisException; @@ -36,12 +34,20 @@ public class NspAnalyzerTest extends BaseTest { analyzer.setFilesMatched(true); analyzer.initialize(getSettings()); analyzer.prepare(engine); - final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "nsp/package.json")); - analyzer.analyze(result, engine); - - assertTrue(result.getEvidence(EvidenceType.VENDOR).toString().contains("owasp-nodejs-goat")); - assertTrue(result.getEvidence(EvidenceType.PRODUCT).toString().contains("A tool to learn OWASP Top 10 for node.js developers")); - assertTrue(result.getEvidence(EvidenceType.VERSION).toString().contains("1.3.0")); + final Dependency toScan = new Dependency(BaseTest.getResourceAsFile(this, "nsp/package.json")); + analyzer.analyze(toScan, engine); + boolean found = false; + assertEquals("4 dependencies should be identified", 4, engine.getDependencies().length); + for (Dependency result : engine.getDependencies()) { + if ("package.json?uglify-js".equals(result.getFileName())) { + found = true; + assertTrue(result.getEvidence(EvidenceType.VENDOR).toString().contains("uglify-js")); + assertTrue(result.getEvidence(EvidenceType.PRODUCT).toString().contains("uglify-js")); + assertTrue(result.getEvidence(EvidenceType.VERSION).toString().contains("2.4.24")); + assertTrue(result.isVirtual()); + } + } + assertTrue("Uglify was not found", found); } } @@ -61,38 +67,6 @@ public class NspAnalyzerTest extends BaseTest { } } - @Test - public void testAnalyzePackageJsonWithBundledDeps() throws AnalysisException, InitializationException { - try (Engine engine = new Engine(getSettings())) { - NspAnalyzer analyzer = new NspAnalyzer(); - analyzer.setFilesMatched(true); - analyzer.initialize(getSettings()); - analyzer.prepare(engine); - final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "nsp/bundled.deps.package.json")); - analyzer.analyze(result, engine); - - assertTrue(result.getEvidence(EvidenceType.VENDOR).toString().contains("Philipp Dunkel ")); - assertTrue(result.getEvidence(EvidenceType.PRODUCT).toString().contains("Native Access to Mac OS-X FSEvents")); - assertTrue(result.getEvidence(EvidenceType.VERSION).toString().contains("1.1.1")); - } - } - - @Test - public void testAnalyzePackageJsonWithLicenseObject() throws AnalysisException, InitializationException { - try (Engine engine = new Engine(getSettings())) { - NspAnalyzer analyzer = new NspAnalyzer(); - analyzer.setFilesMatched(true); - analyzer.initialize(getSettings()); - analyzer.prepare(engine); - final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "nsp/license.obj.package.json")); - analyzer.analyze(result, engine); - - assertTrue(result.getEvidence(EvidenceType.VENDOR).toString().contains("Twitter, Inc.")); - assertTrue(result.getEvidence(EvidenceType.PRODUCT).toString().contains("The most popular front-end framework for developing responsive, mobile first projects on the web")); - assertTrue(result.getEvidence(EvidenceType.VERSION).toString().contains("3.2.0")); - } - } - @Test public void testAnalyzePackageJsonInNodeModulesDirectory() throws AnalysisException, InitializationException { try (Engine engine = new Engine(getSettings())) { @@ -100,12 +74,10 @@ public class NspAnalyzerTest extends BaseTest { analyzer.setFilesMatched(true); analyzer.initialize(getSettings()); analyzer.prepare(engine); - final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "nodejs/node_modules/dns-sync/package.json")); - analyzer.analyze(result, engine); - // package.json adds 5 bits of evidence - assertTrue(result.size() == 5); - // but no vulnerabilities were cited - assertTrue(result.getVulnerabilities().isEmpty()); + final Dependency toScan = new Dependency(BaseTest.getResourceAsFile(this, "nodejs/node_modules/dns-sync/package.json")); + engine.addDependency(toScan); + analyzer.analyze(toScan, engine); + assertEquals("No dependencies should exist", 0, engine.getDependencies().length); } } diff --git a/dependency-check-core/src/test/resources/dependencycheck.properties b/dependency-check-core/src/test/resources/dependencycheck.properties index 133ee11c0..ce2875943 100644 --- a/dependency-check-core/src/test/resources/dependencycheck.properties +++ b/dependency-check-core/src/test/resources/dependencycheck.properties @@ -124,4 +124,4 @@ analyzer.vulnerabilitysuppression.enabled=true updater.nvdcve.enabled=true updater.versioncheck.enabled=true -ecosystem.skip.nvdcve=npm \ No newline at end of file +ecosystem.skip.cpeanalyzer=npm \ No newline at end of file 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 730c2de5d..a33ba86cd 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 @@ -443,9 +443,9 @@ public final class Settings { */ public static final String UPDATE_VERSION_CHECK_ENABLED = "updater.versioncheck.enabled"; /** - * The key to determine which ecosystems should skip the NVD CVE analysis. + * The key to determine which ecosystems should skip the CPE analysis. */ - public static final String ECOSYSTEM_SKIP_NVDCVE = "ecosystem.skip.nvdcve"; + public static final String ECOSYSTEM_SKIP_CPEANALYZER = "ecosystem.skip.cpeanalyzer"; /** * private constructor because this is a "utility" class containing diff --git a/pom.xml b/pom.xml index 86da3e0be..b2410c6ac 100644 --- a/pom.xml +++ b/pom.xml @@ -625,6 +625,11 @@ Copyright (c) 2012 - Jeremy Long + + com.vdurmont + semver4j + 2.1.0 + joda-time