Skip to content

Commit

Permalink
fixes #3893
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremylong committed Dec 21, 2021
1 parent 5bdd304 commit 8954fe4
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 29 deletions.
4 changes: 2 additions & 2 deletions core/pom.xml
Expand Up @@ -213,8 +213,8 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
Expand Down
Expand Up @@ -21,6 +21,8 @@
import com.github.packageurl.PackageURL;
import com.github.packageurl.PackageURL.StandardTypes;
import com.github.packageurl.PackageURLBuilder;
import com.vdurmont.semver4j.Semver;
import com.vdurmont.semver4j.Semver.SemverType;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.data.nodeaudit.Advisory;
import org.owasp.dependencycheck.data.nodeaudit.NodeAuditSearch;
Expand All @@ -38,6 +40,7 @@
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.annotation.concurrent.ThreadSafe;
Expand All @@ -48,6 +51,7 @@
import javax.json.JsonString;
import javax.json.JsonValue;
import javax.json.JsonValue.ValueType;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.lang3.StringUtils;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.analyzer.exception.UnexpectedAnalysisException;
Expand Down Expand Up @@ -440,7 +444,7 @@ protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationExcep
* @throws CpeValidationException thrown when a CPE cannot be created
*/
protected void processResults(final List<Advisory> advisories, Engine engine,
Dependency dependency, Map<String, String> dependencyMap)
Dependency dependency, MultiValuedMap<String, String> dependencyMap)
throws CpeValidationException {
for (Advisory advisory : advisories) {
//Create a new vulnerability out of the advisory returned by nsp.
Expand All @@ -464,9 +468,8 @@ protected void processResults(final List<Advisory> advisories, Engine engine,

String version = advisory.getVersion();
if (version == null && dependencyMap.containsKey(advisory.getModuleName())) {
version = dependencyMap.get(advisory.getModuleName());
version = determineVersionFromMap(advisory.getVulnerableVersions(), dependencyMap.get(advisory.getModuleName()));
}

final Dependency existing = findDependency(engine, advisory.getModuleName(), version);
if (existing == null) {
final Dependency nodeModule = createDependency(dependency, advisory.getModuleName(), version, "transitive");
Expand Down Expand Up @@ -509,4 +512,17 @@ protected void replaceOrAddVulnerability(Dependency dependency, Vulnerability vu
protected NodeAuditSearch getSearcher() {
return searcher;
}

public String determineVersionFromMap(String versionRange, Collection<String> availableVersions) {
if (availableVersions.size()==1) {
return availableVersions.iterator().next();
}
for (String v : availableVersions){
Semver version = new Semver(v, SemverType.NPM);
if (version.satisfies(versionRange)) {
return v;
}
}
return availableVersions.iterator().next();
}
}
Expand Up @@ -30,15 +30,15 @@
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.concurrent.ThreadSafe;
import javax.json.Json;
import javax.json.JsonException;
import javax.json.JsonObject;
import javax.json.JsonReader;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;
import org.owasp.dependencycheck.analyzer.exception.SearchException;
import org.owasp.dependencycheck.analyzer.exception.UnexpectedAnalysisException;
import org.owasp.dependencycheck.data.nvd.ecosystem.Ecosystem;
Expand Down Expand Up @@ -140,7 +140,8 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An
}
final File packageJson = new File(packageLock.getParentFile(), "package.json");
final List<Advisory> advisories;
final Map<String, String> dependencyMap = new HashMap<>();
final MultiValuedMap<String, String> dependencyMap = new HashSetValuedHashMap<>();
//final Map<String, String> dependencyMap = new HashMap<>();
if (packageJson.isFile()) {
advisories = analyzePackage(packageLock, packageJson, dependency, dependencyMap);
} else {
Expand Down Expand Up @@ -170,7 +171,7 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An
* submitting the npm audit API payload
*/
private List<Advisory> analyzePackage(final File lockFile, final File packageFile,
Dependency dependency, Map<String, String> dependencyMap)
Dependency dependency, MultiValuedMap<String, String> dependencyMap)
throws AnalysisException {
try {
final JsonReader packageReader = Json.createReader(FileUtils.openInputStream(packageFile));
Expand Down Expand Up @@ -227,7 +228,7 @@ private List<Advisory> analyzePackage(final File lockFile, final File packageFil
* @throws AnalysisException thrown when there is an error creating or
* submitting the npm audit API payload
*/
private List<Advisory> legacyAnalysis(final File file, Dependency dependency, Map<String, String> dependencyMap)
private List<Advisory> legacyAnalysis(final File file, Dependency dependency, MultiValuedMap<String, String> dependencyMap)
throws AnalysisException {

try (JsonReader jsonReader = Json.createReader(FileUtils.openInputStream(file))) {
Expand Down
Expand Up @@ -43,9 +43,9 @@
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;

@ThreadSafe
public class PnpmAuditAnalyzer extends AbstractNpmAnalyzer {
Expand Down Expand Up @@ -89,7 +89,7 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An
return;
}
final List<Advisory> advisories;
final Map<String, String> dependencyMap = new HashMap<>();
final MultiValuedMap<String, String> dependencyMap = new HashSetValuedHashMap<>();
advisories = analyzePackage(packageLock, dependency);
try {
processResults(advisories, engine, dependency, dependencyMap);
Expand Down
Expand Up @@ -23,15 +23,15 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.concurrent.ThreadSafe;
import javax.json.Json;
import javax.json.JsonException;
import javax.json.JsonObject;
import javax.json.JsonReader;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
Expand Down Expand Up @@ -102,7 +102,7 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An
}
final File packageJson = new File(packageLock.getParentFile(), "package.json");
final List<Advisory> advisories;
final Map<String, String> dependencyMap = new HashMap<>();
final MultiValuedMap<String, String> dependencyMap = new HashSetValuedHashMap<>();
advisories = analyzePackage(packageLock, packageJson, dependency, dependencyMap);
try {
processResults(advisories, engine, dependency, dependencyMap);
Expand Down Expand Up @@ -276,7 +276,7 @@ private JsonObject fetchYarnAuditJson(Dependency dependency, boolean skipDevDepe
* submitting the npm audit API payload
*/
private List<Advisory> analyzePackage(final File lockFile, final File packageFile,
Dependency dependency, Map<String, String> dependencyMap)
Dependency dependency, MultiValuedMap<String, String> dependencyMap)
throws AnalysisException {
try {
final Boolean skipDevDependencies = getSettings().getBoolean(Settings.KEYS.ANALYZER_NODE_AUDIT_SKIPDEV, false);
Expand Down
Expand Up @@ -17,6 +17,7 @@
*/
package org.owasp.dependencycheck.data.nodeaudit;

import com.esotericsoftware.minlog.Log;
import org.owasp.dependencycheck.analyzer.NodePackageAnalyzer;

import java.util.Map;
Expand All @@ -28,6 +29,7 @@
import javax.json.JsonString;
import javax.json.JsonValue;
import javax.annotation.concurrent.ThreadSafe;
import org.apache.commons.collections4.MultiValuedMap;

/**
* Class used to create the payload to submit to the NPM Audit API service.
Expand Down Expand Up @@ -56,7 +58,7 @@ private NpmPayloadBuilder() {
* @return the npm audit API payload
*/
public static JsonObject build(JsonObject lockJson, JsonObject packageJson,
Map<String, String> dependencyMap, boolean skipDevDependencies) {
MultiValuedMap<String, String> dependencyMap, boolean skipDevDependencies) {
final JsonObjectBuilder payloadBuilder = Json.createObjectBuilder();
addProjectInfo(packageJson, payloadBuilder);

Expand Down Expand Up @@ -132,7 +134,7 @@ public static JsonObject build(JsonObject lockJson, JsonObject packageJson,
* populated while building the payload
* @return the JSON payload for NPN Audit
*/
public static JsonObject build(JsonObject packageJson, Map<String, String> dependencyMap) {
public static JsonObject build(JsonObject packageJson, MultiValuedMap<String, String> dependencyMap) {
final JsonObjectBuilder payloadBuilder = Json.createObjectBuilder();
addProjectInfo(packageJson, payloadBuilder);

Expand Down Expand Up @@ -215,7 +217,7 @@ private static void addConstantElements(final JsonObjectBuilder payloadBuilder)
* @param dependencyMap the collection of child dependencies
* @return the dependencies structure needed for the npm audit API payload
*/
private static JsonObject buildDependencies(JsonObject dep, Map<String, String> dependencyMap) {
private static JsonObject buildDependencies(JsonObject dep, MultiValuedMap<String, String> dependencyMap) {
final JsonObjectBuilder depBuilder = Json.createObjectBuilder();
depBuilder.add("version", dep.getString("version"));

Expand Down
@@ -0,0 +1,98 @@
/*
* 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) 2021 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.analyzer;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.json.JsonArray;
import javax.json.JsonObject;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.data.nodeaudit.Advisory;
import org.owasp.dependencycheck.data.nodeaudit.NodeAuditSearch;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Vulnerability;

/**
*
* @author jeremy long
*/
public class AbstractNpmAnalyzerIT {


/**
* Test of determineVersionFromMap method, of class AbstractNpmAnalyzer.
*/
@Test
public void testDetermineVersionFromMap() {
String versionRange = ">2.1.1 <5.0.1";
Collection<String> availableVersions = new ArrayList<>();
availableVersions.add("2.0.2");
availableVersions.add("5.0.2");
availableVersions.add("10.1.0");
availableVersions.add("8.1.0");
availableVersions.add("5.1.0");
availableVersions.add("7.1.0");
availableVersions.add("3.0.0");
availableVersions.add("2.0.0");
AbstractNpmAnalyzer instance = new AbstractNpmAnalyzerImpl();
String expResult = "3.0.0";
String result = instance.determineVersionFromMap(versionRange, availableVersions);
assertEquals(expResult, result);
}

public class AbstractNpmAnalyzerImpl extends AbstractNpmAnalyzer {

@Override
protected FileFilter getFileFilter() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
protected String getAnalyzerEnabledSettingKey() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
public String getName() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
public AnalysisPhase getAnalysisPhase() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}

}
Expand Up @@ -28,6 +28,8 @@
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonReader;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;

import org.owasp.dependencycheck.BaseTest;

Expand All @@ -53,7 +55,7 @@ public void testSanitizer() {
);

JsonObject packageJson = builder.build();
Map<String, String> dependencyMap = new HashMap<>();
final MultiValuedMap<String, String> dependencyMap = new HashSetValuedHashMap<>();
JsonObject sanitized = NpmPayloadBuilder.build(packageJson, dependencyMap);

Assert.assertTrue(sanitized.containsKey("name"));
Expand Down Expand Up @@ -98,7 +100,7 @@ public void testSkippedDependencies() {
);

JsonObject packageJson = builder.build();
Map<String, String> dependencyMap = new HashMap<>();
final MultiValuedMap<String, String> dependencyMap = new HashSetValuedHashMap<>();
JsonObject sanitized = NpmPayloadBuilder.build(packageJson, dependencyMap);

Assert.assertTrue(sanitized.containsKey("name"));
Expand All @@ -121,7 +123,7 @@ public void testSkippedDependencies() {
@Test
public void testSanitizePackage() {
InputStream in = BaseTest.getResourceAsStream(this, "nodeaudit/package-lock.json");
Map<String, String> dependencyMap = new HashMap<>();
final MultiValuedMap<String, String> dependencyMap = new HashSetValuedHashMap<>();
try (JsonReader jsonReader = Json.createReader(in)) {
JsonObject packageJson = jsonReader.readObject();
JsonObject sanitized = NpmPayloadBuilder.build(packageJson, dependencyMap);
Expand All @@ -144,7 +146,7 @@ public void testSanitizePackage() {
public void testPayloadWithLockAndPackage() {
InputStream lock = BaseTest.getResourceAsStream(this, "nodeaudit/package-lock.json");
InputStream json = BaseTest.getResourceAsStream(this, "nodeaudit/package.json");
Map<String, String> dependencyMap = new HashMap<>();
final MultiValuedMap<String, String> dependencyMap = new HashSetValuedHashMap<>();
try (JsonReader jsonReader = Json.createReader(json); JsonReader lockReader = Json.createReader(lock)) {
JsonObject packageJson = jsonReader.readObject();
JsonObject lockJson = lockReader.readObject();
Expand All @@ -162,8 +164,6 @@ public void testPayloadWithLockAndPackage() {
Assert.assertFalse(sanitized.containsKey("lockfileVersion"));
Assert.assertFalse(sanitized.containsKey("random"));



Assert.assertTrue(sanitized.containsKey("name"));
Assert.assertTrue(sanitized.containsKey("version"));
Assert.assertTrue(sanitized.containsKey("dependencies"));
Expand Down
6 changes: 3 additions & 3 deletions pom.xml
Expand Up @@ -1167,9 +1167,9 @@ Copyright (c) 2012 - Jeremy Long
<version>${maven-reporting-api.version}</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons-collections.version}</version>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
Expand Down

0 comments on commit 8954fe4

Please sign in to comment.