mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-03-25 02:21:28 +01:00
updated code to better handle TLS errors
This commit is contained in:
@@ -50,10 +50,11 @@ import javax.json.JsonReader;
|
|||||||
import javax.json.JsonString;
|
import javax.json.JsonString;
|
||||||
import javax.json.JsonValue;
|
import javax.json.JsonValue;
|
||||||
import org.owasp.dependencycheck.exception.InitializationException;
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
import org.owasp.dependencycheck.utils.URLConnectionFailureException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to analyze Node Package Manager (npm) package.json files via
|
* Used to analyze Node Package Manager (npm) package.json files via Node
|
||||||
* Node Security Platform (nsp).
|
* Security Platform (nsp).
|
||||||
*
|
*
|
||||||
* @author Steve Springett
|
* @author Steve Springett
|
||||||
*/
|
*/
|
||||||
@@ -161,7 +162,7 @@ public class NspAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
// Submits the package payload to the nsp check service
|
// Submits the package payload to the nsp check service
|
||||||
final List<Advisory> advisories = searcher.submitPackage(nspPayload);
|
final List<Advisory> advisories = searcher.submitPackage(nspPayload);
|
||||||
|
|
||||||
for (Advisory advisory: advisories) {
|
for (Advisory advisory : advisories) {
|
||||||
/*
|
/*
|
||||||
* Create a new vulnerability out of the advisory returned by nsp.
|
* Create a new vulnerability out of the advisory returned by nsp.
|
||||||
*/
|
*/
|
||||||
@@ -247,23 +248,27 @@ public class NspAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
addToEvidence(packageJson, vendorEvidence, "author");
|
addToEvidence(packageJson, vendorEvidence, "author");
|
||||||
addToEvidence(packageJson, dependency.getVersionEvidence(), "version");
|
addToEvidence(packageJson, dependency.getVersionEvidence(), "version");
|
||||||
dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName()));
|
dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName()));
|
||||||
|
} catch (URLConnectionFailureException e) {
|
||||||
|
this.setEnabled(false);
|
||||||
|
throw new AnalysisException(e.getMessage(), e);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.debug("Error reading dependency or connecting to Node Security Platform /check API", e);
|
LOGGER.debug("Error reading dependency or connecting to Node Security Platform - check API", e);
|
||||||
|
this.setEnabled(false);
|
||||||
|
throw new AnalysisException(e.getMessage(), e);
|
||||||
} catch (JsonException e) {
|
} catch (JsonException e) {
|
||||||
LOGGER.warn("Failed to parse package.json file.", e);
|
throw new AnalysisException(String.format("Failed to parse %s file.", file.getPath()), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes a part of package.json (as defined by JsobObject) and
|
* Processes a part of package.json (as defined by JsobObject) and update
|
||||||
* update the specified dependency with relevant info.
|
* the specified dependency with relevant info.
|
||||||
*
|
*
|
||||||
* @param dependency the Dependency to update
|
* @param dependency the Dependency to update
|
||||||
* @param jsonObject the jsonObject to parse
|
* @param jsonObject the jsonObject to parse
|
||||||
*/
|
*/
|
||||||
private void processPackage(Dependency dependency, JsonObject jsonObject, String depType) {
|
private void processPackage(Dependency dependency, JsonObject jsonObject, String depType) {
|
||||||
for (int i=0; i<jsonObject.size(); i++) {
|
for (int i = 0; i < jsonObject.size(); i++) {
|
||||||
for (Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
|
for (Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
|
||||||
/*
|
/*
|
||||||
* Create identifies that include the npm module and version. Since these are defined,
|
* Create identifies that include the npm module and version. Since these are defined,
|
||||||
@@ -273,7 +278,7 @@ public class NspAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
moduleName.setConfidence(Confidence.HIGHEST);
|
moduleName.setConfidence(Confidence.HIGHEST);
|
||||||
String version = "";
|
String version = "";
|
||||||
if (entry.getValue() != null && entry.getValue().getValueType() == JsonValue.ValueType.STRING) {
|
if (entry.getValue() != null && entry.getValue().getValueType() == JsonValue.ValueType.STRING) {
|
||||||
version = ((JsonString)entry.getValue()).getString();
|
version = ((JsonString) entry.getValue()).getString();
|
||||||
}
|
}
|
||||||
final Identifier moduleVersion = new Identifier("npm", "Version", null, version);
|
final Identifier moduleVersion = new Identifier("npm", "Version", null, version);
|
||||||
moduleVersion.setConfidence(Confidence.HIGHEST);
|
moduleVersion.setConfidence(Confidence.HIGHEST);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import javax.json.Json;
|
|||||||
import javax.json.JsonArray;
|
import javax.json.JsonArray;
|
||||||
import javax.json.JsonObject;
|
import javax.json.JsonObject;
|
||||||
import javax.json.JsonReader;
|
import javax.json.JsonReader;
|
||||||
|
import org.owasp.dependencycheck.utils.URLConnectionFailureException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class of methods to search via Node Security Platform.
|
* Class of methods to search via Node Security Platform.
|
||||||
@@ -75,70 +76,80 @@ public class NspSearch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submits the package.json file to the NSP public /check API and returns
|
* Submits the package.json file to the NSP public /check API and returns a
|
||||||
* a list of zero or more Advisories.
|
* list of zero or more Advisories.
|
||||||
*
|
*
|
||||||
* @param packageJson the package.json file retrieved from the Dependency
|
* @param packageJson the package.json file retrieved from the Dependency
|
||||||
* @return a List of zero or more Advisory object
|
* @return a List of zero or more Advisory object
|
||||||
* @throws IOException if it's unable to connect to Node Security Platform
|
* @throws IOException if it's unable to connect to Node Security Platform
|
||||||
*/
|
*/
|
||||||
public List<Advisory> submitPackage(JsonObject packageJson) throws IOException {
|
public List<Advisory> submitPackage(JsonObject packageJson) throws IOException {
|
||||||
List<Advisory> result = new ArrayList<>();
|
try {
|
||||||
byte[] packageDatabytes = packageJson.toString().getBytes(StandardCharsets.UTF_8);
|
List<Advisory> result = new ArrayList<>();
|
||||||
|
byte[] packageDatabytes = packageJson.toString().getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(nspCheckUrl, useProxy);
|
final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(nspCheckUrl, useProxy);
|
||||||
conn.setDoOutput(true);
|
conn.setDoOutput(true);
|
||||||
conn.setDoInput(true);
|
conn.setDoInput(true);
|
||||||
conn.setRequestMethod("POST");
|
conn.setRequestMethod("POST");
|
||||||
conn.setRequestProperty("X-NSP-VERSION", "2.6.2");
|
conn.setRequestProperty("X-NSP-VERSION", "2.6.2");
|
||||||
conn.setRequestProperty("Content-Type", "application/json");
|
conn.setRequestProperty("Content-Type", "application/json");
|
||||||
conn.setRequestProperty("Content-Length", Integer.toString(packageDatabytes.length));
|
conn.setRequestProperty("Content-Length", Integer.toString(packageDatabytes.length));
|
||||||
conn.connect();
|
conn.connect();
|
||||||
|
|
||||||
try (OutputStream os = new BufferedOutputStream(conn.getOutputStream())) {
|
try (OutputStream os = new BufferedOutputStream(conn.getOutputStream())) {
|
||||||
os.write(packageDatabytes);
|
os.write(packageDatabytes);
|
||||||
os.flush();
|
os.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn.getResponseCode() == 200) {
|
if (conn.getResponseCode() == 200) {
|
||||||
try (InputStream in = new BufferedInputStream(conn.getInputStream())) {
|
try (InputStream in = new BufferedInputStream(conn.getInputStream())) {
|
||||||
JsonReader jsonReader = Json.createReader(in);
|
JsonReader jsonReader = Json.createReader(in);
|
||||||
JsonArray array = jsonReader.readArray();
|
JsonArray array = jsonReader.readArray();
|
||||||
if (array != null) {
|
if (array != null) {
|
||||||
for (int i=0; i<array.size(); i++) {
|
for (int i = 0; i < array.size(); i++) {
|
||||||
JsonObject object = array.getJsonObject(i);
|
JsonObject object = array.getJsonObject(i);
|
||||||
Advisory advisory = new Advisory();
|
Advisory advisory = new Advisory();
|
||||||
advisory.setId(object.getInt("id"));
|
advisory.setId(object.getInt("id"));
|
||||||
advisory.setUpdatedAt(object.getString("updated_at", null));
|
advisory.setUpdatedAt(object.getString("updated_at", null));
|
||||||
advisory.setCreatedAt(object.getString("created_at", null));
|
advisory.setCreatedAt(object.getString("created_at", null));
|
||||||
advisory.setPublishDate(object.getString("publish_date", null));
|
advisory.setPublishDate(object.getString("publish_date", null));
|
||||||
advisory.setOverview(object.getString("overview"));
|
advisory.setOverview(object.getString("overview"));
|
||||||
advisory.setRecommendation(object.getString("recommendation", null));
|
advisory.setRecommendation(object.getString("recommendation", null));
|
||||||
advisory.setCvssVector(object.getString("cvss_vector", null));
|
advisory.setCvssVector(object.getString("cvss_vector", null));
|
||||||
advisory.setCvssScore(Float.parseFloat(object.getJsonNumber("cvss_score").toString()));
|
advisory.setCvssScore(Float.parseFloat(object.getJsonNumber("cvss_score").toString()));
|
||||||
advisory.setModule(object.getString("module", null));
|
advisory.setModule(object.getString("module", null));
|
||||||
advisory.setVersion(object.getString("version", null));
|
advisory.setVersion(object.getString("version", null));
|
||||||
advisory.setVulnerableVersions(object.getString("vulnerable_versions", null));
|
advisory.setVulnerableVersions(object.getString("vulnerable_versions", null));
|
||||||
advisory.setPatchedVersions(object.getString("patched_versions", null));
|
advisory.setPatchedVersions(object.getString("patched_versions", null));
|
||||||
advisory.setTitle(object.getString("title", null));
|
advisory.setTitle(object.getString("title", null));
|
||||||
advisory.setAdvisory(object.getString("advisory", null));
|
advisory.setAdvisory(object.getString("advisory", null));
|
||||||
|
|
||||||
JsonArray jsonPath = object.getJsonArray("path");
|
JsonArray jsonPath = object.getJsonArray("path");
|
||||||
List<String> stringPath = new ArrayList<>();
|
List<String> stringPath = new ArrayList<>();
|
||||||
for (int j=0; j<jsonPath.size(); j++) {
|
for (int j = 0; j < jsonPath.size(); j++) {
|
||||||
stringPath.add(jsonPath.getString(j));
|
stringPath.add(jsonPath.getString(j));
|
||||||
|
}
|
||||||
|
advisory.setPath(stringPath.toArray(new String[stringPath.size()]));
|
||||||
|
|
||||||
|
result.add(advisory);
|
||||||
}
|
}
|
||||||
advisory.setPath(stringPath.toArray(new String[stringPath.size()]));
|
|
||||||
|
|
||||||
result.add(advisory);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("Could not connect to Node Security Platform. Received response code: {} {}",
|
||||||
|
conn.getResponseCode(), conn.getResponseMessage());
|
||||||
|
throw new IOException("Could not connect to Node Security Platform");
|
||||||
}
|
}
|
||||||
} else {
|
return result;
|
||||||
LOGGER.debug("Could not connect to Node Security Platform. Received response code: {} {}",
|
} catch (IOException ex) {
|
||||||
conn.getResponseCode(), conn.getResponseMessage());
|
if (ex instanceof javax.net.ssl.SSLHandshakeException
|
||||||
throw new IOException("Could not connect to Node Security Platform");
|
&& ex.getMessage().contains("unable to find valid certification path to requested target")) {
|
||||||
|
final String msg = String.format("Unable to connect to '%s' - the Java trust store does not contain a trusted root for the cert. "
|
||||||
|
+ " Please see https://github.com/jeremylong/InstallCert for one method of updating the trusted certificates.", nspCheckUrl);
|
||||||
|
throw new URLConnectionFailureException(msg, ex);
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
package org.owasp.dependencycheck;
|
package org.owasp.dependencycheck;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -58,18 +60,23 @@ public class EngineIT extends BaseDBTestCase {
|
|||||||
try {
|
try {
|
||||||
instance.analyzeDependencies();
|
instance.analyzeDependencies();
|
||||||
} catch (ExceptionCollection ex) {
|
} catch (ExceptionCollection ex) {
|
||||||
if (ex.getExceptions().size() == 1
|
Set<String> allowedMessages = new HashSet<>();
|
||||||
&& (ex.getExceptions().get(0).getMessage().contains("bundle-audit")
|
allowedMessages.add("bundle-audit");
|
||||||
|| ex.getExceptions().get(0).getMessage().contains("AssemblyAnalyzer"))) {
|
allowedMessages.add("AssemblyAnalyzer");
|
||||||
//this is fine to ignore
|
//allowedMessages.add("Unable to connect to");
|
||||||
} else if (ex.getExceptions().size() == 2
|
for (Throwable t : ex.getExceptions()) {
|
||||||
&& ((ex.getExceptions().get(0).getMessage().contains("bundle-audit")
|
boolean isOk = false;
|
||||||
&& ex.getExceptions().get(1).getMessage().contains("AssemblyAnalyzer"))
|
if (t.getMessage()!=null) {
|
||||||
|| (ex.getExceptions().get(1).getMessage().contains("bundle-audit")
|
for (String msg : allowedMessages) {
|
||||||
&& ex.getExceptions().get(0).getMessage().contains("AssemblyAnalyzer")))) {
|
if (t.getMessage().contains(msg)) {
|
||||||
//this is fine to ignore
|
isOk=true;
|
||||||
} else {
|
break;
|
||||||
throw ex;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isOk) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DatabaseProperties prop = null;
|
DatabaseProperties prop = null;
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import static org.junit.Assume.assumeFalse;
|
||||||
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
import org.owasp.dependencycheck.utils.URLConnectionFailureException;
|
||||||
|
|
||||||
public class NspSearchTest extends BaseTest {
|
public class NspSearchTest extends BaseTest {
|
||||||
|
|
||||||
@@ -45,8 +48,7 @@ public class NspSearchTest extends BaseTest {
|
|||||||
searcher = new NspSearch(new URL(url));
|
searcher = new NspSearch(new URL(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Test
|
@Test
|
||||||
//todo: this test does not work in Java 7 - UNABLE TO FIND VALID CERTIFICATION PATH TO REQUESTED TARGET
|
|
||||||
public void testNspSearchPositive() throws Exception {
|
public void testNspSearchPositive() throws Exception {
|
||||||
InputStream in = BaseTest.getResourceAsStream(this, "nsp/package.json");
|
InputStream in = BaseTest.getResourceAsStream(this, "nsp/package.json");
|
||||||
try (JsonReader jsonReader = Json.createReader(in)) {
|
try (JsonReader jsonReader = Json.createReader(in)) {
|
||||||
@@ -56,17 +58,24 @@ public class NspSearchTest extends BaseTest {
|
|||||||
final JsonObject nspPayload = builder.add("package", sanitizedJson).build();
|
final JsonObject nspPayload = builder.add("package", sanitizedJson).build();
|
||||||
final List<Advisory> advisories = searcher.submitPackage(nspPayload);
|
final List<Advisory> advisories = searcher.submitPackage(nspPayload);
|
||||||
Assert.assertTrue(advisories.size() > 0);
|
Assert.assertTrue(advisories.size() > 0);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
assumeFalse(ex instanceof URLConnectionFailureException
|
||||||
|
&& ex.getMessage().contains("Unable to connect to "));
|
||||||
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Test(expected = IOException.class)
|
@Test
|
||||||
//todo: this test does not work in Java 7 - UNABLE TO FIND VALID CERTIFICATION PATH TO REQUESTED TARGET
|
|
||||||
public void testNspSearchNegative() throws Exception {
|
public void testNspSearchNegative() throws Exception {
|
||||||
InputStream in = BaseTest.getResourceAsStream(this, "nsp/package.json");
|
InputStream in = BaseTest.getResourceAsStream(this, "nsp/package.json");
|
||||||
try (JsonReader jsonReader = Json.createReader(in)) {
|
try (JsonReader jsonReader = Json.createReader(in)) {
|
||||||
final JsonObject packageJson = jsonReader.readObject();
|
final JsonObject packageJson = jsonReader.readObject();
|
||||||
final JsonObject sanitizedJson = SanitizePackage.sanitize(packageJson);
|
final JsonObject sanitizedJson = SanitizePackage.sanitize(packageJson);
|
||||||
searcher.submitPackage(sanitizedJson);
|
searcher.submitPackage(sanitizedJson);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
assumeFalse(ex instanceof URLConnectionFailureException
|
||||||
|
&& ex.getMessage().contains("Unable to connect to "));
|
||||||
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user