From c7a70741539e5452b7ef9bcf833ddc8c1c845182 Mon Sep 17 00:00:00 2001 From: mehab Date: Tue, 17 Jan 2023 21:46:56 +0000 Subject: [PATCH 01/31] unirest removed from repo meta analyzer files Signed-off-by: mehab --- .../parser/osv/OsvAdvisoryParser.java | 4 +- .../tasks/OsvDownloadTask.java | 2 +- .../repositories/AbstractMetaAnalyzer.java | 16 ++++ .../tasks/repositories/CargoMetaAnalyzer.java | 51 +++++------ .../repositories/ComposerMetaAnalyzer.java | 50 +++++------ .../tasks/repositories/GemMetaAnalyzer.java | 32 +++---- .../repositories/GoModulesMetaAnalyzer.java | 35 +++----- .../tasks/repositories/HexMetaAnalyzer.java | 37 +++----- .../tasks/repositories/MavenMetaAnalyzer.java | 54 +++++------ .../tasks/repositories/NpmMetaAnalyzer.java | 33 +++---- .../tasks/repositories/NugetMetaAnalyzer.java | 89 +++++++++---------- .../tasks/repositories/PypiMetaAnalyzer.java | 38 ++++---- .../tasks/scanners/OssIndexAnalysisTask.java | 2 +- .../integration/ApiClient.java | 2 +- .../parser/osv/OsvAdvisoryParserTest.java | 4 +- .../tasks/OsvDownloadTaskTest.java | 6 +- 16 files changed, 204 insertions(+), 251 deletions(-) diff --git a/src/main/java/org/dependencytrack/parser/osv/OsvAdvisoryParser.java b/src/main/java/org/dependencytrack/parser/osv/OsvAdvisoryParser.java index dc73b2aa75..8b1b3692b8 100644 --- a/src/main/java/org/dependencytrack/parser/osv/OsvAdvisoryParser.java +++ b/src/main/java/org/dependencytrack/parser/osv/OsvAdvisoryParser.java @@ -1,7 +1,7 @@ package org.dependencytrack.parser.osv; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; +import org.json.JSONArray; +import org.json.JSONObject; import org.apache.commons.lang3.StringUtils; import org.dependencytrack.model.Severity; import org.dependencytrack.parser.osv.model.OsvAdvisory; diff --git a/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java b/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java index 4f9fb295a9..4fedb95156 100644 --- a/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java +++ b/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java @@ -6,7 +6,7 @@ import alpine.model.ConfigProperty; import com.github.packageurl.MalformedPackageURLException; import com.github.packageurl.PackageURL; -import kong.unirest.json.JSONObject; +import org.json.JSONObject; import org.apache.http.StatusLine; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; diff --git a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java index bca39977dd..03dcb4e8d9 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java @@ -22,10 +22,17 @@ import alpine.notification.Notification; import alpine.notification.NotificationLevel; import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.dependencytrack.common.HttpClientPool; import org.dependencytrack.model.Component; import org.dependencytrack.notification.NotificationConstants; import org.dependencytrack.notification.NotificationGroup; import org.dependencytrack.notification.NotificationScope; +import org.dependencytrack.util.HttpUtil; + +import java.io.IOException; /** * Base abstract class that all IMetaAnalyzer implementations should likely extend. @@ -84,4 +91,13 @@ protected void handleRequestException(final Logger logger, final Exception e) { ); } + protected CloseableHttpResponse processHttpRequest(String url) throws IOException { + final HttpUriRequest request = new HttpGet(url); + request.addHeader("accept", "application/json"); + if (username != null || password != null) { + request.addHeader("Authorization", HttpUtil.basicAuthHeaderValue(username, password)); + } + return HttpClientPool.getClient().execute(request); + } + } diff --git a/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java index 43381f6c48..1ee289acbd 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java @@ -20,19 +20,19 @@ import alpine.common.logging.Logger; import com.github.packageurl.PackageURL; -import kong.unirest.GetRequest; -import kong.unirest.HttpRequest; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.UnirestException; -import kong.unirest.UnirestInstance; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; -import org.dependencytrack.common.UnirestFactory; +import org.json.JSONArray; +import org.json.JSONObject; +import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; +import org.apache.http.StatusLine; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.util.EntityUtils; import org.dependencytrack.model.Component; import org.dependencytrack.model.RepositoryType; import org.dependencytrack.util.DateUtil; +import java.io.IOException; + /** * An IMetaAnalyzer implementation that supports Cargo via crates.io compatible repos * @@ -67,35 +67,30 @@ public RepositoryType supportedRepositoryType() { * {@inheritDoc} */ public MetaModel analyze(final Component component) { - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); final MetaModel meta = new MetaModel(component); if (component.getPurl() != null) { final String url = String.format(baseUrl + API_URL, component.getPurl().getName()); - try { - final HttpRequest request = ui.get(url) - .header("accept", "application/json"); - if (username != null || password != null) { - request.basicAuth(username, password); - } - final HttpResponse response = request.asJson(); - - if (response.getStatus() == 200) { - if (response.getBody() != null && response.getBody().getObject() != null) { - final JSONObject crate = response.getBody().getObject().optJSONObject("crate"); + try (final CloseableHttpResponse response = processHttpRequest(url)) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + final HttpEntity entity = response.getEntity(); + if (entity != null) { + String responseString = EntityUtils.toString(entity); + org.json.JSONObject jsonObject = new org.json.JSONObject(responseString); + final JSONObject crate = jsonObject.optJSONObject("crate"); if (crate != null) { final String latest = crate.getString("newest_version"); meta.setLatestVersion(latest); } - final JSONArray versions = response.getBody().getObject().optJSONArray("versions"); + final JSONArray versions = jsonObject.optJSONArray("versions"); if (versions != null) { - for (int i=0; i request = ui.get(url) - .header("accept", "application/json"); - if (username != null || password != null) { - request.basicAuth(username, password); + try (final CloseableHttpResponse response = processHttpRequest(url)) { + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component); + return meta; } - final HttpResponse response = request.asJson(); - - if (response.getStatus() != 200) { - handleUnexpectedHttpResponse(LOGGER, url, response.getStatus(), response.getStatusText(), component); + if (response.getEntity().getContent() == null) { return meta; } - - if (response.getBody() == null || response.getBody().getObject() == null) { + String jsonString = EntityUtils.toString(response.getEntity()); + if (jsonString.equalsIgnoreCase("")) { return meta; } - + if (jsonString.equalsIgnoreCase("{}")) { + return meta; + } + org.json.JSONObject jsonObject = new org.json.JSONObject(jsonString); final String expectedResponsePackage = component.getPurl().getNamespace() + "/" + component.getPurl().getName(); - final JSONObject responsePackages = response - .getBody() - .getObject() + final org.json.JSONObject responsePackages = jsonObject .getJSONObject("packages"); if (!responsePackages.has(expectedResponsePackage)) { // the package no longer exists - like this one: https://repo.packagist.org/p/magento/adobe-ims.json @@ -121,8 +115,7 @@ public MetaModel analyze(final Component component) { final String version_normalized = composerPackage.getJSONObject(key).getString("version_normalized"); ComparableVersion currentComparableVersion = new ComparableVersion(version_normalized); - if ( currentComparableVersion.compareTo(latestVersion) < 0) - { + if (currentComparableVersion.compareTo(latestVersion) < 0) { // smaller version can be skipped return; } @@ -138,10 +131,11 @@ public MetaModel analyze(final Component component) { LOGGER.warn("An error occurred while parsing upload time", e); } }); - } catch (UnirestException e) { - handleRequestException(LOGGER, e); + } catch (IOException ex) { + handleRequestException(LOGGER, ex); } + return meta; } diff --git a/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java index 3747e29ebd..7b46e2eb87 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java @@ -26,9 +26,16 @@ import kong.unirest.JsonNode; import kong.unirest.UnirestException; import kong.unirest.UnirestInstance; +import org.apache.http.HttpStatus; +import org.apache.http.StatusLine; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.util.EntityUtils; import org.dependencytrack.common.UnirestFactory; import org.dependencytrack.model.Component; import org.dependencytrack.model.RepositoryType; +import org.json.JSONObject; + +import java.io.IOException; /** * An IMetaAnalyzer implementation that supports Ruby Gems. @@ -64,29 +71,24 @@ public RepositoryType supportedRepositoryType() { * {@inheritDoc} */ public MetaModel analyze(final Component component) { - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); final MetaModel meta = new MetaModel(component); if (component.getPurl() != null) { final String url = String.format(baseUrl + API_URL, component.getPurl().getName()); - try { - final HttpRequest request = ui.get(url) - .header("accept", "application/json"); - if (username != null || password != null) { - request.basicAuth(username, password); - } - final HttpResponse response = request.asJson(); - - if (response.getStatus() == 200) { - if (response.getBody() != null && response.getBody().getObject() != null) { - final String latest = response.getBody().getObject().getString("version"); + try (final CloseableHttpResponse response = processHttpRequest(url)) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ + if(response.getEntity()!=null){ + String responseString = EntityUtils.toString(response.getEntity()); + JSONObject jsonObject = new JSONObject(responseString); + final String latest = jsonObject.getString("version"); meta.setLatestVersion(latest); } } else { - handleUnexpectedHttpResponse(LOGGER, url, response.getStatus(), response.getStatusText(), component); + handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component); } - } catch (UnirestException e) { - handleRequestException(LOGGER, e); + }catch (IOException ex){ + handleRequestException(LOGGER, ex); } + } return meta; } diff --git a/src/main/java/org/dependencytrack/tasks/repositories/GoModulesMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/GoModulesMetaAnalyzer.java index 7bbdf55ca9..696f5f3305 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/GoModulesMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/GoModulesMetaAnalyzer.java @@ -20,18 +20,15 @@ import alpine.common.logging.Logger; import com.github.packageurl.PackageURL; -import kong.unirest.GetRequest; -import kong.unirest.HttpRequest; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.UnirestException; -import kong.unirest.UnirestInstance; -import kong.unirest.json.JSONObject; import org.apache.commons.lang3.StringUtils; -import org.dependencytrack.common.UnirestFactory; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.util.EntityUtils; import org.dependencytrack.model.Component; import org.dependencytrack.model.RepositoryType; +import org.json.JSONObject; +import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -66,21 +63,13 @@ public MetaModel analyze(final Component component) { if (component.getPurl() == null || component.getPurl().getNamespace() == null) { return meta; } - - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); final String url = String.format(baseUrl + API_URL, caseEncode(component.getPurl().getNamespace()), caseEncode(component.getPurl().getName())); - try { - final HttpRequest request = ui.get(url) - .header("accept", "application/json"); - if (username != null || password != null) { - request.basicAuth(username, password); - } - final HttpResponse response = request.asJson(); - - if (response.getStatus() == 200) { - if (response.getBody() != null && response.getBody().getObject() != null) { - final JSONObject responseJson = response.getBody().getObject(); + try (final CloseableHttpResponse response = processHttpRequest(url)) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + if (response.getEntity()!=null) { + String responseString = EntityUtils.toString(response.getEntity()); + final JSONObject responseJson = new org.json.JSONObject(responseString); meta.setLatestVersion(responseJson.getString("Version")); // Module versions are prefixed with "v" in the Go ecosystem. @@ -99,9 +88,9 @@ public MetaModel analyze(final Component component) { } } } else { - handleUnexpectedHttpResponse(LOGGER, url, response.getStatus(), response.getStatusText(), component); + handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component); } - } catch (UnirestException | ParseException e) { + } catch (IOException | ParseException e) { handleRequestException(LOGGER, e); } diff --git a/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java index 0d5b23dd6b..53ac9dc373 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java @@ -20,18 +20,15 @@ import alpine.common.logging.Logger; import com.github.packageurl.PackageURL; -import kong.unirest.GetRequest; -import kong.unirest.HttpRequest; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.UnirestException; -import kong.unirest.UnirestInstance; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; -import org.dependencytrack.common.UnirestFactory; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.util.EntityUtils; import org.dependencytrack.model.Component; import org.dependencytrack.model.RepositoryType; +import org.json.JSONArray; +import org.json.JSONObject; +import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -71,7 +68,6 @@ public RepositoryType supportedRepositoryType() { * {@inheritDoc} */ public MetaModel analyze(final Component component) { - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); final MetaModel meta = new MetaModel(component); if (component.getPurl() != null) { @@ -83,17 +79,12 @@ public MetaModel analyze(final Component component) { } final String url = String.format(baseUrl + API_URL, packageName); - try { - final HttpRequest request = ui.get(url) - .header("accept", "application/json"); - if (username != null || password != null) { - request.basicAuth(username, password); - } - final HttpResponse response = request.asJson(); - - if (response.getStatus() == 200) { - if (response.getBody() != null && response.getBody().getObject() != null) { - final JSONArray releasesArray = response.getBody().getObject().getJSONArray("releases"); + try (final CloseableHttpResponse response = processHttpRequest(url)) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + if (response.getEntity()!=null) { + String responseString = EntityUtils.toString(response.getEntity()); + org.json.JSONObject jsonObject = new org.json.JSONObject(responseString); + final JSONArray releasesArray = jsonObject.getJSONArray("releases"); if (releasesArray.length() > 0) { // The first one in the array is always the latest version final JSONObject release = releasesArray.getJSONObject(0); @@ -112,9 +103,9 @@ public MetaModel analyze(final Component component) { } } } else { - handleUnexpectedHttpResponse(LOGGER, url, response.getStatus(), response.getStatusText(), component); + handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component); } - } catch (UnirestException e) { + } catch (IOException e) { handleRequestException(LOGGER, e); } } diff --git a/src/main/java/org/dependencytrack/tasks/repositories/MavenMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/MavenMetaAnalyzer.java index f3629c618e..0dc73707c5 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/MavenMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/MavenMetaAnalyzer.java @@ -21,15 +21,11 @@ import alpine.common.logging.Logger; import com.github.packageurl.PackageURL; import org.apache.http.HttpEntity; -import org.apache.http.StatusLine; +import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; -import org.dependencytrack.common.HttpClientPool; import org.dependencytrack.model.Component; import org.dependencytrack.model.RepositoryType; import org.dependencytrack.util.DateUtil; -import org.dependencytrack.util.HttpUtil; import org.dependencytrack.util.XmlUtil; import org.w3c.dom.Document; import org.xml.sax.SAXException; @@ -81,44 +77,36 @@ public MetaModel analyze(final Component component) { if (component.getPurl() != null) { final String mavenGavUrl = component.getPurl().getNamespace().replaceAll("\\.", "/") + "/" + component.getPurl().getName(); final String url = String.format(baseUrl + REPO_METADATA_URL, mavenGavUrl); - try { - final HttpUriRequest request = new HttpGet(url); + try (final CloseableHttpResponse response = processHttpRequest(url)) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + final HttpEntity entity = response.getEntity(); + if (entity != null) { + try (InputStream in = entity.getContent()) { + final Document document = XmlUtil.buildSecureDocumentBuilder().parse(in); + final XPathFactory xpathFactory = XPathFactory.newInstance(); + final XPath xpath = xpathFactory.newXPath(); - if (username != null || password != null) { - request.setHeader("Authorization", HttpUtil.basicAuthHeaderValue(username, password)); - } - - try (final CloseableHttpResponse response = HttpClientPool.getClient().execute(request)) { - final StatusLine status = response.getStatusLine(); - if (status.getStatusCode() == 200) { - final HttpEntity entity = response.getEntity(); - if (entity != null) { - try (InputStream in = entity.getContent()) { - final Document document = XmlUtil.buildSecureDocumentBuilder().parse(in); - final XPathFactory xpathFactory = XPathFactory.newInstance(); - final XPath xpath = xpathFactory.newXPath(); + final XPathExpression releaseExpression = xpath.compile("/metadata/versioning/release"); + final XPathExpression latestExpression = xpath.compile("/metadata/versioning/latest"); + final String release = (String) releaseExpression.evaluate(document, XPathConstants.STRING); + final String latest = (String) latestExpression.evaluate(document, XPathConstants.STRING); - final XPathExpression releaseExpression = xpath.compile("/metadata/versioning/release"); - final XPathExpression latestExpression = xpath.compile("/metadata/versioning/latest"); - final String release = (String) releaseExpression.evaluate(document, XPathConstants.STRING); - final String latest = (String) latestExpression.evaluate(document, XPathConstants.STRING); + final XPathExpression lastUpdatedExpression = xpath.compile("/metadata/versioning/lastUpdated"); + final String lastUpdated = (String) lastUpdatedExpression.evaluate(document, XPathConstants.STRING); - final XPathExpression lastUpdatedExpression = xpath.compile("/metadata/versioning/lastUpdated"); - final String lastUpdated = (String) lastUpdatedExpression.evaluate(document, XPathConstants.STRING); - - meta.setLatestVersion(release != null ? release: latest); - if (lastUpdated != null) { - meta.setPublishedTimestamp(DateUtil.parseDate(lastUpdated)); - } + meta.setLatestVersion(release != null ? release : latest); + if (lastUpdated != null) { + meta.setPublishedTimestamp(DateUtil.parseDate(lastUpdated)); } } - } else { - handleUnexpectedHttpResponse(LOGGER, url, status.getStatusCode(), status.getReasonPhrase(), component); } + } else { + handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component); } } catch (IOException | ParserConfigurationException | SAXException | XPathExpressionException e) { handleRequestException(LOGGER, e); } + } return meta; } diff --git a/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java index 03ccf30bfc..d7e0553bab 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java @@ -20,15 +20,16 @@ import alpine.common.logging.Logger; import com.github.packageurl.PackageURL; -import kong.unirest.GetRequest; -import kong.unirest.HttpRequest; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.UnirestException; import kong.unirest.UnirestInstance; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.util.EntityUtils; import org.dependencytrack.common.UnirestFactory; import org.dependencytrack.model.Component; import org.dependencytrack.model.RepositoryType; +import org.json.JSONObject; + +import java.io.IOException; /** * An IMetaAnalyzer implementation that supports NPM. @@ -64,7 +65,6 @@ public RepositoryType supportedRepositoryType() { * {@inheritDoc} */ public MetaModel analyze(final Component component) { - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); final MetaModel meta = new MetaModel(component); if (component.getPurl() != null) { @@ -76,25 +76,20 @@ public MetaModel analyze(final Component component) { } final String url = String.format(baseUrl + API_URL, packageName); - try { - final HttpRequest request = ui.get(url) - .header("accept", "application/json"); - if (username != null || password != null) { - request.basicAuth(username, password); - } - final HttpResponse response = request.asJson(); - - if (response.getStatus() == 200) { - if (response.getBody() != null && response.getBody().getObject() != null) { - final String latest = response.getBody().getObject().optString("latest"); + try (final CloseableHttpResponse response = processHttpRequest(url)) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + if (response.getEntity()!=null) { + String responseString = EntityUtils.toString(response.getEntity()); + JSONObject jsonObject = new JSONObject(responseString); + final String latest = jsonObject.optString("latest"); if (latest != null) { meta.setLatestVersion(latest); } } } else { - handleUnexpectedHttpResponse(LOGGER, url, response.getStatus(), response.getStatusText(), component); + handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component); } - } catch (UnirestException e) { + } catch (IOException e) { handleRequestException(LOGGER, e); } } diff --git a/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java index bd0333dc59..8588b32364 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java @@ -20,19 +20,16 @@ import alpine.common.logging.Logger; import com.github.packageurl.PackageURL; -import kong.unirest.GetRequest; -import kong.unirest.HttpRequest; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.UnirestException; -import kong.unirest.UnirestInstance; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.util.EntityUtils; import org.apache.maven.artifact.versioning.ComparableVersion; -import org.dependencytrack.common.UnirestFactory; import org.dependencytrack.model.Component; import org.dependencytrack.model.RepositoryType; +import org.json.JSONArray; +import org.json.JSONObject; +import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -107,25 +104,26 @@ public MetaModel analyze(final Component component) { private boolean performVersionCheck(final MetaModel meta, final Component component) { final String url = String.format(versionQueryUrl, component.getPurl().getName().toLowerCase()); - try { - final HttpResponse response = httpGet(url); - if (response.getStatus() == 200) { - if (response.getBody() != null && response.getBody().getObject() != null) { - final JSONArray versions = response.getBody().getObject().getJSONArray("versions"); + try (final CloseableHttpResponse response = processHttpRequest(url)) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + if (response.getEntity() != null) { + String responseString = EntityUtils.toString(response.getEntity()); + org.json.JSONObject jsonObject = new org.json.JSONObject(responseString); + final org.json.JSONArray versions = jsonObject.getJSONArray("versions"); final String latest = findLatestVersion(versions); // get the last version in the array meta.setLatestVersion(latest); } return true; } else { - handleUnexpectedHttpResponse(LOGGER, url, response.getStatus(), response.getStatusText(), component); + handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component); } - } catch (UnirestException e) { + } catch (IOException e) { handleRequestException(LOGGER, e); } return false; } - private String findLatestVersion(JSONArray versions) { + private String findLatestVersion(org.json.JSONArray versions) { if (versions.length() < 1) { return null; } @@ -142,33 +140,25 @@ private String findLatestVersion(JSONArray versions) { return latestVersion.toString(); } - private HttpResponse httpGet(String url) { - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); - final HttpRequest request = ui.get(url).header("accept", "application/json"); - - if (username != null || password != null) { - request.basicAuth(username, password); - } - - return request.asJson(); - } - private boolean performLastPublishedCheck(final MetaModel meta, final Component component) { final String url = String.format(registrationUrl, component.getPurl().getName().toLowerCase(), meta.getLatestVersion()); - try { - final HttpResponse response = httpGet(url); - if (response.getStatus() == 200) { - if (response.getBody() != null && response.getBody().getObject() != null) { - final String updateTime = response.getBody().getObject().optString("published", null); - if (updateTime != null) { - meta.setPublishedTimestamp(parseUpdateTime(updateTime)); + try (final CloseableHttpResponse response = processHttpRequest(url)) { + if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { + if (response.getEntity() != null) { + String stringResponse = EntityUtils.toString(response.getEntity()); + if (!stringResponse.equalsIgnoreCase("") && !stringResponse.equalsIgnoreCase("{}")) { + org.json.JSONObject jsonResponse = new org.json.JSONObject(stringResponse); + final String updateTime = jsonResponse.optString("published", null); + if (updateTime != null) { + meta.setPublishedTimestamp(parseUpdateTime(updateTime)); + } + return true; } } - return true; } else { - handleUnexpectedHttpResponse(LOGGER, url, response.getStatus(), response.getStatusText(), component); + handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component); } - } catch (UnirestException e) { + } catch (IOException e) { handleRequestException(LOGGER, e); } return false; @@ -177,17 +167,22 @@ private boolean performLastPublishedCheck(final MetaModel meta, final Component private void initializeEndpoints() { final String url = baseUrl + INDEX_URL; try { - final HttpResponse response = httpGet(url); - if (response.getStatus() == 200 && response.getBody() != null && response.getBody().getObject() != null) { - final JSONArray resources = response.getBody().getObject().getJSONArray("resources"); - final JSONObject packageBaseResource = findResourceByType(resources, "PackageBaseAddress"); - final JSONObject registrationsBaseResource = findResourceByType(resources, "RegistrationsBaseUrl"); - if (packageBaseResource != null && registrationsBaseResource != null) { - versionQueryUrl = packageBaseResource.getString("@id") + "%s/index.json"; - registrationUrl = registrationsBaseResource.getString("@id") + "%s/%s.json"; + try (final CloseableHttpResponse response = processHttpRequest(url)) { + if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { + if(response.getEntity()!=null){ + String responseString = EntityUtils.toString(response.getEntity()); + org.json.JSONObject responseJson = new org.json.JSONObject(responseString); + final org.json.JSONArray resources = responseJson.getJSONArray("resources"); + final org.json.JSONObject packageBaseResource = findResourceByType(resources, "PackageBaseAddress"); + final org.json.JSONObject registrationsBaseResource = findResourceByType(resources, "RegistrationsBaseUrl"); + if (packageBaseResource != null && registrationsBaseResource != null) { + versionQueryUrl = packageBaseResource.getString("@id") + "%s/index.json"; + registrationUrl = registrationsBaseResource.getString("@id") + "%s/%s.json"; + } + } } } - } catch (UnirestException e) { + } catch (IOException e) { handleRequestException(LOGGER, e); } } diff --git a/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java index bddda44aad..f466d89fc3 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java @@ -20,18 +20,16 @@ import alpine.common.logging.Logger; import com.github.packageurl.PackageURL; -import kong.unirest.GetRequest; -import kong.unirest.HttpRequest; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; import kong.unirest.UnirestException; -import kong.unirest.UnirestInstance; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; -import org.dependencytrack.common.UnirestFactory; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.util.EntityUtils; import org.dependencytrack.model.Component; import org.dependencytrack.model.RepositoryType; +import org.json.JSONArray; +import org.json.JSONObject; +import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -71,25 +69,19 @@ public RepositoryType supportedRepositoryType() { * {@inheritDoc} */ public MetaModel analyze(final Component component) { - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); final MetaModel meta = new MetaModel(component); if (component.getPurl() != null) { final String url = String.format(baseUrl + API_URL, component.getPurl().getName()); - try { - final HttpRequest request = ui.get(url) - .header("accept", "application/json"); - if (username != null || password != null) { - request.basicAuth(username, password); - } - final HttpResponse response = request.asJson(); - - if (response.getStatus() == 200) { - if (response.getBody() != null && response.getBody().getObject() != null) { - final JSONObject info = response.getBody().getObject().getJSONObject("info"); + try (final CloseableHttpResponse response = processHttpRequest(url)) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + if (response.getEntity() != null) { + String stringResponse = EntityUtils.toString(response.getEntity()); + org.json.JSONObject jsonObject = new org.json.JSONObject(stringResponse); + final org.json.JSONObject info = jsonObject.getJSONObject("info"); final String latest = info.optString("version", null); if (latest != null) { meta.setLatestVersion(latest); - final JSONObject releases = response.getBody().getObject().getJSONObject("releases"); + final org.json.JSONObject releases = jsonObject.getJSONObject("releases"); final JSONArray latestArray = releases.getJSONArray(latest); if (latestArray.length() > 0) { final JSONObject release = latestArray.getJSONObject(0); @@ -107,9 +99,9 @@ public MetaModel analyze(final Component component) { } } } else { - handleUnexpectedHttpResponse(LOGGER, url, response.getStatus(), response.getStatusText(), component); + handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component); } - } catch (UnirestException e) { + } catch (UnirestException | IOException e) { handleRequestException(LOGGER, e); } } diff --git a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java index d7b0079528..8f4ba3a50b 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java @@ -38,7 +38,7 @@ import kong.unirest.JsonNode; import kong.unirest.UnirestException; import kong.unirest.UnirestInstance; -import kong.unirest.json.JSONObject; +import org.json.JSONObject; import org.apache.commons.collections4.CollectionUtils; import org.apache.http.HttpHeaders; import org.dependencytrack.common.ConfigKey; diff --git a/src/test/java/org/dependencytrack/integration/ApiClient.java b/src/test/java/org/dependencytrack/integration/ApiClient.java index d0d7d35a97..157a31cdc0 100644 --- a/src/test/java/org/dependencytrack/integration/ApiClient.java +++ b/src/test/java/org/dependencytrack/integration/ApiClient.java @@ -22,7 +22,7 @@ import kong.unirest.JsonNode; import kong.unirest.UnirestException; import kong.unirest.UnirestInstance; -import kong.unirest.json.JSONObject; +import org.json.JSONObject; import org.apache.commons.io.FileUtils; import org.dependencytrack.common.UnirestFactory; diff --git a/src/test/java/org/dependencytrack/parser/osv/OsvAdvisoryParserTest.java b/src/test/java/org/dependencytrack/parser/osv/OsvAdvisoryParserTest.java index d33dc3fe66..4ba6b8ba4f 100644 --- a/src/test/java/org/dependencytrack/parser/osv/OsvAdvisoryParserTest.java +++ b/src/test/java/org/dependencytrack/parser/osv/OsvAdvisoryParserTest.java @@ -1,7 +1,7 @@ package org.dependencytrack.parser.osv; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; +import org.json.JSONArray; +import org.json.JSONObject; import org.dependencytrack.parser.osv.model.OsvAdvisory; import org.dependencytrack.parser.osv.model.OsvAffectedPackage; import org.junit.Assert; diff --git a/src/test/java/org/dependencytrack/tasks/OsvDownloadTaskTest.java b/src/test/java/org/dependencytrack/tasks/OsvDownloadTaskTest.java index 5d6edc9406..5fc37d5b81 100644 --- a/src/test/java/org/dependencytrack/tasks/OsvDownloadTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/OsvDownloadTaskTest.java @@ -17,16 +17,13 @@ import alpine.model.IConfigProperty; import com.github.packageurl.PackageURL; -import kong.unirest.json.JSONObject; +import org.json.JSONObject; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; import org.dependencytrack.PersistenceCapableTest; import org.dependencytrack.model.AffectedVersionAttribution; import org.dependencytrack.model.Severity; import org.dependencytrack.model.Vulnerability; import org.dependencytrack.model.VulnerableSoftware; -import org.dependencytrack.parser.github.graphql.model.GitHubSecurityAdvisory; -import org.dependencytrack.parser.github.graphql.model.GitHubVulnerability; import org.dependencytrack.parser.osv.OsvAdvisoryParser; import org.dependencytrack.parser.osv.model.OsvAdvisory; import org.dependencytrack.persistence.CweImporter; @@ -39,7 +36,6 @@ import java.nio.file.Paths; import java.time.LocalDateTime; import java.time.ZoneOffset; -import java.time.ZonedDateTime; import java.util.List; import java.util.function.Consumer; From 39f31f33e02daf60d21cc8d597d7ed4736b8be21 Mon Sep 17 00:00:00 2001 From: mehab Date: Tue, 17 Jan 2023 21:55:18 +0000 Subject: [PATCH 02/31] empty commit Signed-off-by: mehab --- .../dependencytrack/tasks/repositories/PypiMetaAnalyzer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java index f466d89fc3..8c439802c9 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java @@ -107,4 +107,4 @@ public MetaModel analyze(final Component component) { } return meta; } -} +} \ No newline at end of file From 7e40086909217144674370379c6055e4ec5ab277 Mon Sep 17 00:00:00 2001 From: mehab Date: Thu, 19 Jan 2023 17:23:57 +0000 Subject: [PATCH 03/31] more removal of unirest Signed-off-by: mehab --- .../publisher/AbstractWebhookPublisher.java | 79 +++++++++++-------- .../graphql/GitHubSecurityAdvisoryParser.java | 4 +- .../parser/snyk/SnykParser.java | 4 +- .../tasks/GitHubAdvisoryMirrorTask.java | 54 +++++++++---- .../tasks/repositories/GemMetaAnalyzer.java | 8 -- .../tasks/repositories/NpmMetaAnalyzer.java | 2 - .../tasks/repositories/PypiMetaAnalyzer.java | 3 +- .../tasks/scanners/SnykAnalysisTask.java | 68 +++++++++------- .../tasks/scanners/VulnDbAnalysisTask.java | 8 +- .../parser/snyk/SnykParserTest.java | 4 +- 10 files changed, 138 insertions(+), 96 deletions(-) diff --git a/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java b/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java index b865e156f8..3fc2765d21 100644 --- a/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java +++ b/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java @@ -20,17 +20,25 @@ import alpine.common.logging.Logger; import alpine.notification.Notification; +import alpine.notification.NotificationLevel; import io.pebbletemplates.pebble.template.PebbleTemplate; -import kong.unirest.Header; -import kong.unirest.Headers; -import kong.unirest.UnirestInstance; -import org.dependencytrack.common.UnirestFactory; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.util.EntityUtils; +import org.dependencytrack.common.HttpClientPool; import org.dependencytrack.exception.PublisherException; +import org.dependencytrack.notification.NotificationConstants; +import org.dependencytrack.notification.NotificationGroup; +import org.dependencytrack.notification.NotificationScope; +import org.dependencytrack.util.HttpUtil; +import org.slf4j.LoggerFactory; import javax.json.JsonObject; -import java.util.stream.Collectors; +import java.io.IOException; public abstract class AbstractWebhookPublisher implements Publisher { + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AbstractWebhookPublisher.class); public void publish(final String publisherName, final PebbleTemplate template, final Notification notification, final JsonObject config) { final Logger logger = Logger.getLogger(this.getClass()); @@ -46,33 +54,31 @@ public void publish(final String publisherName, final PebbleTemplate template, f return; } final String mimeType = getTemplateMimeType(config); - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); - - final var headers = new Headers(); - headers.add("content-type", mimeType); - headers.add("accept", mimeType); - final BasicAuthCredentials credentials; try { - credentials = getBasicAuthCredentials(); - } catch (PublisherException e) { - logger.warn("An error occurred during the retrieval of credentials needed for notification publication. Skipping notification", e); - return; - } - if (credentials != null) { - headers.setBasicAuth(credentials.user(), credentials.password()); - } - - final var response = ui.post(destination) - .headers(headers.all().stream().collect(Collectors.toMap(Header::getName, Header::getValue))) - .body(content) - .asString(); - - if (!response.isSuccess()) { - logger.error("An error was encountered publishing notification to " + publisherName); - logger.error("HTTP Status : " + response.getStatus() + " " + response.getStatusText()); - logger.error("Destination: " + destination); - logger.error("Response: " + response.getBody()); - logger.debug(content); + HttpPost request = new HttpPost(destination); + request.addHeader("content-type", mimeType); + request.addHeader("accept", mimeType); + final BasicAuthCredentials credentials; + try { + credentials = getBasicAuthCredentials(); + } catch (PublisherException e) { + logger.warn("An error occurred during the retrieval of credentials needed for notification publication. Skipping notification", e); + return; + } + if (credentials != null) { + request.addHeader("Authorization", HttpUtil.basicAuthHeaderValue(credentials.user(), credentials.password())); + } + request.setEntity(new StringEntity(content)); + final CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + if (response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() >= 300) { + logger.error("An error was encountered publishing notification to " + publisherName); + logger.error("HTTP Status : " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); + logger.error("Destination: " + destination); + logger.error("Response: " + EntityUtils.toString(response.getEntity())); + logger.debug(content); + } + }catch (IOException ex){ + handleRequestException(LOGGER, ex); } } @@ -86,4 +92,15 @@ protected BasicAuthCredentials getBasicAuthCredentials() { protected record BasicAuthCredentials(String user, String password) { } + + protected void handleRequestException(final org.slf4j.Logger logger, final Exception e) { + logger.error("Request failure", e); + Notification.dispatch(new Notification() + .scope(NotificationScope.SYSTEM) + .group(NotificationGroup.REPOSITORY) + .title(NotificationConstants.Title.REPO_ERROR) + .content("An error occurred publishing notification. Check log for details. " + e.getMessage()) + .level(NotificationLevel.ERROR) + ); + } } diff --git a/src/main/java/org/dependencytrack/parser/github/graphql/GitHubSecurityAdvisoryParser.java b/src/main/java/org/dependencytrack/parser/github/graphql/GitHubSecurityAdvisoryParser.java index a06ce36b82..7e7854bd13 100644 --- a/src/main/java/org/dependencytrack/parser/github/graphql/GitHubSecurityAdvisoryParser.java +++ b/src/main/java/org/dependencytrack/parser/github/graphql/GitHubSecurityAdvisoryParser.java @@ -18,8 +18,8 @@ */ package org.dependencytrack.parser.github.graphql; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; +import org.json.JSONArray; +import org.json.JSONObject; import org.apache.commons.lang3.tuple.Pair; import org.dependencytrack.parser.github.graphql.model.GitHubSecurityAdvisory; import org.dependencytrack.parser.github.graphql.model.GitHubVulnerability; diff --git a/src/main/java/org/dependencytrack/parser/snyk/SnykParser.java b/src/main/java/org/dependencytrack/parser/snyk/SnykParser.java index 861c9fb2c2..0f6c7b9c6b 100644 --- a/src/main/java/org/dependencytrack/parser/snyk/SnykParser.java +++ b/src/main/java/org/dependencytrack/parser/snyk/SnykParser.java @@ -4,8 +4,8 @@ import alpine.model.ConfigProperty; import com.github.packageurl.MalformedPackageURLException; import com.github.packageurl.PackageURL; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; +import org.json.JSONArray; +import org.json.JSONObject; import org.dependencytrack.model.ConfigPropertyConstants; import org.dependencytrack.model.Cwe; import org.dependencytrack.model.Severity; diff --git a/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java b/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java index 85fb9c2625..5d2f628378 100644 --- a/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java +++ b/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java @@ -29,12 +29,12 @@ import com.github.packageurl.PackageURLBuilder; import io.pebbletemplates.pebble.PebbleEngine; import io.pebbletemplates.pebble.template.PebbleTemplate; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.UnirestInstance; -import kong.unirest.json.JSONObject; import org.apache.commons.lang3.tuple.Pair; -import org.dependencytrack.common.UnirestFactory; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.util.EntityUtils; +import org.dependencytrack.common.HttpClientPool; import org.dependencytrack.event.GitHubAdvisoryMirrorEvent; import org.dependencytrack.event.IndexEvent; import org.dependencytrack.model.Cwe; @@ -51,6 +51,7 @@ import org.dependencytrack.parser.github.graphql.model.GitHubVulnerability; import org.dependencytrack.parser.github.graphql.model.PageableList; import org.dependencytrack.persistence.QueryManager; +import org.json.JSONObject; import java.io.IOException; import java.io.StringWriter; @@ -97,7 +98,11 @@ public void inform(final Event e) { if (this.accessToken != null) { final long start = System.currentTimeMillis(); LOGGER.info("Starting GitHub Advisory mirroring task"); - retrieveAdvisories(null); + try { + retrieveAdvisories(null); + } catch (IOException ex) { + handleRequestException(LOGGER, ex); + } final long end = System.currentTimeMillis(); LOGGER.info("GitHub Advisory mirroring complete"); LOGGER.info("Time spent (total): " + (end - start) + "ms"); @@ -123,23 +128,28 @@ private String generateQueryTemplate(final String advisoriesEndCursor) { } } - private void retrieveAdvisories(final String advisoriesEndCursor) { + private void retrieveAdvisories(final String advisoriesEndCursor) throws IOException { final String queryTemplate = generateQueryTemplate(advisoriesEndCursor); - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); - final HttpResponse response = ui.post(GITHUB_GRAPHQL_URL) - .header("Authorization", "bearer " + accessToken) - .header("content-type", "application/json") - .header("accept", "application/json") - .body(new JSONObject().put("query", queryTemplate)) - .asJson(); - if (response.getStatus() < 200 || response.getStatus() > 299) { + HttpPost request = new HttpPost(GITHUB_GRAPHQL_URL); + request.addHeader("Authorization", "bearer " + accessToken); + request.addHeader("content-type", "application/json"); + request.addHeader("accept", "application/json"); + org.json.JSONObject jsonBody = new org.json.JSONObject(); + jsonBody.put("query", queryTemplate); + StringEntity stringEntity = new StringEntity(jsonBody.toString()); + request.setEntity(stringEntity); + CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + + if (response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() > 299) { LOGGER.error("An error was encountered retrieving advisories"); - LOGGER.error("HTTP Status : " + response.getStatus() + " " + response.getStatusText()); + LOGGER.error("HTTP Status : " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); LOGGER.debug(queryTemplate); mirroredWithoutErrors = false; } else { GitHubSecurityAdvisoryParser parser = new GitHubSecurityAdvisoryParser(); - final PageableList pageableList = parser.parse(response.getBody().getObject()); + String responseString = EntityUtils.toString(response.getEntity()); + JSONObject jsonObject = new JSONObject(responseString); + final PageableList pageableList = parser.parse(jsonObject); updateDatasource(pageableList.getAdvisories()); if (pageableList.isHasNextPage()) { retrieveAdvisories(pageableList.getEndCursor()); @@ -346,4 +356,14 @@ private PackageURL generatePurlFromGitHubVulnerability(final GitHubVulnerability return null; } + protected void handleRequestException(final Logger logger, final Exception e) { + logger.error("Request failure", e); + Notification.dispatch(new Notification() + .scope(NotificationScope.SYSTEM) + .group(NotificationGroup.ANALYZER) + .title(NotificationConstants.Title.ANALYZER_ERROR) + .content("An error occurred while communicating with a vulnerability intelligence source. Check log for details. " + e.getMessage()) + .level(NotificationLevel.ERROR) + ); + } } diff --git a/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java index 7b46e2eb87..bc881f4f47 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java @@ -20,17 +20,9 @@ import alpine.common.logging.Logger; import com.github.packageurl.PackageURL; -import kong.unirest.GetRequest; -import kong.unirest.HttpRequest; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.UnirestException; -import kong.unirest.UnirestInstance; import org.apache.http.HttpStatus; -import org.apache.http.StatusLine; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.util.EntityUtils; -import org.dependencytrack.common.UnirestFactory; import org.dependencytrack.model.Component; import org.dependencytrack.model.RepositoryType; import org.json.JSONObject; diff --git a/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java index d7e0553bab..2677519da3 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java @@ -20,11 +20,9 @@ import alpine.common.logging.Logger; import com.github.packageurl.PackageURL; -import kong.unirest.UnirestInstance; import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.util.EntityUtils; -import org.dependencytrack.common.UnirestFactory; import org.dependencytrack.model.Component; import org.dependencytrack.model.RepositoryType; import org.json.JSONObject; diff --git a/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java index 8c439802c9..40ad1cc90b 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java @@ -20,7 +20,6 @@ import alpine.common.logging.Logger; import com.github.packageurl.PackageURL; -import kong.unirest.UnirestException; import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.util.EntityUtils; @@ -101,7 +100,7 @@ public MetaModel analyze(final Component component) { } else { handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component); } - } catch (UnirestException | IOException e) { + } catch (IOException e) { handleRequestException(LOGGER, e); } } diff --git a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java index d1f9bb6b43..8d363ddebe 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java @@ -34,17 +34,17 @@ import io.github.resilience4j.retry.Retry; import io.github.resilience4j.retry.RetryConfig; import io.github.resilience4j.retry.RetryRegistry; -import kong.unirest.GetRequest; -import kong.unirest.HttpResponse; -import kong.unirest.HttpStatus; -import kong.unirest.JsonNode; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.apache.http.HttpHeaders; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.util.EntityUtils; import org.dependencytrack.common.ConfigKey; -import org.dependencytrack.common.UnirestFactory; +import org.dependencytrack.common.HttpClientPool; import org.dependencytrack.event.IndexEvent; import org.dependencytrack.event.SnykAnalysisEvent; import org.dependencytrack.model.Component; @@ -58,7 +58,10 @@ import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.util.NotificationUtil; import org.dependencytrack.util.RoundRobinAccessor; +import org.json.JSONArray; +import org.json.JSONObject; +import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.Duration; @@ -99,7 +102,7 @@ public class SnykAnalysisTask extends BaseComponentAnalyzerTask implements Cache private static final ExecutorService EXECUTOR; static { - final RetryRegistry retryRegistry = RetryRegistry.of(RetryConfig.>custom() + final RetryRegistry retryRegistry = RetryRegistry.of(RetryConfig.custom() .intervalFunction(ofExponentialBackoff( Duration.ofSeconds(Config.getInstance().getPropertyAsInt(ConfigKey.SNYK_RETRY_EXPONENTIAL_BACKOFF_INITIAL_DURATION_SECONDS)), Config.getInstance().getPropertyAsInt(ConfigKey.SNYK_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER), @@ -107,7 +110,7 @@ public class SnykAnalysisTask extends BaseComponentAnalyzerTask implements Cache )) .maxAttempts(Config.getInstance().getPropertyAsInt(ConfigKey.SNYK_RETRY_MAX_ATTEMPTS)) .retryOnException(exception -> false) - .retryOnResult(response -> HttpStatus.TOO_MANY_REQUESTS == response.getStatus()) + .retryOnResult(response -> 429 == response.getStatusLine().getStatusCode()) .build()); RETRY = retryRegistry.retry("snyk-api"); RETRY.getEventPublisher() @@ -294,30 +297,39 @@ public void applyAnalysisFromCache(final Component component) { private void analyzeComponent(final Component component) { final String encodedPurl = URLEncoder.encode(component.getPurl().getCoordinates(), StandardCharsets.UTF_8); final String requestUrl = "%s/rest/orgs/%s/packages/%s/issues?version=%s".formatted(apiBaseUrl, apiOrgId, encodedPurl, apiVersion); - final GetRequest request = UnirestFactory.getUnirestInstance().get(requestUrl) - .header(HttpHeaders.AUTHORIZATION, "token " + apiTokenSupplier.get()) - .header(HttpHeaders.ACCEPT, "application/vnd.api+json"); - - final HttpResponse response = RETRY.executeSupplier(request::asJson); - apiVersionSunset = StringUtils.trimToNull(response.getHeaders().getFirst("Sunset")); - if (response.isSuccess()) { - handle(component, response.getBody().getObject()); - } else if (response.getBody() != null) { - final List errors = new SnykParser().parseErrors(response.getBody().getObject()); - if (!errors.isEmpty()) { - LOGGER.error("Analysis of component %s failed with HTTP status %d: \n%s" - .formatted(component.getPurl(), response.getStatus(), errors.stream() - .map(error -> " - %s: %s (%s)".formatted(error.title(), error.detail(), error.code())) - .collect(Collectors.joining("\n")))); + + try { + HttpUriRequest request = new HttpGet(requestUrl); + request.addHeader(HttpHeaders.AUTHORIZATION, "token " + apiTokenSupplier.get()); + request.addHeader(HttpHeaders.ACCEPT, "application/vnd.api+json"); + CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + String stringResponse = EntityUtils.toString(response.getEntity()); + org.json.JSONObject jsonResponse = new org.json.JSONObject(stringResponse); + apiVersionSunset = StringUtils.trimToNull(response.getFirstHeader("Sunset").getValue()); + if (response.getStatusLine().getStatusCode()>= org.apache.http.HttpStatus.SC_OK && response.getStatusLine().getStatusCode() errors = new SnykParser().parseErrors(jsonResponse); + if (!errors.isEmpty()) { + LOGGER.error("Analysis of component %s failed with HTTP status %d: \n%s" + .formatted(component.getPurl(), response.getStatusLine().getStatusCode(), errors.stream() + .map(error -> " - %s: %s (%s)".formatted(error.title(), error.detail(), error.code())) + .collect(Collectors.joining("\n")))); + } else { + handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); + } } else { - handleUnexpectedHttpResponse(LOGGER, request.getUrl(), response.getStatus(), response.getStatusText()); + handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } - } else { - handleUnexpectedHttpResponse(LOGGER, request.getUrl(), response.getStatus(), response.getStatusText()); + + }catch (IOException ex){ + handleRequestException(LOGGER, ex); } } - private void handle(final Component component, final JSONObject object) { + private void handle(final Component component, final org.json.JSONObject object) { try (QueryManager qm = new QueryManager()) { String purl = null; final JSONObject metaInfo = object.optJSONObject("meta"); diff --git a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java index c33a120ef9..a2157980f7 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java @@ -23,7 +23,9 @@ import alpine.event.framework.Subscriber; import alpine.model.ConfigProperty; import alpine.security.crypto.DataEncryption; -import org.dependencytrack.common.UnirestFactory; +import kong.unirest.Unirest; +import kong.unirest.UnirestInstance; +import org.dependencytrack.common.ManagedHttpClientFactory; import org.dependencytrack.event.VulnDbAnalysisEvent; import org.dependencytrack.model.Component; import org.dependencytrack.model.ConfigPropertyConstants; @@ -114,7 +116,9 @@ public boolean isCapable(final Component component) { * @param components a list of Components */ public void analyze(final List components) { - final VulnDbApi api = new VulnDbApi(this.apiConsumerKey, this.apiConsumerSecret, UnirestFactory.getUnirestInstance()); + final UnirestInstance unirestInstance = Unirest.primaryInstance(); + unirestInstance.config().httpClient(ManagedHttpClientFactory.newManagedHttpClient().getHttpClient()); + final VulnDbApi api = new VulnDbApi(this.apiConsumerKey, this.apiConsumerSecret, unirestInstance); for (final Component component: components) { if (!component.isInternal() && isCapable(component) && !isCacheCurrent(Vulnerability.Source.VULNDB, TARGET_HOST, component.getCpe())) { diff --git a/src/test/java/org/dependencytrack/parser/snyk/SnykParserTest.java b/src/test/java/org/dependencytrack/parser/snyk/SnykParserTest.java index 5d855dc4e9..104dccbcec 100644 --- a/src/test/java/org/dependencytrack/parser/snyk/SnykParserTest.java +++ b/src/test/java/org/dependencytrack/parser/snyk/SnykParserTest.java @@ -19,8 +19,8 @@ package org.dependencytrack.parser.snyk; import alpine.model.IConfigProperty; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; +import org.json.JSONArray; +import org.json.JSONObject; import org.dependencytrack.PersistenceCapableTest; import org.dependencytrack.model.VulnerableSoftware; import org.dependencytrack.parser.snyk.model.SnykError; From 2c99bf22fde7be139d93af08a6c5ca08750789e3 Mon Sep 17 00:00:00 2001 From: mehab Date: Fri, 20 Jan 2023 18:41:43 +0000 Subject: [PATCH 04/31] defect dojo and oss index changed Signed-off-by: mehab --- .../defectdojo/DefectDojoClient.java | 178 ++++++++++-------- .../parser/ossindex/OssIndexParser.java | 37 ++-- .../tasks/scanners/OssIndexAnalysisTask.java | 78 ++++---- .../tasks/scanners/SnykAnalysisTask.java | 57 +++--- 4 files changed, 207 insertions(+), 143 deletions(-) diff --git a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java index 720aaad9e0..f552372956 100644 --- a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java +++ b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java @@ -19,19 +19,29 @@ package org.dependencytrack.integrations.defectdojo; import alpine.common.logging.Logger; -import kong.unirest.UnirestInstance; -import kong.unirest.HttpRequestWithBody; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; -import org.dependencytrack.common.UnirestFactory; +import org.json.JSONArray; +import org.json.JSONObject; +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.dependencytrack.common.HttpClientPool; +import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; +import java.util.List; public class DefectDojoClient { @@ -40,36 +50,44 @@ public class DefectDojoClient { private final DefectDojoUploader uploader; private final URL baseURL; - public DefectDojoClient(final DefectDojoUploader uploader, final URL baseURL) { + public DefectDojoClient(final DefectDojoUploader uploader, final URL baseURL) { this.uploader = uploader; this.baseURL = baseURL; } public void uploadDependencyTrackFindings(final String token, final String engagementId, final InputStream findingsJson) { LOGGER.debug("Uploading Dependency-Track findings to DefectDojo"); - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); - final HttpRequestWithBody request = ui.post(baseURL + "/api/v2/import-scan/"); + HttpPost request = new HttpPost(baseURL + "/api/v2/import-scan/"); + request.addHeader("accept", "application/json"); + request.addHeader("Authorization", "Token " + token); + List nameValuePairs = new ArrayList<>(); + nameValuePairs.add(new BasicNameValuePair("engagement", engagementId)); + nameValuePairs.add(new BasicNameValuePair("scan_type", "Dependency Track Finding Packaging Format (FPF) Export")); + nameValuePairs.add(new BasicNameValuePair("verified", "true")); + nameValuePairs.add(new BasicNameValuePair("active", "true")); + nameValuePairs.add(new BasicNameValuePair("minimum_severity", "Info")); + nameValuePairs.add(new BasicNameValuePair("close_old_findings", "true")); + nameValuePairs.add(new BasicNameValuePair("push_to_jira", "false")); + nameValuePairs.add(new BasicNameValuePair("scan_date", DATE_FORMAT.format(new Date()))); - final HttpResponse response = request - .header("accept", "application/json") - .header("Authorization", "Token " + token) - .field("file", findingsJson, "findings.json") - .field("engagement", engagementId) - .field("scan_type", "Dependency Track Finding Packaging Format (FPF) Export") - .field("verified", "true") - .field("active", "true") - .field("minimum_severity", "Info") - .field("close_old_findings", "true") - .field("push_to_jira", "false") - .field("scan_date", DATE_FORMAT.format(new Date())) - .asString(); - if (response.getStatus() == 201) { - LOGGER.debug("Successfully uploaded findings to DefectDojo"); - } else { - LOGGER.warn("DefectDojo Client did not receive expected response while attempting to upload " - + "Dependency-Track findings. HTTP response code: " - + response.getStatus() + " - " + response.getStatusText()); - uploader.handleUnexpectedHttpResponse(LOGGER, request.getUrl(), response.getStatus(), response.getStatusText()); + HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addBinaryBody("file", findingsJson, ContentType.DEFAULT_BINARY, "findings.json") + .build(); + request.setEntity(data); + request.setEntity(new UrlEncodedFormEntity(nameValuePairs, StandardCharsets.UTF_8)); + try { + CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + if (response.getStatusLine().getStatusCode() == 201) { + LOGGER.debug("Successfully uploaded findings to DefectDojo"); + } else { + LOGGER.warn("DefectDojo Client did not receive expected response while attempting to upload " + + "Dependency-Track findings. HTTP response code: " + + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); + uploader.handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); + } + } catch (IOException ex) { + LOGGER.error("Error while sending request from upload DT findings defectDojo Client" + ex.getMessage()); + LOGGER.error("Error while sending request from upload DT findings defectDojo Client" + ex.getStackTrace()); } } @@ -77,29 +95,29 @@ public void uploadDependencyTrackFindings(final String token, final String engag public ArrayList getDojoTestIds(final String token, final String eid) { LOGGER.debug("Pulling DefectDojo Tests API ..."); String tests_uri = "/api/v2/tests/"; - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); LOGGER.debug("Make the first pagination call"); - HttpResponse response = ui.get(baseURL + tests_uri + "?limit=100&engagement=" + eid) - .header("accept", "application/json") - .header("Authorization", "Token " + token) - .asJson(); - if (response.getStatus() == 200) { - if (response.getBody() != null && response.getBody().getObject() != null) { - JsonNode root = response.getBody(); - JSONObject dojoObj = root.getObject(); + HttpGet request = new HttpGet(baseURL + tests_uri + "?limit=100&engagement=" + eid); + request.addHeader("accept", "application/json"); + request.addHeader("Authorization", "Token " + token); + try{ + CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + if (response.getStatusLine().getStatusCode() == 200) { + if (response.getEntity()!=null) { + String stringResponse = EntityUtils.toString(response.getEntity()); + JSONObject dojoObj = new JSONObject(stringResponse); JSONArray dojoArray = dojoObj.getJSONArray("results"); ArrayList dojoTests = jsonToList(dojoArray); String nextUrl = ""; - while (dojoObj.get("next") != null ) { + while (dojoObj.get("next") != null) { nextUrl = dojoObj.get("next").toString(); LOGGER.debug("Making the subsequent pagination call on " + nextUrl); - response = ui.get(nextUrl) - .header("accept", "application/json") - .header("Authorization", "Token " + token) - .asJson(); + request = new HttpGet(nextUrl); + request.addHeader("accept", "application/json"); + request.addHeader("Authorization", "Token " + token); + response = HttpClientPool.getClient().execute(request); nextUrl = dojoObj.get("next").toString(); - root = response.getBody(); - dojoObj = root.getObject(); + stringResponse = EntityUtils.toString(response.getEntity()); + dojoObj = new JSONObject(stringResponse); dojoArray = dojoObj.getJSONArray("results"); dojoTests.addAll(jsonToList(dojoArray)); } @@ -108,18 +126,20 @@ public ArrayList getDojoTestIds(final String token, final String eid) { } } else { LOGGER.warn("DefectDojo Client did not receive expected response while attempting to retrieve tests list " - + response.getStatus() + " - " + response.getBody()); + + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); + }}catch (IOException ex){ + LOGGER.error("Error while getting dojo test id's"+ex.getMessage()); } - return null; + return new ArrayList<>(); } // Given the engagement id and scan type, search for existing test id - public String getDojoTestId(final String engagementID, final ArrayList dojoTests) { + public String getDojoTestId(final String engagementID, final ArrayList dojoTests) { for (int i = 0; i < dojoTests.size(); i++) { String s = dojoTests.get(i).toString(); JSONObject dojoTest = new JSONObject(s); - if (dojoTest.get("engagement").toString().equals(engagementID) && - dojoTest.get("scan_type").toString().equals("Dependency Track Finding Packaging Format (FPF) Export")) { + if (dojoTest.get("engagement").toString().equals(engagementID) && + dojoTest.get("scan_type").toString().equals("Dependency Track Finding Packaging Format (FPF) Export")) { return dojoTest.get("id").toString(); } } @@ -140,32 +160,40 @@ public ArrayList jsonToList(final JSONArray jsonArray) { /* * A Reimport will reuse (overwrite) the existing test, instead of create a new test. * The Successfully reimport will also increase the reimport counter by 1. - */ + */ public void reimportDependencyTrackFindings(final String token, final String engagementId, final InputStream findingsJson, final String testId) { LOGGER.debug("Re-reimport Dependency-Track findings to DefectDojo per Engagement"); - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); - final HttpRequestWithBody request = ui.post(baseURL + "/api/v2/reimport-scan/"); - final HttpResponse response = request - .header("accept", "application/json") - .header("Authorization", "Token " + token) - .field("file", findingsJson, "findings.json") - .field("engagement", engagementId) - .field("scan_type", "Dependency Track Finding Packaging Format (FPF) Export") - .field("verified", "true") - .field("active", "true") - .field("minimum_severity", "Info") - .field("close_old_findings", "true") - .field("push_to_jira", "false") - .field("test", testId) - .field("scan_date", DATE_FORMAT.format(new Date())) - .asString(); - if (response.getStatus() == 201) { - LOGGER.debug("Successfully reimport findings to DefectDojo"); - } else { - LOGGER.warn("DefectDojo Client did not receive expected response while attempting to reimport" - + "Dependency-Track findings. HTTP response code: " - + response.getStatus() + " - " + response.getStatusText()); - uploader.handleUnexpectedHttpResponse(LOGGER, request.getUrl(), response.getStatus(), response.getBody()); + HttpPost request = new HttpPost(baseURL + "/api/v2/reimport-scan/"); + request.addHeader("accept", "application/json"); + request.addHeader("Authorization", "Token " + token); + List nameValuePairs = new ArrayList<>(); + nameValuePairs.add(new BasicNameValuePair("engagement", engagementId)); + nameValuePairs.add(new BasicNameValuePair("scan_type", "Dependency Track Finding Packaging Format (FPF) Export")); + nameValuePairs.add(new BasicNameValuePair("verified", "true")); + nameValuePairs.add(new BasicNameValuePair("active", "true")); + nameValuePairs.add(new BasicNameValuePair("minimum_severity", "Info")); + nameValuePairs.add(new BasicNameValuePair("close_old_findings", "true")); + nameValuePairs.add(new BasicNameValuePair("push_to_jira", "false")); + nameValuePairs.add(new BasicNameValuePair("test", testId)); + nameValuePairs.add(new BasicNameValuePair("scan_date", DATE_FORMAT.format(new Date()))); + request.setEntity(new UrlEncodedFormEntity(nameValuePairs, StandardCharsets.UTF_8)); + HttpEntity fileData = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addBinaryBody("file", findingsJson, ContentType.DEFAULT_BINARY, "findings.json") + .build(); + request.setEntity(fileData); + try{ + CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + if (response.getStatusLine().getStatusCode() == 201) { + LOGGER.debug("Successfully reimport findings to DefectDojo"); + } else { + LOGGER.warn("DefectDojo Client did not receive expected response while attempting to reimport" + + "Dependency-Track findings. HTTP response code: " + + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); + uploader.handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); + } + }catch (IOException ex){ + LOGGER.error("Error while sending request from reimport DT findings defectDojo Client" + ex.getMessage()); + LOGGER.error("Error while sending request from reimport DT findings defectDojo Client" + ex.getStackTrace()); } } diff --git a/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java b/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java index 4e729b9934..88c877d6a1 100644 --- a/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java +++ b/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java @@ -19,9 +19,10 @@ package org.dependencytrack.parser.ossindex; import alpine.common.logging.Logger; -import kong.unirest.JsonNode; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; +import com.fasterxml.jackson.databind.JsonNode; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; import org.dependencytrack.parser.ossindex.model.ComponentReport; import org.dependencytrack.parser.ossindex.model.ComponentReportVulnerability; @@ -41,17 +42,31 @@ public class OssIndexParser { /** * Parses the JSON response from Sonatype OSS Index * - * @param jsonNode the JSON node to parse + * @param responseString the JSON node to parse * @return an ComponentReport object */ - public List parse(final JsonNode jsonNode) { - LOGGER.debug("Parsing JSON node"); + public List parse(final String responseString) { + LOGGER.debug("Parsing JSON response"); + JSONArray arr = null; + JSONObject jsonObject = null; + try { + jsonObject = new JSONObject(responseString); + } catch (JSONException ex) { + arr = new JSONArray(responseString); + } catch (Exception ex) { + LOGGER.error("failed in parsing response"); + } + if (jsonObject != null) { + arr = new JSONArray(); + arr.put(jsonObject); + } final List componentReports = new ArrayList<>(); - final JSONArray resultArray = jsonNode.getArray(); - for (int i = 0; i < resultArray.length(); i++) { - final JSONObject object = resultArray.getJSONObject(i); - final ComponentReport componentReport = parse(object); - componentReports.add(componentReport); + if (arr != null) { + for (int i = 0; i < arr.length(); i++) { + final JSONObject object = arr.getJSONObject(i); + final ComponentReport componentReport = parse(object); + componentReports.add(componentReport); + } } return componentReports; } diff --git a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java index 8f4ba3a50b..41836705f8 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java @@ -33,17 +33,18 @@ import io.github.resilience4j.retry.Retry; import io.github.resilience4j.retry.RetryConfig; import io.github.resilience4j.retry.RetryRegistry; -import kong.unirest.HttpRequestWithBody; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.UnirestException; -import kong.unirest.UnirestInstance; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.util.EntityUtils; +import org.dependencytrack.common.HttpClientPool; +import org.dependencytrack.util.HttpUtil; import org.json.JSONObject; import org.apache.commons.collections4.CollectionUtils; import org.apache.http.HttpHeaders; import org.dependencytrack.common.ConfigKey; import org.dependencytrack.common.ManagedHttpClientFactory; -import org.dependencytrack.common.UnirestFactory; import org.dependencytrack.event.ComponentMetricsUpdateEvent; import org.dependencytrack.event.OssIndexAnalysisEvent; import org.dependencytrack.model.Component; @@ -63,6 +64,7 @@ import us.springett.cvss.CvssV3; import us.springett.cvss.Score; +import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; @@ -111,7 +113,7 @@ public class OssIndexAnalysisTask extends BaseComponentAnalyzerTask implements C public AnalyzerIdentity getAnalyzerIdentity() { return AnalyzerIdentity.OSSINDEX_ANALYZER; } - + /** * {@inheritDoc} */ @@ -142,7 +144,7 @@ public void inform(final Event e) { } } } - final OssIndexAnalysisEvent event = (OssIndexAnalysisEvent)e; + final OssIndexAnalysisEvent event = (OssIndexAnalysisEvent) e; LOGGER.info("Starting Sonatype OSS Index analysis task"); vulnerabilityAnalysisLevel = event.getVulnerabilityAnalysisLevel(); if (event.getComponents().size() > 0) { @@ -185,6 +187,7 @@ public void applyAnalysisFromCache(final Component component) { /** * Analyzes a list of Components. + * * @param components a list of Components */ public void analyze(final List components) { @@ -202,12 +205,9 @@ public void analyze(final List components) { if (!CollectionUtils.isEmpty(coordinates)) { final JSONObject json = new JSONObject(); json.put("coordinates", coordinates); - try { - final List report = ossIndexRetryer.executeSupplier(() -> submit(json)); - processResults(report, paginatedList); - } catch (UnirestException e) { - handleRequestException(LOGGER, e); - } + final List report = ossIndexRetryer.executeSupplier(() -> submit(json)); + processResults(report, paginatedList); + LOGGER.info("Analyzing " + coordinates.size() + " component(s)"); } paginatedComponents.nextPage(); @@ -219,15 +219,16 @@ public void analyze(final List components) { * HTTP POST is used and PackageURL is specified that contains qualifiers (and possibly a subpath). * Therefore, this method will return a String representation of a PackageURL without qualifier * or subpath. - * + *

* Additionally, as of October 2021, versions prefixed with "v" (as commonly done in the Go and PHP ecosystems) * are triggering a bug in OSS Index that causes all vulnerabilities for the given component to be returned, * not just the ones for the requested version: https://github.com/OSSIndex/vulns/issues/129#issuecomment-740666614 * As a result, this method will remove "v" prefixes from versions. - * + *

* This method should be removed at a future date when OSSIndex resolves the issues. - * + *

* TODO: Delete this method and workaround for OSSIndex bugs once Sonatype resolves them. + * * @since 3.4.0 */ @Deprecated @@ -249,29 +250,36 @@ private static String minimizePurl(final PackageURL purl) { /** * Submits the payload to the Sonatype OSS Index service */ - private List submit(final JSONObject payload) throws UnirestException { - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); - final HttpRequestWithBody request = ui.post(API_BASE_URL) - .header(HttpHeaders.ACCEPT, "application/json") - .header(HttpHeaders.CONTENT_TYPE, "application/json") - .header(HttpHeaders.USER_AGENT, ManagedHttpClientFactory.getUserAgent()); + private List submit(final JSONObject payload) { + HttpPost request = new HttpPost(API_BASE_URL); + request.addHeader(HttpHeaders.ACCEPT, "application/json"); + request.addHeader(HttpHeaders.CONTENT_TYPE, "application/json"); + request.addHeader(HttpHeaders.USER_AGENT, ManagedHttpClientFactory.getUserAgent()); if (apiUsername != null && apiToken != null) { - request.basicAuth(apiUsername, apiToken); + request.addHeader("Authorization", HttpUtil.basicAuthHeaderValue(apiUsername, apiToken)); } - final HttpResponse jsonResponse = request.body(payload).asJson(); - if (jsonResponse.getStatus() == 200) { - final OssIndexParser parser = new OssIndexParser(); - return parser.parse(jsonResponse.getBody()); - } else { - handleUnexpectedHttpResponse(LOGGER, API_BASE_URL, jsonResponse.getStatus(), jsonResponse.getStatusText()); + try { + final CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + HttpEntity responseEntity = response.getEntity(); + String responseString = EntityUtils.toString(responseEntity); + response.setEntity(new StringEntity(payload.toString())); + if (response.getStatusLine().getStatusCode() == 200) { + final OssIndexParser parser = new OssIndexParser(); + return parser.parse(responseString); + } else { + handleUnexpectedHttpResponse(LOGGER, API_BASE_URL, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); + } + return new ArrayList<>(); + } catch (IOException ex) { + handleRequestException(LOGGER, ex); + return null; } - return new ArrayList<>(); } private void processResults(final List report, final List componentsScanned) { try (QueryManager qm = new QueryManager()) { - for (final ComponentReport componentReport: report) { - for (final Component c: componentsScanned) { + for (final ComponentReport componentReport : report) { + for (final Component c : componentsScanned) { //final String componentPurl = component.getPurl().canonicalize(); // todo: put this back when minimizePurl() is removed final String componentPurl = minimizePurl(c.getPurl()); final PackageURL sonatypePurl = oldPurlResolver(componentReport.getCoordinates()); @@ -283,7 +291,7 @@ private void processResults(final List report, final Listcustom() + final RetryRegistry retryRegistry = RetryRegistry.of(RetryConfig.custom() .intervalFunction(ofExponentialBackoff( Duration.ofSeconds(Config.getInstance().getPropertyAsInt(ConfigKey.SNYK_RETRY_EXPONENTIAL_BACKOFF_INITIAL_DURATION_SECONDS)), Config.getInstance().getPropertyAsInt(ConfigKey.SNYK_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER), @@ -297,20 +297,34 @@ public void applyAnalysisFromCache(final Component component) { private void analyzeComponent(final Component component) { final String encodedPurl = URLEncoder.encode(component.getPurl().getCoordinates(), StandardCharsets.UTF_8); final String requestUrl = "%s/rest/orgs/%s/packages/%s/issues?version=%s".formatted(apiBaseUrl, apiOrgId, encodedPurl, apiVersion); + final HttpUriRequest request = new HttpGet(requestUrl); + request.setHeader(HttpHeaders.USER_AGENT, ManagedHttpClientFactory.getUserAgent()); + request.setHeader(HttpHeaders.AUTHORIZATION, "token " + apiTokenSupplier.get()); + request.setHeader(HttpHeaders.ACCEPT, "application/vnd.api+json"); try { - HttpUriRequest request = new HttpGet(requestUrl); - request.addHeader(HttpHeaders.AUTHORIZATION, "token " + apiTokenSupplier.get()); - request.addHeader(HttpHeaders.ACCEPT, "application/vnd.api+json"); - CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - String stringResponse = EntityUtils.toString(response.getEntity()); - org.json.JSONObject jsonResponse = new org.json.JSONObject(stringResponse); - apiVersionSunset = StringUtils.trimToNull(response.getFirstHeader("Sunset").getValue()); - if (response.getStatusLine().getStatusCode()>= org.apache.http.HttpStatus.SC_OK && response.getStatusLine().getStatusCode() errors = new SnykParser().parseErrors(jsonResponse); + final CloseableHttpResponse response = RETRY.executeSupplier(() -> { + try { + return HttpClientPool.getClient().execute(request); + } catch (IOException e) { + handleRequestException(LOGGER, e); + return null; + } + }); + Header header = response.getFirstHeader("Sunset"); + if(header!=null) { + apiVersionSunset = StringUtils.trimToNull(header.getValue()); + } + else { + apiVersionSunset = null; + } + if (response.getStatusLine().getStatusCode() >= 200 && response.getStatusLine().getStatusCode() < 300) { + String responseString = EntityUtils.toString(response.getEntity()); + org.json.JSONObject responseJson = new org.json.JSONObject(responseString); + handle(component, responseJson); + } else if (response.getEntity() != null) { + String responseString = EntityUtils.toString(response.getEntity()); + org.json.JSONObject responseJson = new org.json.JSONObject(responseString); + final List errors = new SnykParser().parseErrors(responseJson); if (!errors.isEmpty()) { LOGGER.error("Analysis of component %s failed with HTTP status %d: \n%s" .formatted(component.getPurl(), response.getStatusLine().getStatusCode(), errors.stream() @@ -322,13 +336,12 @@ private void analyzeComponent(final Component component) { } else { handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } - }catch (IOException ex){ handleRequestException(LOGGER, ex); } } - private void handle(final Component component, final org.json.JSONObject object) { + private void handle(final Component component, final JSONObject object) { try (QueryManager qm = new QueryManager()) { String purl = null; final JSONObject metaInfo = object.optJSONObject("meta"); From b1dca1d01e689d2def9727ffdb1909b502493f71 Mon Sep 17 00:00:00 2001 From: mehab Date: Mon, 23 Jan 2023 16:05:39 +0000 Subject: [PATCH 05/31] removed unirest client Signed-off-by: mehab --- pom.xml | 7 - .../common/UnirestFactory.java | 37 -- .../defectdojo/DefectDojoClient.java | 4 +- .../fortifyssc/FortifySscClient.java | 102 +++--- .../kenna/KennaDataTransformer.java | 1 - .../kenna/KennaSecurityUploader.java | 51 +-- .../model/ConfigPropertyConstants.java | 2 +- .../tasks/scanners/OssIndexAnalysisTask.java | 4 +- .../tasks/scanners/VulnDbAnalysisTask.java | 14 +- .../org/dependencytrack/util/VulnDBUtil.java | 338 ++++++++++++++++++ .../org/dependencytrack/ResourceTest.java | 3 - .../common/UnirestFactoryTest.java | 39 -- .../integration/ApiClient.java | 80 +++-- .../tasks/scanners/SnykAnalysisTaskTest.java | 6 +- 14 files changed, 479 insertions(+), 209 deletions(-) delete mode 100644 src/main/java/org/dependencytrack/common/UnirestFactory.java create mode 100644 src/main/java/org/dependencytrack/util/VulnDBUtil.java delete mode 100644 src/test/java/org/dependencytrack/common/UnirestFactoryTest.java diff --git a/pom.xml b/pom.xml index 9338f5a4bc..799076ec14 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,6 @@ 8.11.2 1.4.1 3.2.0 - 3.14.1 1.0.1 2.0.1 6.4.0 @@ -239,12 +238,6 @@ - - - com.konghq - unirest-java - ${lib.unirest.version} - com.fasterxml.woodstox woodstox-core diff --git a/src/main/java/org/dependencytrack/common/UnirestFactory.java b/src/main/java/org/dependencytrack/common/UnirestFactory.java deleted file mode 100644 index f658a87be9..0000000000 --- a/src/main/java/org/dependencytrack/common/UnirestFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) Steve Springett. All Rights Reserved. - */ -package org.dependencytrack.common; - -import kong.unirest.Unirest; -import kong.unirest.UnirestInstance; - -public final class UnirestFactory { - - private static final UnirestInstance UNIREST_INSTANCE = Unirest.primaryInstance(); - static { - UNIREST_INSTANCE.config().httpClient(ManagedHttpClientFactory.newManagedHttpClient().getHttpClient()); - } - - private UnirestFactory() { - } - - public static UnirestInstance getUnirestInstance() { - return UNIREST_INSTANCE; - } -} diff --git a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java index f552372956..96fe5ab33a 100644 --- a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java +++ b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java @@ -71,7 +71,7 @@ public void uploadDependencyTrackFindings(final String token, final String engag nameValuePairs.add(new BasicNameValuePair("scan_date", DATE_FORMAT.format(new Date()))); HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE) - .addBinaryBody("file", findingsJson, ContentType.DEFAULT_BINARY, "findings.json") + .addBinaryBody("file", findingsJson, ContentType.APPLICATION_JSON, "findings.json") .build(); request.setEntity(data); request.setEntity(new UrlEncodedFormEntity(nameValuePairs, StandardCharsets.UTF_8)); @@ -178,7 +178,7 @@ public void reimportDependencyTrackFindings(final String token, final String eng nameValuePairs.add(new BasicNameValuePair("scan_date", DATE_FORMAT.format(new Date()))); request.setEntity(new UrlEncodedFormEntity(nameValuePairs, StandardCharsets.UTF_8)); HttpEntity fileData = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE) - .addBinaryBody("file", findingsJson, ContentType.DEFAULT_BINARY, "findings.json") + .addBinaryBody("file", findingsJson, ContentType.APPLICATION_JSON, "findings.json") .build(); request.setEntity(fileData); try{ diff --git a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java index 035763e3ce..546aa6bfa1 100644 --- a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java +++ b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java @@ -19,18 +19,23 @@ package org.dependencytrack.integrations.fortifyssc; import alpine.common.logging.Logger; -import kong.unirest.HttpRequestWithBody; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.UnirestInstance; -import kong.unirest.json.JSONObject; -import org.dependencytrack.common.UnirestFactory; - +import org.json.JSONObject; +import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.util.EntityUtils; +import org.dependencytrack.common.HttpClientPool; +import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.HashMap; +import java.util.*; public class FortifySscClient { @@ -45,49 +50,54 @@ public FortifySscClient(final FortifySscUploader uploader, final URL baseURL) { public String generateOneTimeUploadToken(final String citoken) { LOGGER.debug("Generating one-time upload token"); - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); + HttpPost request = new HttpPost(baseURL + "/api/v1/fileTokens"); final JSONObject payload = new JSONObject().put("fileTokenType", "UPLOAD"); - final HttpRequestWithBody request = ui.post(baseURL + "/api/v1/fileTokens"); - final HttpResponse response = request - .header("Content-Type", "application/json") - .header("Authorization", "FortifyToken " + Base64.getEncoder().encodeToString(citoken.getBytes(StandardCharsets.UTF_8))) - .body(payload) - .asJson(); - if (response.getStatus() == 201) { - if (response.getBody() != null) { - final JSONObject root = response.getBody().getObject(); - LOGGER.debug("One-time upload token retrieved"); - return root.getJSONObject("data").getString("token"); + request.addHeader("Content-Type", "application/json"); + request.addHeader("Authorization", "FortifyToken " + Base64.getEncoder().encodeToString(citoken.getBytes(StandardCharsets.UTF_8))); + try { + request.setEntity(new StringEntity(payload.toString())); + CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED) { + if (response.getEntity() != null) { + String responseString = EntityUtils.toString(response.getEntity()); + final JSONObject root = new JSONObject(responseString); + LOGGER.debug("One-time upload token retrieved"); + return root.getJSONObject("data").getString("token"); + } + } else { + LOGGER.warn("Fortify SSC Client did not receive expected response while attempting to generate a " + + "one-time-use fileupload token. HTTP response code: " + + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); + uploader.handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } - } else { - LOGGER.warn("Fortify SSC Client did not receive expected response while attempting to generate a " - + "one-time-use fileupload token. HTTP response code: " - + response.getStatus() + " - " + response.getStatusText()); - uploader.handleUnexpectedHttpResponse(LOGGER, request.getUrl(), response.getStatus(), response.getStatusText()); + } catch (IOException ex) { + uploader.handleException(LOGGER, ex); } return null; } public void uploadDependencyTrackFindings(final String token, final String applicationVersion, final InputStream findingsJson) { - LOGGER.debug("Uploading Dependency-Track findings to Fortify SSC"); - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); - final HashMap params = new HashMap<>(); - params.put("engineType", "DEPENDENCY_TRACK"); - params.put("mat", token); - params.put("entityId", applicationVersion); - final HttpRequestWithBody request = ui.post(baseURL + "/upload/resultFileUpload.html"); - final HttpResponse response = request - .header("accept", "application/xml") - .queryString(params) - .field("files[]", findingsJson, "findings.json") - .asString(); - if (response.getStatus() == 200) { - LOGGER.debug("Successfully uploaded findings to Fortify SSC"); - } else { - LOGGER.warn("Fortify SSC Client did not receive expected response while attempting to upload " - + "Dependency-Track findings. HTTP response code: " - + response.getStatus() + " - " + response.getStatusText()); - uploader.handleUnexpectedHttpResponse(LOGGER, request.getUrl(), response.getStatus(), response.getStatusText()); + try { + LOGGER.debug("Uploading Dependency-Track findings to Fortify SSC"); + URIBuilder builder = new URIBuilder(baseURL + "/upload/resultFileUpload.html"); + builder.setParameter("engineType", "DEPENDENCY_TRACK").setParameter("mat", token).setParameter("entityId", applicationVersion); + HttpPost request = new HttpPost(builder.build()); + request.addHeader("accept", "application/xml"); + HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addBinaryBody("files[]", findingsJson, org.apache.http.entity.ContentType.APPLICATION_JSON, "findings.json") + .build(); + request.setEntity(data); + CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + LOGGER.debug("Successfully uploaded findings to Fortify SSC"); + } else { + LOGGER.warn("Fortify SSC Client did not receive expected response while attempting to upload " + + "Dependency-Track findings. HTTP response code: " + + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); + uploader.handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); + } + }catch (URISyntaxException | IOException ex){ + uploader.handleException(LOGGER, ex); } } -} +} \ No newline at end of file diff --git a/src/main/java/org/dependencytrack/integrations/kenna/KennaDataTransformer.java b/src/main/java/org/dependencytrack/integrations/kenna/KennaDataTransformer.java index c4548bf989..b6a0634f23 100644 --- a/src/main/java/org/dependencytrack/integrations/kenna/KennaDataTransformer.java +++ b/src/main/java/org/dependencytrack/integrations/kenna/KennaDataTransformer.java @@ -25,7 +25,6 @@ import org.dependencytrack.model.Severity; import org.dependencytrack.model.Tag; import org.dependencytrack.model.Vulnerability; -import org.dependencytrack.parser.common.resolver.CweResolver; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.util.DateUtil; import org.json.JSONArray; diff --git a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java index 5647a6e607..f7f2ae545a 100644 --- a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java +++ b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java @@ -21,20 +21,27 @@ import alpine.common.logging.Logger; import alpine.model.ConfigProperty; import alpine.security.crypto.DataEncryption; -import kong.unirest.ContentType; -import kong.unirest.HttpRequestWithBody; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.UnirestInstance; -import kong.unirest.json.JSONObject; -import org.dependencytrack.common.UnirestFactory; +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.dependencytrack.common.HttpClientPool; import org.dependencytrack.integrations.AbstractIntegrationPoint; import org.dependencytrack.integrations.PortfolioFindingUploader; import org.dependencytrack.model.Project; import org.dependencytrack.model.ProjectProperty; +import org.json.JSONObject; import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; import static org.dependencytrack.model.ConfigPropertyConstants.*; @@ -72,7 +79,7 @@ public boolean isEnabled() { public InputStream process() { LOGGER.debug("Processing..."); final KennaDataTransformer kdi = new KennaDataTransformer(qm); - for (final Project project: qm.getAllProjects()) { + for (final Project project : qm.getAllProjects()) { final ProjectProperty externalId = qm.getProjectProperty(project, KENNA_ENABLED.getGroupName(), ASSET_EXTID_PROPERTY); if (externalId != null && externalId.getPropertyValue() != null) { LOGGER.debug("Transforming findings for project: " + project.getUuid() + " to KDI format"); @@ -87,17 +94,21 @@ public void upload(final InputStream payload) { LOGGER.debug("Uploading payload to KennaSecurity"); final ConfigProperty tokenProperty = qm.getConfigProperty(KENNA_TOKEN.getGroupName(), KENNA_TOKEN.getPropertyName()); try { - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); final String token = DataEncryption.decryptAsString(tokenProperty.getPropertyValue()); - final HttpRequestWithBody request = ui.post(String.format(CONNECTOR_UPLOAD_URL, connectorId)); - final HttpResponse response = request - .header("X-Risk-Token", token) - .header("accept", "application/json") - .field("file", payload, ContentType.APPLICATION_JSON, "findings.json") - .field("run", "true") - .asJson(); - if (response.getStatus() == 200 && response.getBody() != null) { - final JSONObject root = response.getBody().getObject(); + HttpPost request = new HttpPost(String.format(CONNECTOR_UPLOAD_URL, connectorId)); + request.addHeader("X-Risk-Token", token); + request.addHeader("accept", "application/json"); + List nameValuePairList = new ArrayList<>(); + nameValuePairList.add(new BasicNameValuePair("run", "true")); + request.setEntity(new UrlEncodedFormEntity(nameValuePairList, StandardCharsets.UTF_8)); + HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addBinaryBody("file", payload, org.apache.http.entity.ContentType.APPLICATION_JSON, "findings.json") + .build(); + request.setEntity(data); + final CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + if (response.getStatusLine().getStatusCode() == 200 && response.getEntity() != null) { + String responseString = EntityUtils.toString(response.getEntity()); + final JSONObject root = new JSONObject(responseString); if (root.getString("success").equals("true")) { LOGGER.debug("Successfully uploaded KDI"); return; @@ -106,8 +117,8 @@ public void upload(final InputStream payload) { } else { LOGGER.warn("Kenna uploader did not receive expected response while attempting to upload " + "Dependency-Track findings. HTTP response code: " - + response.getStatus() + " - " + response.getStatusText()); - handleUnexpectedHttpResponse(LOGGER, request.getUrl(), response.getStatus(), response.getStatusText()); + + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); + handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } } catch (Exception e) { LOGGER.error("An error occurred attempting to upload findings to Kenna Security", e); diff --git a/src/main/java/org/dependencytrack/model/ConfigPropertyConstants.java b/src/main/java/org/dependencytrack/model/ConfigPropertyConstants.java index 2e9bbe3f34..1391eaf681 100644 --- a/src/main/java/org/dependencytrack/model/ConfigPropertyConstants.java +++ b/src/main/java/org/dependencytrack/model/ConfigPropertyConstants.java @@ -53,7 +53,7 @@ public enum ConfigPropertyConstants { SCANNER_SNYK_ENABLED("scanner", "snyk.enabled", "false", PropertyType.BOOLEAN, "Flag to enable/disable Snyk Vulnerability Analysis"), SCANNER_SNYK_API_TOKEN("scanner", "snyk.api.token", null, PropertyType.ENCRYPTEDSTRING, "The API token used for Snyk API authentication"), SCANNER_SNYK_ORG_ID("scanner", "snyk.org.id", null, PropertyType.STRING, "The Organization ID used for Snyk API access"), - SCANNER_SNYK_API_VERSION("scanner", "snyk.api.version", "2022-11-14", PropertyType.STRING, "Snyk API version"), + SCANNER_SNYK_API_VERSION("scanner", "snyk.api.version", "2023-01-04", PropertyType.STRING, "Snyk API version"), SCANNER_SNYK_CVSS_SOURCE("scanner", "snyk.cvss.source", "NVD", PropertyType.STRING, "Type of source to be prioritized for cvss calculation"), SCANNER_SNYK_BASE_URL("scanner", "snyk.base.url", "https://api.snyk.io", PropertyType.URL, "Base Url pointing to the hostname and path for Snyk analysis"), VULNERABILITY_SOURCE_NVD_ENABLED("vuln-source", "nvd.enabled", "true", PropertyType.BOOLEAN, "Flag to enable/disable National Vulnerability Database"), diff --git a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java index 41836705f8..2b7b657c2f 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java @@ -255,14 +255,14 @@ private List submit(final JSONObject payload) { request.addHeader(HttpHeaders.ACCEPT, "application/json"); request.addHeader(HttpHeaders.CONTENT_TYPE, "application/json"); request.addHeader(HttpHeaders.USER_AGENT, ManagedHttpClientFactory.getUserAgent()); + try { + request.setEntity(new StringEntity(payload.toString())); if (apiUsername != null && apiToken != null) { request.addHeader("Authorization", HttpUtil.basicAuthHeaderValue(apiUsername, apiToken)); } - try { final CloseableHttpResponse response = HttpClientPool.getClient().execute(request); HttpEntity responseEntity = response.getEntity(); String responseString = EntityUtils.toString(responseEntity); - response.setEntity(new StringEntity(payload.toString())); if (response.getStatusLine().getStatusCode() == 200) { final OssIndexParser parser = new OssIndexParser(); return parser.parse(responseString); diff --git a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java index a2157980f7..d59152a417 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java @@ -23,9 +23,6 @@ import alpine.event.framework.Subscriber; import alpine.model.ConfigProperty; import alpine.security.crypto.DataEncryption; -import kong.unirest.Unirest; -import kong.unirest.UnirestInstance; -import org.dependencytrack.common.ManagedHttpClientFactory; import org.dependencytrack.event.VulnDbAnalysisEvent; import org.dependencytrack.model.Component; import org.dependencytrack.model.ConfigPropertyConstants; @@ -34,7 +31,7 @@ import org.dependencytrack.parser.vulndb.ModelConverter; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.util.NotificationUtil; -import us.springett.vulndbdatamirror.client.VulnDbApi; +import org.dependencytrack.util.VulnDBUtil; import us.springett.vulndbdatamirror.parser.model.Results; import java.util.List; @@ -91,7 +88,7 @@ public void inform(final Event e) { return; } } - final VulnDbAnalysisEvent event = (VulnDbAnalysisEvent)e; + final VulnDbAnalysisEvent event = (VulnDbAnalysisEvent) e; vulnerabilityAnalysisLevel = event.getVulnerabilityAnalysisLevel(); LOGGER.info("Starting VulnDB analysis task"); if (event.getComponents().size() > 0) { @@ -113,13 +110,12 @@ public boolean isCapable(final Component component) { /** * Analyzes a list of Components. + * * @param components a list of Components */ public void analyze(final List components) { - final UnirestInstance unirestInstance = Unirest.primaryInstance(); - unirestInstance.config().httpClient(ManagedHttpClientFactory.newManagedHttpClient().getHttpClient()); - final VulnDbApi api = new VulnDbApi(this.apiConsumerKey, this.apiConsumerSecret, unirestInstance); - for (final Component component: components) { + final VulnDBUtil api = new VulnDBUtil(this.apiConsumerKey, this.apiConsumerSecret); + for (final Component component : components) { if (!component.isInternal() && isCapable(component) && !isCacheCurrent(Vulnerability.Source.VULNDB, TARGET_HOST, component.getCpe())) { int page = 1; diff --git a/src/main/java/org/dependencytrack/util/VulnDBUtil.java b/src/main/java/org/dependencytrack/util/VulnDBUtil.java new file mode 100644 index 0000000000..372209a364 --- /dev/null +++ b/src/main/java/org/dependencytrack/util/VulnDBUtil.java @@ -0,0 +1,338 @@ +package org.dependencytrack.util; + +import oauth.signpost.OAuthConsumer; +import org.json.JSONArray; +import org.json.JSONObject; +import oauth.signpost.basic.DefaultOAuthConsumer; +import oauth.signpost.exception.OAuthException; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.util.EntityUtils; +import org.dependencytrack.common.HttpClientPool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import us.springett.vulndbdatamirror.parser.model.*; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +public class VulnDBUtil { + + private final String consumerKey; + private final String consumerSecret; + + public VulnDBUtil(String consumerKey, String consumerSecret) { + this.consumerKey = consumerKey; + this.consumerSecret = consumerSecret; + } + + private static final Logger LOGGER = LoggerFactory.getLogger(VulnDBUtil.class); + + public Results getVulnerabilitiesByCpe(String cpe, int size, int page) { + String encodedCpe = cpe; + + try { + encodedCpe = URLEncoder.encode(cpe, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException var6) { + LOGGER.error("An error occurred while URL encoding a CPE", var6); + } + + return this.getResults("https://vulndb.cyberriskanalytics.com/api/v1/vulnerabilities/find_by_cpe?&cpe=" + encodedCpe, Vulnerability.class, size, page); + } + + private Results getResults(String url, Class clazz, int size, int page) { + String modifiedUrl = url.contains("?") ? url + "&" : url + "?"; + CloseableHttpResponse response = this.makeRequest(modifiedUrl + "size=" + size + "&page=" + page); + Results results; + try{ + if (response != null) { + if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { + String responseString = EntityUtils.toString(response.getEntity()); + JSONObject jsonObject = new JSONObject(responseString); + results = parse(jsonObject, clazz); + return results; + } else { + results = new Results(); + results.setErrorCondition("An unexpected response was returned from VulnDB. Request unsuccessful: " + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); + this.logHttpResponseError(response); + return results; + } + } else { + results = new Results(); + results.setErrorCondition("No response was returned from VulnDB. No further information is available."); + return results; + } + }catch (IOException ex){ + LOGGER.error("An error occurred making request: " + url); + return null; + } + } + + private CloseableHttpResponse makeRequest(String url) { + try { + OAuthConsumer consumer = new DefaultOAuthConsumer(this.consumerKey, this.consumerSecret); + String signed = consumer.sign(url); + HttpGet request = new HttpGet(signed); + request.addHeader("X-User-Agent", "VulnDB Data Mirror (https://github.com/stevespringett/vulndb-data-mirror)"); + return HttpClientPool.getClient().execute(request); + } catch (IOException | OAuthException var4) { + LOGGER.error("An error occurred making request: " + url, var4); + return null; + } + } + + private void logHttpResponseError(CloseableHttpResponse response) { + LOGGER.error("Response was not successful: " + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); + System.err.println("\n" + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); + } + + public Results parse(JSONObject jsonResponse, Class apiObject) { + LOGGER.debug("Parsing JSON node"); + Results results = new Results(); + results.setPage(jsonResponse.getInt("current_page")); + results.setTotal(jsonResponse.getInt("total_entries")); + results.setRawResults(jsonResponse.toString()); + JSONArray rso = jsonResponse.getJSONArray("results"); + if (Product.class == apiObject) { + results.setResults(this.parseProducts(rso)); + } else if (Vendor.class == apiObject) { + results.setResults(this.parseVendors(rso)); + } else if (Version.class == apiObject) { + results.setResults(this.parseVersions(rso)); + } else if (Vulnerability.class == apiObject) { + results.setResults(this.parseVulnerabilities(rso)); + } + + return results; + } + + private List parseProducts(JSONArray rso) { + List products = null; + if (rso != null) { + products = new ArrayList(); + + for(int i = 0; i < rso.length(); ++i) { + JSONObject object = rso.getJSONObject(i); + Product product = new Product(); + product.setId(object.getInt("id")); + product.setName(StringUtils.trimToNull(object.optString("name", (String)null))); + product.setVersions(this.parseVersions(object.optJSONArray("versions"))); + products.add(product); + } + } + + return products; + } + + private List parseVendors(JSONArray rso) { + List vendors = null; + if (rso != null) { + vendors = new ArrayList(); + + for(int i = 0; i < rso.length(); ++i) { + JSONObject object = rso.getJSONObject(i); + if (object.has("vendor")) { + JSONObject childObject = object.getJSONObject("vendor"); + Vendor vendor = this.parseVendor(childObject); + vendors.add(vendor); + } else { + Vendor vendor = this.parseVendor(object); + vendors.add(vendor); + } + } + } + + return vendors; + } + + private Vendor parseVendor(JSONObject object) { + Vendor vendor = new Vendor(); + vendor.setId(object.getInt("id")); + vendor.setName(StringUtils.trimToNull(object.optString("name", (String)null))); + vendor.setShortName(StringUtils.trimToNull(object.optString("short_name", (String)null))); + vendor.setVendorUrl(StringUtils.trimToNull(object.optString("vendor_url", (String)null))); + vendor.setProducts(this.parseProducts(object.optJSONArray("products"))); + return vendor; + } + + private List parseVersions(JSONArray rso) { + List versions = null; + if (rso != null) { + versions = new ArrayList(); + + for(int i = 0; i < rso.length(); ++i) { + JSONObject object = rso.getJSONObject(i); + Version version = new Version(); + version.setId(object.getInt("id")); + version.setName(StringUtils.trimToNull(object.optString("name", (String)null))); + version.setAffected(object.optBoolean("affected", false)); + version.setCpes(this.parseCpes(object.optJSONArray("cpe"))); + versions.add(version); + } + } + + return versions; + } + + private List parseCpes(JSONArray rso) { + List cpes = null; + if (rso != null) { + cpes = new ArrayList(); + + for(int i = 0; i < rso.length(); ++i) { + JSONObject object = rso.getJSONObject(i); + CPE cpe = new CPE(); + cpe.setCpe(StringUtils.trimToNull(object.optString("cpe", (String)null))); + cpe.setType(StringUtils.trimToNull(object.optString("type", (String)null))); + cpes.add(cpe); + } + } + + return cpes; + } + + private List parseVulnerabilities(JSONArray rso) { + List vulnerabilities = null; + if (rso != null) { + vulnerabilities = new ArrayList(); + + for(int i = 0; i < rso.length(); ++i) { + JSONObject object = rso.getJSONObject(i); + Vulnerability vulnerability = new Vulnerability(); + vulnerability.setId(object.getInt("vulndb_id")); + vulnerability.setTitle(StringUtils.trimToNull(object.optString("title", (String)null))); + vulnerability.setDisclosureDate(StringUtils.trimToNull(object.optString("disclosure_date", (String)null))); + vulnerability.setDiscoveryDate(StringUtils.trimToNull(object.optString("discovery_date", (String)null))); + vulnerability.setExploitPublishDate(StringUtils.trimToNull(object.optString("exploit_publish_date", (String)null))); + vulnerability.setKeywords(StringUtils.trimToNull(object.optString("keywords", (String)null))); + vulnerability.setShortDescription(StringUtils.trimToNull(object.optString("short_description", (String)null))); + vulnerability.setDescription(StringUtils.trimToNull(object.optString("description", (String)null))); + vulnerability.setSolution(StringUtils.trimToNull(object.optString("solution", (String)null))); + vulnerability.setManualNotes(StringUtils.trimToNull(object.optString("manual_notes", (String)null))); + vulnerability.setTechnicalDescription(StringUtils.trimToNull(object.optString("t_description", (String)null))); + vulnerability.setSolutionDate(StringUtils.trimToNull(object.optString("solution_date", (String)null))); + vulnerability.setVendorInformedDate(StringUtils.trimToNull(object.optString("vendor_informed_date", (String)null))); + vulnerability.setVendorAckDate(StringUtils.trimToNull(object.optString("vendor_ack_date", (String)null))); + vulnerability.setThirdPartySolutionDate(StringUtils.trimToNull(object.optString("third_party_solution_date", (String)null))); + JSONArray classifications = object.optJSONArray("classifications"); + if (classifications != null) { + for(int j = 0; j < classifications.length(); ++j) { + JSONObject jso = classifications.getJSONObject(j); + Classification classification = new Classification(); + classification.setId(jso.getInt("id")); + classification.setName(StringUtils.trimToNull(jso.optString("name", (String)null))); + classification.setLongname(StringUtils.trimToNull(jso.optString("longname", (String)null))); + classification.setDescription(StringUtils.trimToNull(jso.optString("description", (String)null))); + classification.setMediumtext(StringUtils.trimToNull(jso.optString("mediumtext", (String)null))); + vulnerability.addClassifications(classification); + } + } + + JSONArray authors = object.optJSONArray("authors"); + if (authors != null) { + for(int j = 0; j < authors.length(); ++j) { + JSONObject jso = authors.getJSONObject(j); + Author author = new Author(); + author.setId(jso.getInt("id")); + author.setName(StringUtils.trimToNull(jso.optString("name", (String)null))); + author.setCompany(StringUtils.trimToNull(jso.optString("company", (String)null))); + author.setEmail(StringUtils.trimToNull(jso.optString("email", (String)null))); + author.setCompanyUrl(StringUtils.trimToNull(jso.optString("company_url", (String)null))); + author.setCountry(StringUtils.trimToNull(jso.optString("country", (String)null))); + vulnerability.addAuthor(author); + } + } + + JSONArray extRefs = object.optJSONArray("ext_references"); + if (extRefs != null) { + for(int j = 0; j < extRefs.length(); ++j) { + JSONObject jso = extRefs.getJSONObject(j); + ExternalReference externalReference = new ExternalReference(); + externalReference.setType(StringUtils.trimToNull(jso.optString("type", (String)null))); + externalReference.setValue(StringUtils.trimToNull(jso.optString("value", (String)null))); + vulnerability.addExtReference(externalReference); + } + } + + JSONArray extTexts = object.optJSONArray("ext_texts"); + if (extTexts != null) { + for(int j = 0; j < extTexts.length(); ++j) { + JSONObject jso = extTexts.getJSONObject(j); + ExternalText externalText = new ExternalText(); + externalText.setType(StringUtils.trimToNull(jso.optString("type", (String)null))); + externalText.setValue(StringUtils.trimToNull(jso.optString("value", (String)null))); + vulnerability.addExtText(externalText); + } + } + + JSONArray cvssv2Metrics = object.optJSONArray("cvss_metrics"); + if (cvssv2Metrics != null) { + for(int j = 0; j < cvssv2Metrics.length(); ++j) { + JSONObject jso = cvssv2Metrics.getJSONObject(j); + CvssV2Metric metric = new CvssV2Metric(); + metric.setId(jso.getInt("id")); + metric.setAccessComplexity(StringUtils.trimToNull(jso.optString("access_complexity", (String)null))); + metric.setCveId(StringUtils.trimToNull(jso.optString("cve_id", (String)null))); + metric.setSource(StringUtils.trimToNull(jso.optString("source", (String)null))); + metric.setAvailabilityImpact(StringUtils.trimToNull(jso.optString("availability_impact", (String)null))); + metric.setConfidentialityImpact(StringUtils.trimToNull(jso.optString("confidentiality_impact", (String)null))); + metric.setAuthentication(StringUtils.trimToNull(jso.optString("authentication", (String)null))); + metric.setCalculatedCvssBaseScore(jso.optBigDecimal("calculated_cvss_base_score", (BigDecimal)null)); + metric.setGeneratedOn(StringUtils.trimToNull(jso.optString("generated_on", (String)null))); + metric.setScore(jso.optBigDecimal("score", (BigDecimal)null)); + metric.setAccessVector(StringUtils.trimToNull(jso.optString("access_vector", (String)null))); + metric.setIntegrityImpact(StringUtils.trimToNull(jso.optString("integrity_impact", (String)null))); + vulnerability.addCvssV2Metric(metric); + } + } + + JSONArray cvssv3Metrics = object.optJSONArray("cvss_version_three_metrics"); + if (cvssv3Metrics != null) { + for(int j = 0; j < cvssv3Metrics.length(); ++j) { + JSONObject jso = cvssv3Metrics.getJSONObject(j); + CvssV3Metric metric = new CvssV3Metric(); + metric.setId(jso.getInt("id")); + metric.setAttackComplexity(StringUtils.trimToNull(jso.optString("attack_complexity", (String)null))); + metric.setScope(StringUtils.trimToNull(jso.optString("scope", (String)null))); + metric.setAttackVector(StringUtils.trimToNull(jso.optString("attack_vector", (String)null))); + metric.setAvailabilityImpact(StringUtils.trimToNull(jso.optString("availability_impact", (String)null))); + metric.setScore(jso.optBigDecimal("score", (BigDecimal)null)); + metric.setPrivilegesRequired(StringUtils.trimToNull(jso.optString("privileges_required", (String)null))); + metric.setUserInteraction(StringUtils.trimToNull(jso.optString("user_interaction", (String)null))); + metric.setCveId(StringUtils.trimToNull(jso.optString("cve_id", (String)null))); + metric.setSource(StringUtils.trimToNull(jso.optString("source", (String)null))); + metric.setConfidentialityImpact(StringUtils.trimToNull(jso.optString("confidentiality_impact", (String)null))); + metric.setCalculatedCvssBaseScore(jso.optBigDecimal("calculated_cvss_base_score", (BigDecimal)null)); + metric.setGeneratedOn(StringUtils.trimToNull(jso.optString("generated_on", (String)null))); + metric.setIntegrityImpact(StringUtils.trimToNull(jso.optString("integrity_impact", (String)null))); + vulnerability.addCvssV3Metric(metric); + } + } + + JSONArray nvdInfo = object.optJSONArray("nvd_additional_information"); + if (nvdInfo != null) { + for(int j = 0; j < nvdInfo.length(); ++j) { + JSONObject jso = nvdInfo.getJSONObject(j); + NvdAdditionalInfo nvdAdditionalInfo = new NvdAdditionalInfo(); + nvdAdditionalInfo.setSummary(StringUtils.trimToNull(jso.optString("summary", (String)null))); + nvdAdditionalInfo.setCweId(StringUtils.trimToNull(jso.optString("cwe_id", (String)null))); + nvdAdditionalInfo.setCveId(StringUtils.trimToNull(jso.optString("cve_id", (String)null))); + vulnerability.setNvdAdditionalInfo(nvdAdditionalInfo); + } + } + + JSONArray vendors = object.optJSONArray("vendors"); + vulnerability.setVendors(this.parseVendors(vendors)); + vulnerabilities.add(vulnerability); + } + } + + return vulnerabilities; + } +} diff --git a/src/test/java/org/dependencytrack/ResourceTest.java b/src/test/java/org/dependencytrack/ResourceTest.java index f9761c4d54..9d7ce0d1d1 100644 --- a/src/test/java/org/dependencytrack/ResourceTest.java +++ b/src/test/java/org/dependencytrack/ResourceTest.java @@ -29,10 +29,7 @@ import org.dependencytrack.persistence.QueryManager; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.grizzly.connector.GrizzlyConnectorProvider; -import org.glassfish.jersey.test.DeploymentContext; import org.glassfish.jersey.test.JerseyTest; -import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; -import org.glassfish.jersey.test.spi.TestContainer; import org.glassfish.jersey.test.spi.TestContainerFactory; import org.junit.After; import org.junit.Before; diff --git a/src/test/java/org/dependencytrack/common/UnirestFactoryTest.java b/src/test/java/org/dependencytrack/common/UnirestFactoryTest.java deleted file mode 100644 index 7825388dfb..0000000000 --- a/src/test/java/org/dependencytrack/common/UnirestFactoryTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) Steve Springett. All Rights Reserved. - */ -package org.dependencytrack.common; - -import kong.unirest.UnirestInstance; -import org.junit.Assert; -import org.junit.Test; - -public class UnirestFactoryTest { - - @Test - public void instanceTest() { - UnirestInstance ui1 = UnirestFactory.getUnirestInstance(); - UnirestInstance ui2 = UnirestFactory.getUnirestInstance(); - Assert.assertSame(ui1, ui2); - } - - @Test - public void httpClientTest() { - UnirestInstance ui = UnirestFactory.getUnirestInstance(); - Assert.assertNotSame(ui.config().getClient().getClient(), ManagedHttpClientFactory.newManagedHttpClient()); - } -} diff --git a/src/test/java/org/dependencytrack/integration/ApiClient.java b/src/test/java/org/dependencytrack/integration/ApiClient.java index 157a31cdc0..7c575b16dc 100644 --- a/src/test/java/org/dependencytrack/integration/ApiClient.java +++ b/src/test/java/org/dependencytrack/integration/ApiClient.java @@ -18,13 +18,13 @@ */ package org.dependencytrack.integration; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.UnirestException; -import kong.unirest.UnirestInstance; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.entity.StringEntity; +import org.apache.http.util.EntityUtils; +import org.dependencytrack.common.HttpClientPool; import org.json.JSONObject; import org.apache.commons.io.FileUtils; -import org.dependencytrack.common.UnirestFactory; import java.io.File; import java.io.IOException; @@ -41,46 +41,48 @@ public ApiClient(String baseUrl, String apiKey) { this.apiKey = apiKey; } - public UUID createProject(String name, String version) throws UnirestException { - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); - final HttpResponse response = ui.put(baseUrl + "/api/v1/project") - .header("Content-Type", "application/json") - .header("X-API-Key", apiKey) - .body(new JSONObject() - .put("name", name) - .put("version", version) - ) - .asJson(); - if (response.getStatus() == 201) { - return UUID.fromString(response.getBody().getObject().getString("uuid")); + public UUID createProject(String name, String version) throws IOException { + HttpPut request = new HttpPut(baseUrl + "/api/v1/project"); + request.addHeader("Content-Type", "application/json"); + request.addHeader("X-API-Key", apiKey); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("name", name); + jsonObject.put("version", version); + String jsonString = jsonObject.toString(); + request.setEntity(new StringEntity(jsonString)); + CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + if (response.getStatusLine().getStatusCode() == 201) { + String responseString = EntityUtils.toString(response.getEntity()); + JSONObject jsonObject1 = new JSONObject(responseString); + return UUID.fromString(jsonObject1.getString("uuid")); } - System.out.println("Error creating project " + name + " status: " + response.getStatus()); + System.out.println("Error creating project " + name + " status: " + response.getStatusLine().getStatusCode()); return null; } - public boolean uploadBom(UUID uuid, File bom) throws IOException, UnirestException { - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); - final HttpResponse response = ui.put(baseUrl + "/api/v1/bom") - .header("Content-Type", "application/json") - .header("X-API-Key", apiKey) - .body(new JSONObject() - .put("project", uuid.toString()) - .put("bom", Base64.getEncoder().encodeToString(FileUtils.readFileToByteArray(bom))) - ) - .asJson(); - return (response.getStatus() == 200); + public boolean uploadBom(UUID uuid, File bom) throws IOException, IOException { + HttpPut request = new HttpPut(baseUrl + "/api/v1/bom"); + request.addHeader("Content-Type", "application/json"); + request.addHeader("X-API-Key", apiKey); + JSONObject jsonObject = new JSONObject() + .put("project", uuid.toString()) + .put("bom", Base64.getEncoder().encodeToString(FileUtils.readFileToByteArray(bom))); + String jsonString = jsonObject.toString(); + request.setEntity(new StringEntity(jsonString)); + CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + return (response.getStatusLine().getStatusCode() == 200); } - public boolean uploadScan(UUID uuid, File scan) throws IOException, UnirestException { - final UnirestInstance ui = UnirestFactory.getUnirestInstance(); - final HttpResponse response = ui.put(baseUrl + "/api/v1/scan") - .header("Content-Type", "application/json") - .header("X-API-Key", apiKey) - .body(new JSONObject() + public boolean uploadScan(UUID uuid, File scan) throws IOException { + HttpPut request = new HttpPut(baseUrl + "/api/v1/scan"); + request.addHeader("Content-Type", "application/json"); + request.addHeader("X-API-Key", apiKey); + JSONObject jsonObject = new JSONObject() .put("project", uuid.toString()) - .put("scan", Base64.getEncoder().encodeToString(FileUtils.readFileToByteArray(scan))) - ) - .asJson(); - return (response.getStatus() == 200); + .put("scan", Base64.getEncoder().encodeToString(FileUtils.readFileToByteArray(scan))); + String jsonString = jsonObject.toString(); + request.setEntity(new StringEntity(jsonString)); + CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + return (response.getStatusLine().getStatusCode() == 200); } } diff --git a/src/test/java/org/dependencytrack/tasks/scanners/SnykAnalysisTaskTest.java b/src/test/java/org/dependencytrack/tasks/scanners/SnykAnalysisTaskTest.java index ab03102770..781cc53f6e 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/SnykAnalysisTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/SnykAnalysisTaskTest.java @@ -262,7 +262,7 @@ public void testAnalyzeWithRateLimiting() { } ], "links": { - "self": "/orgs/fd53e445-dc38-4b25-9c8a-5f68ed79f537/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0/issues?version=2022-11-14&limit=1000&offset=0" + "self": "/orgs/fd53e445-dc38-4b25-9c8a-5f68ed79f537/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0/issues?version=2023-01-04&limit=1000&offset=0" }, "meta": { "package": { @@ -354,7 +354,7 @@ public void testAnalyzeWithNoIssues() { }, "data": [], "links": { - "self": "/orgs/da563045-a462-421a-ae47-53239fe46612/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues?version=2022-11-14&limit=1000&offset=0" + "self": "/orgs/da563045-a462-421a-ae47-53239fe46612/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues?version=2023-01-04&limit=1000&offset=0" }, "meta": { "package": { @@ -563,7 +563,7 @@ public void testAnalyzeWithDeprecatedApiVersion() throws Exception { }, "data": [], "links": { - "self": "/orgs/da563045-a462-421a-ae47-53239fe46612/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues?version=2022-11-14&limit=1000&offset=0" + "self": "/orgs/da563045-a462-421a-ae47-53239fe46612/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues?version=2023-01-04&limit=1000&offset=0" }, "meta": { "package": { From e691dda86279222c3138fad69028405dbf0cdb8a Mon Sep 17 00:00:00 2001 From: mehab Date: Mon, 23 Jan 2023 16:32:35 +0000 Subject: [PATCH 06/31] cleanup Signed-off-by: mehab --- .../defectdojo/DefectDojoClient.java | 7 ++++--- .../kenna/KennaSecurityUploader.java | 3 ++- .../parser/ossindex/OssIndexParser.java | 3 +-- .../dependencytrack/tasks/EpssMirrorTask.java | 3 ++- .../tasks/GitHubAdvisoryMirrorTask.java | 5 +++-- .../dependencytrack/tasks/NistMirrorTask.java | 3 ++- .../dependencytrack/tasks/OsvDownloadTask.java | 5 +++-- .../tasks/repositories/CargoMetaAnalyzer.java | 2 +- .../tasks/repositories/ComposerMetaAnalyzer.java | 4 ++-- .../tasks/repositories/HexMetaAnalyzer.java | 2 +- .../tasks/repositories/NugetMetaAnalyzer.java | 16 ++++++++-------- .../tasks/repositories/PypiMetaAnalyzer.java | 6 +++--- .../tasks/scanners/OssIndexAnalysisTask.java | 3 ++- .../tasks/scanners/SnykAnalysisTask.java | 7 ++++--- .../dependencytrack/integration/ApiClient.java | 5 +++-- 15 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java index 96fe5ab33a..b7a36c3825 100644 --- a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java +++ b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java @@ -19,6 +19,7 @@ package org.dependencytrack.integrations.defectdojo; import alpine.common.logging.Logger; +import org.apache.http.HttpStatus; import org.json.JSONArray; import org.json.JSONObject; import org.apache.http.HttpEntity; @@ -77,7 +78,7 @@ public void uploadDependencyTrackFindings(final String token, final String engag request.setEntity(new UrlEncodedFormEntity(nameValuePairs, StandardCharsets.UTF_8)); try { CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - if (response.getStatusLine().getStatusCode() == 201) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED) { LOGGER.debug("Successfully uploaded findings to DefectDojo"); } else { LOGGER.warn("DefectDojo Client did not receive expected response while attempting to upload " @@ -101,7 +102,7 @@ public ArrayList getDojoTestIds(final String token, final String eid) { request.addHeader("Authorization", "Token " + token); try{ CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - if (response.getStatusLine().getStatusCode() == 200) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (response.getEntity()!=null) { String stringResponse = EntityUtils.toString(response.getEntity()); JSONObject dojoObj = new JSONObject(stringResponse); @@ -183,7 +184,7 @@ public void reimportDependencyTrackFindings(final String token, final String eng request.setEntity(fileData); try{ CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - if (response.getStatusLine().getStatusCode() == 201) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED) { LOGGER.debug("Successfully reimport findings to DefectDojo"); } else { LOGGER.warn("DefectDojo Client did not receive expected response while attempting to reimport" diff --git a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java index f7f2ae545a..e1c8d9d895 100644 --- a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java +++ b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java @@ -22,6 +22,7 @@ import alpine.model.ConfigProperty; import alpine.security.crypto.DataEncryption; import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; @@ -106,7 +107,7 @@ public void upload(final InputStream payload) { .build(); request.setEntity(data); final CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - if (response.getStatusLine().getStatusCode() == 200 && response.getEntity() != null) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK && response.getEntity() != null) { String responseString = EntityUtils.toString(response.getEntity()); final JSONObject root = new JSONObject(responseString); if (root.getString("success").equals("true")) { diff --git a/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java b/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java index 88c877d6a1..3eb670c2c4 100644 --- a/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java +++ b/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java @@ -19,7 +19,6 @@ package org.dependencytrack.parser.ossindex; import alpine.common.logging.Logger; -import com.fasterxml.jackson.databind.JsonNode; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -42,7 +41,7 @@ public class OssIndexParser { /** * Parses the JSON response from Sonatype OSS Index * - * @param responseString the JSON node to parse + * @param responseString the response as a String to parse * @return an ComponentReport object */ public List parse(final String responseString) { diff --git a/src/main/java/org/dependencytrack/tasks/EpssMirrorTask.java b/src/main/java/org/dependencytrack/tasks/EpssMirrorTask.java index 4968bfdf73..8c49fbac65 100644 --- a/src/main/java/org/dependencytrack/tasks/EpssMirrorTask.java +++ b/src/main/java/org/dependencytrack/tasks/EpssMirrorTask.java @@ -26,6 +26,7 @@ import alpine.notification.Notification; import alpine.notification.NotificationLevel; import org.apache.commons.io.FileUtils; +import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -146,7 +147,7 @@ private void doDownload(final String urlString) { final StatusLine status = response.getStatusLine(); final long end = System.currentTimeMillis(); metricDownloadTime += end - start; - if (status.getStatusCode() == 200) { + if (status.getStatusCode() == HttpStatus.SC_OK) { LOGGER.info("Downloading..."); try (InputStream in = response.getEntity().getContent()) { file = new File(outputDir, filename); diff --git a/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java b/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java index 5d2f628378..0ce2f8144d 100644 --- a/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java +++ b/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java @@ -30,6 +30,7 @@ import io.pebbletemplates.pebble.PebbleEngine; import io.pebbletemplates.pebble.template.PebbleTemplate; import org.apache.commons.lang3.tuple.Pair; +import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; @@ -134,13 +135,13 @@ private void retrieveAdvisories(final String advisoriesEndCursor) throws IOExcep request.addHeader("Authorization", "bearer " + accessToken); request.addHeader("content-type", "application/json"); request.addHeader("accept", "application/json"); - org.json.JSONObject jsonBody = new org.json.JSONObject(); + JSONObject jsonBody = new JSONObject(); jsonBody.put("query", queryTemplate); StringEntity stringEntity = new StringEntity(jsonBody.toString()); request.setEntity(stringEntity); CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - if (response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() > 299) { + if (response.getStatusLine().getStatusCode() < HttpStatus.SC_OK || response.getStatusLine().getStatusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) { LOGGER.error("An error was encountered retrieving advisories"); LOGGER.error("HTTP Status : " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); LOGGER.debug(queryTemplate); diff --git a/src/main/java/org/dependencytrack/tasks/NistMirrorTask.java b/src/main/java/org/dependencytrack/tasks/NistMirrorTask.java index 0c58fc6285..52f4de589f 100644 --- a/src/main/java/org/dependencytrack/tasks/NistMirrorTask.java +++ b/src/main/java/org/dependencytrack/tasks/NistMirrorTask.java @@ -27,6 +27,7 @@ import alpine.notification.NotificationLevel; import org.apache.commons.io.FileUtils; import org.apache.http.HttpHeaders; +import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -223,7 +224,7 @@ private void doDownload(final String urlString, final ResourceType resourceType) final StatusLine status = response.getStatusLine(); final long end = System.currentTimeMillis(); metricDownloadTime += end - start; - if (status.getStatusCode() == 200) { + if (status.getStatusCode() == HttpStatus.SC_OK) { LOGGER.info("Downloading..."); try (InputStream in = response.getEntity().getContent()) { File temp = File.createTempFile(filename, null); diff --git a/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java b/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java index 4fedb95156..0614de9fb8 100644 --- a/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java +++ b/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java @@ -6,6 +6,7 @@ import alpine.model.ConfigProperty; import com.github.packageurl.MalformedPackageURLException; import com.github.packageurl.PackageURL; +import org.apache.http.HttpStatus; import org.json.JSONObject; import org.apache.http.StatusLine; import org.apache.http.client.methods.CloseableHttpResponse; @@ -90,7 +91,7 @@ public void inform(Event e) { HttpUriRequest request = new HttpGet(url); try (final CloseableHttpResponse response = HttpClientPool.getClient().execute(request)) { final StatusLine status = response.getStatusLine(); - if (status.getStatusCode() == 200) { + if (status.getStatusCode() == HttpStatus.SC_OK) { try (InputStream in = response.getEntity().getContent(); ZipInputStream zipInput = new ZipInputStream(in)) { unzipFolder(zipInput); @@ -318,7 +319,7 @@ public List getEcosystems() { HttpUriRequest request = new HttpGet(url); try (final CloseableHttpResponse response = HttpClientPool.getClient().execute(request)) { final StatusLine status = response.getStatusLine(); - if (status.getStatusCode() == 200) { + if (status.getStatusCode() == HttpStatus.SC_OK) { try (InputStream in = response.getEntity().getContent(); Scanner scanner = new Scanner(in, StandardCharsets.UTF_8)) { while (scanner.hasNextLine()) { diff --git a/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java index 1ee289acbd..aad477afef 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java @@ -75,7 +75,7 @@ public MetaModel analyze(final Component component) { final HttpEntity entity = response.getEntity(); if (entity != null) { String responseString = EntityUtils.toString(entity); - org.json.JSONObject jsonObject = new org.json.JSONObject(responseString); + JSONObject jsonObject = new JSONObject(responseString); final JSONObject crate = jsonObject.optJSONObject("crate"); if (crate != null) { final String latest = crate.getString("newest_version"); diff --git a/src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java index 4a76e24446..2cc49b8255 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java @@ -93,9 +93,9 @@ public MetaModel analyze(final Component component) { if (jsonString.equalsIgnoreCase("{}")) { return meta; } - org.json.JSONObject jsonObject = new org.json.JSONObject(jsonString); + JSONObject jsonObject = new JSONObject(jsonString); final String expectedResponsePackage = component.getPurl().getNamespace() + "/" + component.getPurl().getName(); - final org.json.JSONObject responsePackages = jsonObject + final JSONObject responsePackages = jsonObject .getJSONObject("packages"); if (!responsePackages.has(expectedResponsePackage)) { // the package no longer exists - like this one: https://repo.packagist.org/p/magento/adobe-ims.json diff --git a/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java index 53ac9dc373..3de2698d60 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java @@ -83,7 +83,7 @@ public MetaModel analyze(final Component component) { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (response.getEntity()!=null) { String responseString = EntityUtils.toString(response.getEntity()); - org.json.JSONObject jsonObject = new org.json.JSONObject(responseString); + JSONObject jsonObject = new JSONObject(responseString); final JSONArray releasesArray = jsonObject.getJSONArray("releases"); if (releasesArray.length() > 0) { // The first one in the array is always the latest version diff --git a/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java index 8588b32364..aaba26680c 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java @@ -108,8 +108,8 @@ private boolean performVersionCheck(final MetaModel meta, final Component compon if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (response.getEntity() != null) { String responseString = EntityUtils.toString(response.getEntity()); - org.json.JSONObject jsonObject = new org.json.JSONObject(responseString); - final org.json.JSONArray versions = jsonObject.getJSONArray("versions"); + JSONObject jsonObject = new JSONObject(responseString); + final JSONArray versions = jsonObject.getJSONArray("versions"); final String latest = findLatestVersion(versions); // get the last version in the array meta.setLatestVersion(latest); } @@ -123,7 +123,7 @@ private boolean performVersionCheck(final MetaModel meta, final Component compon return false; } - private String findLatestVersion(org.json.JSONArray versions) { + private String findLatestVersion(JSONArray versions) { if (versions.length() < 1) { return null; } @@ -147,7 +147,7 @@ private boolean performLastPublishedCheck(final MetaModel meta, final Component if (response.getEntity() != null) { String stringResponse = EntityUtils.toString(response.getEntity()); if (!stringResponse.equalsIgnoreCase("") && !stringResponse.equalsIgnoreCase("{}")) { - org.json.JSONObject jsonResponse = new org.json.JSONObject(stringResponse); + JSONObject jsonResponse = new JSONObject(stringResponse); final String updateTime = jsonResponse.optString("published", null); if (updateTime != null) { meta.setPublishedTimestamp(parseUpdateTime(updateTime)); @@ -171,10 +171,10 @@ private void initializeEndpoints() { if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { if(response.getEntity()!=null){ String responseString = EntityUtils.toString(response.getEntity()); - org.json.JSONObject responseJson = new org.json.JSONObject(responseString); - final org.json.JSONArray resources = responseJson.getJSONArray("resources"); - final org.json.JSONObject packageBaseResource = findResourceByType(resources, "PackageBaseAddress"); - final org.json.JSONObject registrationsBaseResource = findResourceByType(resources, "RegistrationsBaseUrl"); + JSONObject responseJson = new JSONObject(responseString); + final JSONArray resources = responseJson.getJSONArray("resources"); + final JSONObject packageBaseResource = findResourceByType(resources, "PackageBaseAddress"); + final JSONObject registrationsBaseResource = findResourceByType(resources, "RegistrationsBaseUrl"); if (packageBaseResource != null && registrationsBaseResource != null) { versionQueryUrl = packageBaseResource.getString("@id") + "%s/index.json"; registrationUrl = registrationsBaseResource.getString("@id") + "%s/%s.json"; diff --git a/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java index 40ad1cc90b..484571bd52 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/PypiMetaAnalyzer.java @@ -75,12 +75,12 @@ public MetaModel analyze(final Component component) { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (response.getEntity() != null) { String stringResponse = EntityUtils.toString(response.getEntity()); - org.json.JSONObject jsonObject = new org.json.JSONObject(stringResponse); - final org.json.JSONObject info = jsonObject.getJSONObject("info"); + JSONObject jsonObject = new JSONObject(stringResponse); + final JSONObject info = jsonObject.getJSONObject("info"); final String latest = info.optString("version", null); if (latest != null) { meta.setLatestVersion(latest); - final org.json.JSONObject releases = jsonObject.getJSONObject("releases"); + final JSONObject releases = jsonObject.getJSONObject("releases"); final JSONArray latestArray = releases.getJSONArray(latest); if (latestArray.length() > 0) { final JSONObject release = latestArray.getJSONObject(0); diff --git a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java index 2b7b657c2f..55e5b12d74 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java @@ -34,6 +34,7 @@ import io.github.resilience4j.retry.RetryConfig; import io.github.resilience4j.retry.RetryRegistry; import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; @@ -263,7 +264,7 @@ private List submit(final JSONObject payload) { final CloseableHttpResponse response = HttpClientPool.getClient().execute(request); HttpEntity responseEntity = response.getEntity(); String responseString = EntityUtils.toString(responseEntity); - if (response.getStatusLine().getStatusCode() == 200) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { final OssIndexParser parser = new OssIndexParser(); return parser.parse(responseString); } else { diff --git a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java index a2f2b377ac..3a33aeb0ef 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java @@ -35,6 +35,7 @@ import io.github.resilience4j.retry.RetryConfig; import io.github.resilience4j.retry.RetryRegistry; import org.apache.http.Header; +import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.json.JSONArray; @@ -317,13 +318,13 @@ private void analyzeComponent(final Component component) { else { apiVersionSunset = null; } - if (response.getStatusLine().getStatusCode() >= 200 && response.getStatusLine().getStatusCode() < 300) { + if (response.getStatusLine().getStatusCode() >= HttpStatus.SC_OK && response.getStatusLine().getStatusCode() < HttpStatus.SC_MULTIPLE_CHOICES) { String responseString = EntityUtils.toString(response.getEntity()); - org.json.JSONObject responseJson = new org.json.JSONObject(responseString); + JSONObject responseJson = new JSONObject(responseString); handle(component, responseJson); } else if (response.getEntity() != null) { String responseString = EntityUtils.toString(response.getEntity()); - org.json.JSONObject responseJson = new org.json.JSONObject(responseString); + JSONObject responseJson = new JSONObject(responseString); final List errors = new SnykParser().parseErrors(responseJson); if (!errors.isEmpty()) { LOGGER.error("Analysis of component %s failed with HTTP status %d: \n%s" diff --git a/src/test/java/org/dependencytrack/integration/ApiClient.java b/src/test/java/org/dependencytrack/integration/ApiClient.java index 7c575b16dc..510b2a27c5 100644 --- a/src/test/java/org/dependencytrack/integration/ApiClient.java +++ b/src/test/java/org/dependencytrack/integration/ApiClient.java @@ -18,6 +18,7 @@ */ package org.dependencytrack.integration; +import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.StringEntity; @@ -70,7 +71,7 @@ public boolean uploadBom(UUID uuid, File bom) throws IOException, IOException { String jsonString = jsonObject.toString(); request.setEntity(new StringEntity(jsonString)); CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - return (response.getStatusLine().getStatusCode() == 200); + return (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK); } public boolean uploadScan(UUID uuid, File scan) throws IOException { @@ -83,6 +84,6 @@ public boolean uploadScan(UUID uuid, File scan) throws IOException { String jsonString = jsonObject.toString(); request.setEntity(new StringEntity(jsonString)); CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - return (response.getStatusLine().getStatusCode() == 200); + return (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK); } } From 89ab9589dc9ae1226ff5a61541656364cf9b7413 Mon Sep 17 00:00:00 2001 From: mehab Date: Mon, 23 Jan 2023 16:47:43 +0000 Subject: [PATCH 07/31] removed spdx based test that is not working and is not relevant Signed-off-by: mehab --- .../integration/ApiClient.java | 89 ------------------- .../integration/PopulateData.java | 50 ----------- 2 files changed, 139 deletions(-) delete mode 100644 src/test/java/org/dependencytrack/integration/ApiClient.java delete mode 100644 src/test/java/org/dependencytrack/integration/PopulateData.java diff --git a/src/test/java/org/dependencytrack/integration/ApiClient.java b/src/test/java/org/dependencytrack/integration/ApiClient.java deleted file mode 100644 index 510b2a27c5..0000000000 --- a/src/test/java/org/dependencytrack/integration/ApiClient.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) Steve Springett. All Rights Reserved. - */ -package org.dependencytrack.integration; - -import org.apache.http.HttpStatus; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.entity.StringEntity; -import org.apache.http.util.EntityUtils; -import org.dependencytrack.common.HttpClientPool; -import org.json.JSONObject; -import org.apache.commons.io.FileUtils; - -import java.io.File; -import java.io.IOException; -import java.util.Base64; -import java.util.UUID; - -public class ApiClient { - - private String baseUrl; - private String apiKey; - - public ApiClient(String baseUrl, String apiKey) { - this.baseUrl = baseUrl; - this.apiKey = apiKey; - } - - public UUID createProject(String name, String version) throws IOException { - HttpPut request = new HttpPut(baseUrl + "/api/v1/project"); - request.addHeader("Content-Type", "application/json"); - request.addHeader("X-API-Key", apiKey); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("name", name); - jsonObject.put("version", version); - String jsonString = jsonObject.toString(); - request.setEntity(new StringEntity(jsonString)); - CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - if (response.getStatusLine().getStatusCode() == 201) { - String responseString = EntityUtils.toString(response.getEntity()); - JSONObject jsonObject1 = new JSONObject(responseString); - return UUID.fromString(jsonObject1.getString("uuid")); - } - System.out.println("Error creating project " + name + " status: " + response.getStatusLine().getStatusCode()); - return null; - } - - public boolean uploadBom(UUID uuid, File bom) throws IOException, IOException { - HttpPut request = new HttpPut(baseUrl + "/api/v1/bom"); - request.addHeader("Content-Type", "application/json"); - request.addHeader("X-API-Key", apiKey); - JSONObject jsonObject = new JSONObject() - .put("project", uuid.toString()) - .put("bom", Base64.getEncoder().encodeToString(FileUtils.readFileToByteArray(bom))); - String jsonString = jsonObject.toString(); - request.setEntity(new StringEntity(jsonString)); - CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - return (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK); - } - - public boolean uploadScan(UUID uuid, File scan) throws IOException { - HttpPut request = new HttpPut(baseUrl + "/api/v1/scan"); - request.addHeader("Content-Type", "application/json"); - request.addHeader("X-API-Key", apiKey); - JSONObject jsonObject = new JSONObject() - .put("project", uuid.toString()) - .put("scan", Base64.getEncoder().encodeToString(FileUtils.readFileToByteArray(scan))); - String jsonString = jsonObject.toString(); - request.setEntity(new StringEntity(jsonString)); - CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - return (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK); - } -} diff --git a/src/test/java/org/dependencytrack/integration/PopulateData.java b/src/test/java/org/dependencytrack/integration/PopulateData.java deleted file mode 100644 index d27b06e418..0000000000 --- a/src/test/java/org/dependencytrack/integration/PopulateData.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) Steve Springett. All Rights Reserved. - */ -package org.dependencytrack.integration; - -import org.junit.Test; - -import java.io.File; -import java.util.UUID; - -public class PopulateData { - - private static final String BASE_URL = "http://localhost:8080"; - private static final String API_KEY = "hETzpWanQkXV6KsJsfPuFoNBRZdiiDyY"; - - @Test - public void doit() throws Exception { - ApiClient api = new ApiClient(BASE_URL, API_KEY); - UUID uuid = api.createProject("SonarQube", "5.6"); - - File file = new File(this.getClass().getResource("/integration/sonarqube-6.5.spdx").getFile()); - - if (file.exists()) { - System.out.println("Found It"); - api.uploadBom(uuid, file); - } - - } - - - public static void main(String[] args) throws Exception { - final PopulateData populateData = new PopulateData(); - populateData.doit(); - } -} From f7d6c1c41b53287a23410e152b3b4c09320e41de Mon Sep 17 00:00:00 2001 From: mehab Date: Tue, 24 Jan 2023 18:36:02 +0000 Subject: [PATCH 08/31] added unit tests for vulndb Signed-off-by: mehab --- .../dependencytrack/tasks/VulnDbSyncTask.java | 1 - .../org/dependencytrack/util/VulnDBUtil.java | 15 +- .../scanners/VulnDBAnalysisTaskTest.java | 431 ++++++++++++++++++ 3 files changed, 445 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java diff --git a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java index 86c6c217f7..61eeb5ea42 100644 --- a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java +++ b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java @@ -190,7 +190,6 @@ private static VulnerableSoftware generateVulnerableSoftware(final QueryManager vs.setVersionStartExcluding(null); vs.setVersionStartIncluding(null); vs = qm.persist(vs); - //Event.dispatch(new IndexEvent(IndexEvent.Action.CREATE, qm.detach(VulnerableSoftware.class, vs.getId()))); return vs; } catch (CpeParsingException | CpeEncodingException e) { LOGGER.warn("An error occurred while parsing: " + cpe.toCpe23FS() + " - The CPE is invalid and will be discarded."); diff --git a/src/main/java/org/dependencytrack/util/VulnDBUtil.java b/src/main/java/org/dependencytrack/util/VulnDBUtil.java index 372209a364..8d2f4cdf35 100644 --- a/src/main/java/org/dependencytrack/util/VulnDBUtil.java +++ b/src/main/java/org/dependencytrack/util/VulnDBUtil.java @@ -12,7 +12,20 @@ import org.dependencytrack.common.HttpClientPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import us.springett.vulndbdatamirror.parser.model.*; +import us.springett.vulndbdatamirror.parser.model.CPE; +import us.springett.vulndbdatamirror.parser.model.Product; +import us.springett.vulndbdatamirror.parser.model.Results; +import us.springett.vulndbdatamirror.parser.model.Vendor; +import us.springett.vulndbdatamirror.parser.model.Version; +import us.springett.vulndbdatamirror.parser.model.ApiObject; +import us.springett.vulndbdatamirror.parser.model.Vulnerability; +import us.springett.vulndbdatamirror.parser.model.Classification; +import us.springett.vulndbdatamirror.parser.model.Author; +import us.springett.vulndbdatamirror.parser.model.CvssV2Metric; +import us.springett.vulndbdatamirror.parser.model.CvssV3Metric; +import us.springett.vulndbdatamirror.parser.model.NvdAdditionalInfo; +import us.springett.vulndbdatamirror.parser.model.ExternalText; +import us.springett.vulndbdatamirror.parser.model.ExternalReference; import java.io.IOException; import java.io.UnsupportedEncodingException; diff --git a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java new file mode 100644 index 0000000000..0a51ad00a8 --- /dev/null +++ b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java @@ -0,0 +1,431 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ +package org.dependencytrack.tasks.scanners; + +import alpine.model.IConfigProperty; +import alpine.notification.Notification; +import alpine.notification.NotificationLevel; +import alpine.notification.NotificationService; +import alpine.notification.Subscriber; +import alpine.notification.Subscription; +import alpine.security.crypto.DataEncryption; +import org.apache.http.HttpHeaders; +import org.assertj.core.api.SoftAssertions; +import org.dependencytrack.PersistenceCapableTest; +import org.dependencytrack.common.ManagedHttpClientFactory; +import org.dependencytrack.event.VulnDbAnalysisEvent; +import org.dependencytrack.model.Component; +import org.dependencytrack.model.ComponentAnalysisCache; +import org.dependencytrack.model.Project; +import org.dependencytrack.model.Severity; +import org.dependencytrack.model.Vulnerability; +import org.dependencytrack.notification.NotificationGroup; +import org.dependencytrack.notification.NotificationScope; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockserver.integration.ClientAndServer; +import org.mockserver.verify.VerificationTimes; + +import javax.jdo.Query; +import javax.json.Json; +import java.time.Duration; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentLinkedQueue; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.dependencytrack.assertion.Assertions.assertConditionWithTimeout; +import static org.dependencytrack.model.ConfigPropertyConstants.*; +import static org.mockserver.model.HttpError.error; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + +public class VulnDBAnalysisTaskTest extends PersistenceCapableTest { + + private static ClientAndServer mockServer; + + @BeforeClass + public static void beforeClass() { + NotificationService.getInstance().subscribe(new Subscription(NotificationSubscriber.class)); + mockServer = ClientAndServer.startClientAndServer(1080); + } + + @Before + public void setUp() throws Exception { + qm.createConfigProperty(SCANNER_VULNDB_ENABLED.getGroupName(), + SCANNER_VULNDB_ENABLED.getPropertyName(), + "true", + IConfigProperty.PropertyType.BOOLEAN, + "vulndb"); + qm.createConfigProperty(SCANNER_ANALYSIS_CACHE_VALIDITY_PERIOD.getGroupName(), + SCANNER_ANALYSIS_CACHE_VALIDITY_PERIOD.getPropertyName(), + "86400", + IConfigProperty.PropertyType.STRING, + "cache"); + qm.createConfigProperty(SCANNER_VULNDB_OAUTH1_CONSUMER_KEY.getGroupName(), + SCANNER_VULNDB_OAUTH1_CONSUMER_KEY.getPropertyName(), + DataEncryption.encryptAsString("secret"), + IConfigProperty.PropertyType.STRING, + "secret"); + qm.createConfigProperty(SCANNER_VULNDB_OAUTH1_CONSUMER_SECRET.getGroupName(), + SCANNER_VULNDB_OAUTH1_CONSUMER_SECRET.getPropertyName(), + "secret", + IConfigProperty.PropertyType.STRING, + "secret"); + } + + @After + public void tearDown() { + mockServer.reset(); + NOTIFICATIONS.clear(); + } + + @AfterClass + public static void afterClass() { + mockServer.stop(); + NotificationService.getInstance().unsubscribe(new Subscription(NotificationSubscriber.class)); + } + + @Test + public void testIsCapable() { + final var asserts = new SoftAssertions(); + + for (final Map.Entry test : Map.of( + "pkg:maven/com.fasterxml.woodstox/woodstox-core", false, // Missing version + "pkg:golang/github.com/CycloneDX/cyclonedx-go@0.7.0", false, // Unsupported type + "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0", true, + "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz", true + ).entrySet()) { + final var component = new Component(); + component.setPurl(test.getKey()); + asserts.assertThat(new VulnDbAnalysisTask().isCapable(component)).isEqualTo(test.getValue()); + } + + asserts.assertAll(); + } + + @Test + public void testAnalyzeWithNoIssues() { + mockServer + .when(request() + .withMethod("GET") + .withPath("/rest/orgs/orgid/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues") + .withQueryStringParameter("version", "version")) + .respond(response() + .withStatusCode(200) + .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") + .withBody(""" + { + "jsonapi": { + "version": "1.0" + }, + "data": [], + "links": { + "self": "/orgs/da563045-a462-421a-ae47-53239fe46612/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues?version=2023-01-04&limit=1000&offset=0" + }, + "meta": { + "package": { + "name": "woodstox-core", + "type": "maven", + "url": "pkg:maven/com.fasterxml.woodstox/woodstox-core@6.4.0", + "version": "6.4.0" + } + } + } + """)); + + var project = new Project(); + project.setName("acme-app"); + project = qm.createProject(project, null, false); + + var component = new Component(); + component.setProject(project); + component.setGroup("com.fasterxml.woodstox"); + component.setName("woodstox-core"); + component.setVersion("6.4.0"); + component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@6.4.0?foo=bar#baz"); + component = qm.createComponent(component, false); + + new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); + + final List vulnerabilities = qm.getAllVulnerabilities(component); + assertThat(vulnerabilities).hasSize(0); + + final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); + final List cacheEntries = cacheQuery.executeList(); + assertThat(cacheEntries).hasSize(1); + + final ComponentAnalysisCache cacheEntry = cacheEntries.get(0); + assertThat(cacheEntry.getTarget()).isEqualTo("pkg:maven/com.fasterxml.woodstox/woodstox-core@6.4.0"); + assertThat(cacheEntry.getResult()) + .containsEntry("vulnIds", Json.createArrayBuilder().build()); + } + + @Test + public void testAnalyzeWithError() { + mockServer + .when(request() + .withMethod("GET") + .withPath("/rest/orgs/orgid/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0/issues") + .withQueryStringParameter("version", "version")) + .respond(response() + .withStatusCode(400) + .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") + .withBody(""" + { + "jsonapi": { + "version": "1.0" + }, + "errors": [ + { + "id": "0f12fd75-c80a-4c15-929b-f7794eb3dd4f", + "links": { + "about": "https://docs.snyk.io/more-info/error-catalog#snyk-ossi-2010-invalid-purl-has-been-provided" + }, + "status": "400", + "code": "SNYK-OSSI-2010", + "title": "Invalid PURL has been provided", + "detail": "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0%", + "source": { + "pointer": "/orgs/0d581750-c5d7-4acf-9ff9-4a5bae31cbf1/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0%25/issues" + }, + "meta": { + "links": [ + "https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst" + ] + } + } + ] + } + """)); + + var project = new Project(); + project.setName("acme-app"); + project = qm.createProject(project, null, false); + + var component = new Component(); + component.setProject(project); + component.setGroup("com.fasterxml.woodstox"); + component.setName("woodstox-core"); + component.setVersion("5.0.0"); + component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); + component = qm.createComponent(component, false); + + new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); + + final List vulnerabilities = qm.getAllVulnerabilities(component); + assertThat(vulnerabilities).hasSize(0); + + final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); + assertThat(cacheQuery.executeList()).isEmpty(); + } + + @Test + public void testAnalyzeWithUnspecifiedError() { + mockServer + .when(request() + .withMethod("GET") + .withPath("/rest/orgs/orgid/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0/issues") + .withQueryStringParameter("version", "version")) + .respond(response() + .withStatusCode(403) + ); + + var project = new Project(); + project.setName("acme-app"); + project = qm.createProject(project, null, false); + + var component = new Component(); + component.setProject(project); + component.setGroup("com.fasterxml.woodstox"); + component.setName("woodstox-core"); + component.setVersion("5.0.0"); + component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); + component = qm.createComponent(component, false); + + new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); + + final List vulnerabilities = qm.getAllVulnerabilities(component); + assertThat(vulnerabilities).hasSize(0); + + final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); + assertThat(cacheQuery.executeList()).isEmpty(); + } + + @Test + public void testAnalyzeWithConnectionError() { + mockServer + .when(request().withPath("/rest/.+")) + .error(error().withDropConnection(true)); + + var project = new Project(); + project.setName("acme-app"); + project = qm.createProject(project, null, false); + + var component = new Component(); + component.setProject(project); + component.setGroup("com.fasterxml.woodstox"); + component.setName("woodstox-core"); + component.setVersion("5.0.0"); + component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); + component = qm.createComponent(component, false); + + new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); + + final List vulnerabilities = qm.getAllVulnerabilities(component); + assertThat(vulnerabilities).hasSize(0); + + final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); + assertThat(cacheQuery.executeList()).isEmpty(); + } + + @Test + public void testAnalyzeWithCurrentCache() { + var vuln = new Vulnerability(); + vuln.setVulnId("VULNDB-001"); + vuln.setSource(Vulnerability.Source.VULNDB); + vuln.setSeverity(Severity.HIGH); + vuln = qm.createVulnerability(vuln, false); + + qm.updateComponentAnalysisCache(ComponentAnalysisCache.CacheType.VULNERABILITY, "http://localhost:1080", + Vulnerability.Source.VULNDB.name(), "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0", new Date(), + Json.createObjectBuilder() + .add("vulnIds", Json.createArrayBuilder().add(vuln.getId())) + .build()); + + var project = new Project(); + project.setName("acme-app"); + project = qm.createProject(project, null, false); + + var component = new Component(); + component.setProject(project); + component.setGroup("com.fasterxml.woodstox"); + component.setName("woodstox-core"); + component.setVersion("5.0.0"); + component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); + component = qm.createComponent(component, false); + + new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); + + final List vulnerabilities = qm.getAllVulnerabilities(component); + assertThat(vulnerabilities).hasSize(1); + + mockServer.verifyZeroInteractions(); + } + + @Test + public void testAnalyzeWithDeprecatedApiVersion() throws Exception { + mockServer + .when(request() + .withMethod("GET") + .withPath("/rest/.+")) + .respond(response() + .withStatusCode(200) + .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") + .withHeader("Sunset", "Wed, 11 Nov 2021 11:11:11 GMT") + .withBody(""" + { + "jsonapi": { + "version": "1.0" + }, + "data": [], + "links": { + "self": "/orgs/da563045-a462-421a-ae47-53239fe46612/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues?version=2023-01-04&limit=1000&offset=0" + }, + "meta": { + "package": { + "name": "woodstox-core", + "type": "maven", + "url": "pkg:maven/com.fasterxml.woodstox/woodstox-core@6.4.0", + "version": "6.4.0" + } + } + } + """)); + + var project = new Project(); + project.setName("acme-app"); + project = qm.createProject(project, null, false); + + var component = new Component(); + component.setProject(project); + component.setGroup("com.fasterxml.woodstox"); + component.setName("woodstox-core"); + component.setVersion("5.0.0"); + component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); + component = qm.createComponent(component, false); + + new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); + + assertConditionWithTimeout(() -> NOTIFICATIONS.size() > 0, Duration.ofSeconds(5)); + assertThat(NOTIFICATIONS).anySatisfy(notification -> { + assertThat(notification.getScope()).isEqualTo(NotificationScope.SYSTEM.name()); + assertThat(notification.getLevel()).isEqualTo(NotificationLevel.WARNING); + assertThat(notification.getGroup()).isEqualTo(NotificationGroup.ANALYZER.name()); + assertThat(notification.getTitle()).isNotEmpty(); + assertThat(notification.getContent()).contains("Wed, 11 Nov 2021 11:11:11 GMT"); + assertThat(notification.getSubject()).isNull(); + }); + } + + @Test + public void testSendsUserAgent() { + mockServer + .when(request() + .withMethod("GET") + .withPath("/rest/.+")) + .respond(response() + .withStatusCode(404)); + + var project = new Project(); + project.setName("acme-app"); + project = qm.createProject(project, null, false); + + var component = new Component(); + component.setProject(project); + component.setGroup("com.fasterxml.woodstox"); + component.setName("woodstox-core"); + component.setVersion("5.0.0"); + component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); + component = qm.createComponent(component, false); + + new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); + + mockServer.verify( + request().withHeader("User-Agent", ManagedHttpClientFactory.getUserAgent()), + VerificationTimes.once() + ); + } + + private static final ConcurrentLinkedQueue NOTIFICATIONS = new ConcurrentLinkedQueue<>(); + + public static class NotificationSubscriber implements Subscriber { + + @Override + public void inform(final Notification notification) { + NOTIFICATIONS.add(notification); + } + + } + +} \ No newline at end of file From 9e45ee7f3d525a9b0971834e60f715c6362216ba Mon Sep 17 00:00:00 2001 From: mehab Date: Fri, 27 Jan 2023 19:32:50 +0000 Subject: [PATCH 09/31] added tests Signed-off-by: mehab --- .../tasks/VulnerabilityAnalysisTask.java | 2 +- .../tasks/scanners/VulnDbAnalysisTask.java | 16 +- .../org/dependencytrack/util/VulnDBUtil.java | 10 +- .../scanners/VulnDBAnalysisTaskTest.java | 500 +++++++++--------- 4 files changed, 276 insertions(+), 252 deletions(-) diff --git a/src/main/java/org/dependencytrack/tasks/VulnerabilityAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/VulnerabilityAnalysisTask.java index c601a8fe22..73153900d8 100644 --- a/src/main/java/org/dependencytrack/tasks/VulnerabilityAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/VulnerabilityAnalysisTask.java @@ -110,7 +110,7 @@ private void analyzeComponents(final QueryManager qm, final List comp */ final InternalAnalysisTask internalAnalysisTask = new InternalAnalysisTask(); final OssIndexAnalysisTask ossIndexAnalysisTask = new OssIndexAnalysisTask(); - final VulnDbAnalysisTask vulnDbAnalysisTask = new VulnDbAnalysisTask(); + final VulnDbAnalysisTask vulnDbAnalysisTask = new VulnDbAnalysisTask("https://vulndb.cyberriskanalytics.com"); final SnykAnalysisTask snykAnalysisTask = new SnykAnalysisTask(); for (final Component component : components) { inspectComponentReadiness(component, internalAnalysisTask, internalCandidates); diff --git a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java index d59152a417..b4fb0ef5a9 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java @@ -19,6 +19,7 @@ package org.dependencytrack.tasks.scanners; import alpine.common.logging.Logger; +import alpine.common.util.UrlUtil; import alpine.event.framework.Event; import alpine.event.framework.Subscriber; import alpine.model.ConfigProperty; @@ -35,6 +36,7 @@ import us.springett.vulndbdatamirror.parser.model.Results; import java.util.List; +import java.util.Optional; /** * Subscriber task that performs an analysis of component using VulnDB REST API. @@ -44,6 +46,10 @@ */ public class VulnDbAnalysisTask extends BaseComponentAnalyzerTask implements Subscriber { + public VulnDbAnalysisTask(String apiBaseUrl) { + this.apiBaseUrl = apiBaseUrl; + } + private static final Logger LOGGER = Logger.getLogger(VulnDbAnalysisTask.class); private static final String TARGET_HOST = "https://vulndb.cyberriskanalytics.com/"; private static final int PAGE_SIZE = 100; @@ -51,6 +57,8 @@ public class VulnDbAnalysisTask extends BaseComponentAnalyzerTask implements Sub private String apiConsumerKey; private String apiConsumerSecret; + private String apiBaseUrl; + public AnalyzerIdentity getAnalyzerIdentity() { return AnalyzerIdentity.VULNDB_ANALYZER; } @@ -72,6 +80,11 @@ public void inform(final Event e) { ConfigPropertyConstants.SCANNER_VULNDB_OAUTH1_CONSUMER_SECRET.getGroupName(), ConfigPropertyConstants.SCANNER_VULNDB_OAUTH1_CONSUMER_SECRET.getPropertyName() ); + if (this.apiBaseUrl == null) { + LOGGER.warn("No API base URL provided; Skipping"); + return; + } + if (apiConsumerKey == null || apiConsumerKey.getPropertyValue() == null) { LOGGER.warn("An OAuth 1.0a consumer key has not been specified for use with VulnDB. Skipping"); return; @@ -114,7 +127,7 @@ public boolean isCapable(final Component component) { * @param components a list of Components */ public void analyze(final List components) { - final VulnDBUtil api = new VulnDBUtil(this.apiConsumerKey, this.apiConsumerSecret); + final VulnDBUtil api = new VulnDBUtil(this.apiConsumerKey, this.apiConsumerSecret, this.apiBaseUrl); for (final Component component : components) { if (!component.isInternal() && isCapable(component) && !isCacheCurrent(Vulnerability.Source.VULNDB, TARGET_HOST, component.getCpe())) { @@ -153,4 +166,5 @@ private boolean processResults(final Results results, final Component component) return results.getPage() * PAGE_SIZE < results.getTotal(); } } + } diff --git a/src/main/java/org/dependencytrack/util/VulnDBUtil.java b/src/main/java/org/dependencytrack/util/VulnDBUtil.java index 8d2f4cdf35..304eb9951b 100644 --- a/src/main/java/org/dependencytrack/util/VulnDBUtil.java +++ b/src/main/java/org/dependencytrack/util/VulnDBUtil.java @@ -40,9 +40,13 @@ public class VulnDBUtil { private final String consumerKey; private final String consumerSecret; - public VulnDBUtil(String consumerKey, String consumerSecret) { + private final String apiBaseUrl; + + + public VulnDBUtil(String consumerKey, String consumerSecret, String apiBaseUrl) { this.consumerKey = consumerKey; this.consumerSecret = consumerSecret; + this.apiBaseUrl = apiBaseUrl; } private static final Logger LOGGER = LoggerFactory.getLogger(VulnDBUtil.class); @@ -56,7 +60,7 @@ public Results getVulnerabilitiesByCpe(String cpe, int size, int page) { LOGGER.error("An error occurred while URL encoding a CPE", var6); } - return this.getResults("https://vulndb.cyberriskanalytics.com/api/v1/vulnerabilities/find_by_cpe?&cpe=" + encodedCpe, Vulnerability.class, size, page); + return this.getResults(apiBaseUrl+"/api/v1/vulnerabilities/find_by_cpe?&cpe=" + encodedCpe, Vulnerability.class, size, page); } private Results getResults(String url, Class clazz, int size, int page) { @@ -106,7 +110,7 @@ private void logHttpResponseError(CloseableHttpResponse response) { } public Results parse(JSONObject jsonResponse, Class apiObject) { - LOGGER.debug("Parsing JSON node"); + LOGGER.debug("Parsing JSON response"); Results results = new Results(); results.setPage(jsonResponse.getInt("current_page")); results.setTotal(jsonResponse.getInt("total_entries")); diff --git a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java index 0a51ad00a8..0390c3f8b7 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java @@ -42,7 +42,9 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.mockserver.client.MockServerClient; import org.mockserver.integration.ClientAndServer; +import org.mockserver.model.Header; import org.mockserver.verify.VerificationTimes; import javax.jdo.Query; @@ -89,7 +91,7 @@ public void setUp() throws Exception { "secret"); qm.createConfigProperty(SCANNER_VULNDB_OAUTH1_CONSUMER_SECRET.getGroupName(), SCANNER_VULNDB_OAUTH1_CONSUMER_SECRET.getPropertyName(), - "secret", + DataEncryption.encryptAsString("secret"), IConfigProperty.PropertyType.STRING, "secret"); } @@ -111,14 +113,12 @@ public void testIsCapable() { final var asserts = new SoftAssertions(); for (final Map.Entry test : Map.of( - "pkg:maven/com.fasterxml.woodstox/woodstox-core", false, // Missing version - "pkg:golang/github.com/CycloneDX/cyclonedx-go@0.7.0", false, // Unsupported type - "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0", true, - "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz", true + "cpe:2.3:a:apache:log4j:2.0:-:*:*:*:*:*:*", true, + "cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*", true ).entrySet()) { final var component = new Component(); - component.setPurl(test.getKey()); - asserts.assertThat(new VulnDbAnalysisTask().isCapable(component)).isEqualTo(test.getValue()); + component.setCpe(test.getKey()); + asserts.assertThat(new VulnDbAnalysisTask("http://localhost:1080").isCapable(component)).isEqualTo(test.getValue()); } asserts.assertAll(); @@ -129,8 +129,9 @@ public void testAnalyzeWithNoIssues() { mockServer .when(request() .withMethod("GET") - .withPath("/rest/orgs/orgid/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues") - .withQueryStringParameter("version", "version")) + .withPath("/api/v1/vulnerabilities/find_by_cpe") + .withHeader(new Header("X-User-Agent", "VulnDB Data Mirror (https://github.com/stevespringett/vulndb-data-mirror)")) + .withQueryStringParameter("cpe", "cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*" )) .respond(response() .withStatusCode(200) .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") @@ -163,12 +164,17 @@ public void testAnalyzeWithNoIssues() { component.setGroup("com.fasterxml.woodstox"); component.setName("woodstox-core"); component.setVersion("6.4.0"); - component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@6.4.0?foo=bar#baz"); + component.setCpe("cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*"); component = qm.createComponent(component, false); - new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); + new VulnDbAnalysisTask("http://localhost:1080").inform(new VulnDbAnalysisEvent(component)); final List vulnerabilities = qm.getAllVulnerabilities(component); + String logMessages = mockServer + .retrieveLogMessages( + request() + ); + assertThat(vulnerabilities).hasSize(0); final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); @@ -176,246 +182,246 @@ public void testAnalyzeWithNoIssues() { assertThat(cacheEntries).hasSize(1); final ComponentAnalysisCache cacheEntry = cacheEntries.get(0); - assertThat(cacheEntry.getTarget()).isEqualTo("pkg:maven/com.fasterxml.woodstox/woodstox-core@6.4.0"); + assertThat(cacheEntry.getTarget()).isEqualTo("cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*"); assertThat(cacheEntry.getResult()) .containsEntry("vulnIds", Json.createArrayBuilder().build()); } - @Test - public void testAnalyzeWithError() { - mockServer - .when(request() - .withMethod("GET") - .withPath("/rest/orgs/orgid/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0/issues") - .withQueryStringParameter("version", "version")) - .respond(response() - .withStatusCode(400) - .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") - .withBody(""" - { - "jsonapi": { - "version": "1.0" - }, - "errors": [ - { - "id": "0f12fd75-c80a-4c15-929b-f7794eb3dd4f", - "links": { - "about": "https://docs.snyk.io/more-info/error-catalog#snyk-ossi-2010-invalid-purl-has-been-provided" - }, - "status": "400", - "code": "SNYK-OSSI-2010", - "title": "Invalid PURL has been provided", - "detail": "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0%", - "source": { - "pointer": "/orgs/0d581750-c5d7-4acf-9ff9-4a5bae31cbf1/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0%25/issues" - }, - "meta": { - "links": [ - "https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst" - ] - } - } - ] - } - """)); - - var project = new Project(); - project.setName("acme-app"); - project = qm.createProject(project, null, false); - - var component = new Component(); - component.setProject(project); - component.setGroup("com.fasterxml.woodstox"); - component.setName("woodstox-core"); - component.setVersion("5.0.0"); - component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); - component = qm.createComponent(component, false); - - new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); - - final List vulnerabilities = qm.getAllVulnerabilities(component); - assertThat(vulnerabilities).hasSize(0); - - final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); - assertThat(cacheQuery.executeList()).isEmpty(); - } - - @Test - public void testAnalyzeWithUnspecifiedError() { - mockServer - .when(request() - .withMethod("GET") - .withPath("/rest/orgs/orgid/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0/issues") - .withQueryStringParameter("version", "version")) - .respond(response() - .withStatusCode(403) - ); - - var project = new Project(); - project.setName("acme-app"); - project = qm.createProject(project, null, false); - - var component = new Component(); - component.setProject(project); - component.setGroup("com.fasterxml.woodstox"); - component.setName("woodstox-core"); - component.setVersion("5.0.0"); - component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); - component = qm.createComponent(component, false); - - new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); - - final List vulnerabilities = qm.getAllVulnerabilities(component); - assertThat(vulnerabilities).hasSize(0); - - final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); - assertThat(cacheQuery.executeList()).isEmpty(); - } - - @Test - public void testAnalyzeWithConnectionError() { - mockServer - .when(request().withPath("/rest/.+")) - .error(error().withDropConnection(true)); - - var project = new Project(); - project.setName("acme-app"); - project = qm.createProject(project, null, false); - - var component = new Component(); - component.setProject(project); - component.setGroup("com.fasterxml.woodstox"); - component.setName("woodstox-core"); - component.setVersion("5.0.0"); - component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); - component = qm.createComponent(component, false); - - new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); - - final List vulnerabilities = qm.getAllVulnerabilities(component); - assertThat(vulnerabilities).hasSize(0); - - final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); - assertThat(cacheQuery.executeList()).isEmpty(); - } - - @Test - public void testAnalyzeWithCurrentCache() { - var vuln = new Vulnerability(); - vuln.setVulnId("VULNDB-001"); - vuln.setSource(Vulnerability.Source.VULNDB); - vuln.setSeverity(Severity.HIGH); - vuln = qm.createVulnerability(vuln, false); - - qm.updateComponentAnalysisCache(ComponentAnalysisCache.CacheType.VULNERABILITY, "http://localhost:1080", - Vulnerability.Source.VULNDB.name(), "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0", new Date(), - Json.createObjectBuilder() - .add("vulnIds", Json.createArrayBuilder().add(vuln.getId())) - .build()); - - var project = new Project(); - project.setName("acme-app"); - project = qm.createProject(project, null, false); - - var component = new Component(); - component.setProject(project); - component.setGroup("com.fasterxml.woodstox"); - component.setName("woodstox-core"); - component.setVersion("5.0.0"); - component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); - component = qm.createComponent(component, false); - - new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); - - final List vulnerabilities = qm.getAllVulnerabilities(component); - assertThat(vulnerabilities).hasSize(1); - - mockServer.verifyZeroInteractions(); - } - - @Test - public void testAnalyzeWithDeprecatedApiVersion() throws Exception { - mockServer - .when(request() - .withMethod("GET") - .withPath("/rest/.+")) - .respond(response() - .withStatusCode(200) - .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") - .withHeader("Sunset", "Wed, 11 Nov 2021 11:11:11 GMT") - .withBody(""" - { - "jsonapi": { - "version": "1.0" - }, - "data": [], - "links": { - "self": "/orgs/da563045-a462-421a-ae47-53239fe46612/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues?version=2023-01-04&limit=1000&offset=0" - }, - "meta": { - "package": { - "name": "woodstox-core", - "type": "maven", - "url": "pkg:maven/com.fasterxml.woodstox/woodstox-core@6.4.0", - "version": "6.4.0" - } - } - } - """)); - - var project = new Project(); - project.setName("acme-app"); - project = qm.createProject(project, null, false); - - var component = new Component(); - component.setProject(project); - component.setGroup("com.fasterxml.woodstox"); - component.setName("woodstox-core"); - component.setVersion("5.0.0"); - component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); - component = qm.createComponent(component, false); - - new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); - - assertConditionWithTimeout(() -> NOTIFICATIONS.size() > 0, Duration.ofSeconds(5)); - assertThat(NOTIFICATIONS).anySatisfy(notification -> { - assertThat(notification.getScope()).isEqualTo(NotificationScope.SYSTEM.name()); - assertThat(notification.getLevel()).isEqualTo(NotificationLevel.WARNING); - assertThat(notification.getGroup()).isEqualTo(NotificationGroup.ANALYZER.name()); - assertThat(notification.getTitle()).isNotEmpty(); - assertThat(notification.getContent()).contains("Wed, 11 Nov 2021 11:11:11 GMT"); - assertThat(notification.getSubject()).isNull(); - }); - } - - @Test - public void testSendsUserAgent() { - mockServer - .when(request() - .withMethod("GET") - .withPath("/rest/.+")) - .respond(response() - .withStatusCode(404)); - - var project = new Project(); - project.setName("acme-app"); - project = qm.createProject(project, null, false); - - var component = new Component(); - component.setProject(project); - component.setGroup("com.fasterxml.woodstox"); - component.setName("woodstox-core"); - component.setVersion("5.0.0"); - component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); - component = qm.createComponent(component, false); - - new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); - - mockServer.verify( - request().withHeader("User-Agent", ManagedHttpClientFactory.getUserAgent()), - VerificationTimes.once() - ); - } +// @Test +// public void testAnalyzeWithError() { +// mockServer +// .when(request() +// .withMethod("GET") +// .withPath("/rest/orgs/orgid/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0/issues") +// .withQueryStringParameter("version", "version")) +// .respond(response() +// .withStatusCode(400) +// .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") +// .withBody(""" +// { +// "jsonapi": { +// "version": "1.0" +// }, +// "errors": [ +// { +// "id": "0f12fd75-c80a-4c15-929b-f7794eb3dd4f", +// "links": { +// "about": "https://docs.snyk.io/more-info/error-catalog#snyk-ossi-2010-invalid-purl-has-been-provided" +// }, +// "status": "400", +// "code": "SNYK-OSSI-2010", +// "title": "Invalid PURL has been provided", +// "detail": "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0%", +// "source": { +// "pointer": "/orgs/0d581750-c5d7-4acf-9ff9-4a5bae31cbf1/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0%25/issues" +// }, +// "meta": { +// "links": [ +// "https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst" +// ] +// } +// } +// ] +// } +// """)); +// +// var project = new Project(); +// project.setName("acme-app"); +// project = qm.createProject(project, null, false); +// +// var component = new Component(); +// component.setProject(project); +// component.setGroup("com.fasterxml.woodstox"); +// component.setName("woodstox-core"); +// component.setVersion("5.0.0"); +// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); +// component = qm.createComponent(component, false); +// +// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); +// +// final List vulnerabilities = qm.getAllVulnerabilities(component); +// assertThat(vulnerabilities).hasSize(0); +// +// final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); +// assertThat(cacheQuery.executeList()).isEmpty(); +// } +// +// @Test +// public void testAnalyzeWithUnspecifiedError() { +// mockServer +// .when(request() +// .withMethod("GET") +// .withPath("/rest/orgs/orgid/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0/issues") +// .withQueryStringParameter("version", "version")) +// .respond(response() +// .withStatusCode(403) +// ); +// +// var project = new Project(); +// project.setName("acme-app"); +// project = qm.createProject(project, null, false); +// +// var component = new Component(); +// component.setProject(project); +// component.setGroup("com.fasterxml.woodstox"); +// component.setName("woodstox-core"); +// component.setVersion("5.0.0"); +// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); +// component = qm.createComponent(component, false); +// +// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); +// +// final List vulnerabilities = qm.getAllVulnerabilities(component); +// assertThat(vulnerabilities).hasSize(0); +// +// final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); +// assertThat(cacheQuery.executeList()).isEmpty(); +// } +// +// @Test +// public void testAnalyzeWithConnectionError() { +// mockServer +// .when(request().withPath("/rest/.+")) +// .error(error().withDropConnection(true)); +// +// var project = new Project(); +// project.setName("acme-app"); +// project = qm.createProject(project, null, false); +// +// var component = new Component(); +// component.setProject(project); +// component.setGroup("com.fasterxml.woodstox"); +// component.setName("woodstox-core"); +// component.setVersion("5.0.0"); +// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); +// component = qm.createComponent(component, false); +// +// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); +// +// final List vulnerabilities = qm.getAllVulnerabilities(component); +// assertThat(vulnerabilities).hasSize(0); +// +// final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); +// assertThat(cacheQuery.executeList()).isEmpty(); +// } +// +// @Test +// public void testAnalyzeWithCurrentCache() { +// var vuln = new Vulnerability(); +// vuln.setVulnId("VULNDB-001"); +// vuln.setSource(Vulnerability.Source.VULNDB); +// vuln.setSeverity(Severity.HIGH); +// vuln = qm.createVulnerability(vuln, false); +// +// qm.updateComponentAnalysisCache(ComponentAnalysisCache.CacheType.VULNERABILITY, "http://localhost:1080", +// Vulnerability.Source.VULNDB.name(), "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0", new Date(), +// Json.createObjectBuilder() +// .add("vulnIds", Json.createArrayBuilder().add(vuln.getId())) +// .build()); +// +// var project = new Project(); +// project.setName("acme-app"); +// project = qm.createProject(project, null, false); +// +// var component = new Component(); +// component.setProject(project); +// component.setGroup("com.fasterxml.woodstox"); +// component.setName("woodstox-core"); +// component.setVersion("5.0.0"); +// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); +// component = qm.createComponent(component, false); +// +// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); +// +// final List vulnerabilities = qm.getAllVulnerabilities(component); +// assertThat(vulnerabilities).hasSize(1); +// +// mockServer.verifyZeroInteractions(); +// } +// +// @Test +// public void testAnalyzeWithDeprecatedApiVersion() throws Exception { +// mockServer +// .when(request() +// .withMethod("GET") +// .withPath("/rest/.+")) +// .respond(response() +// .withStatusCode(200) +// .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") +// .withHeader("Sunset", "Wed, 11 Nov 2021 11:11:11 GMT") +// .withBody(""" +// { +// "jsonapi": { +// "version": "1.0" +// }, +// "data": [], +// "links": { +// "self": "/orgs/da563045-a462-421a-ae47-53239fe46612/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues?version=2023-01-04&limit=1000&offset=0" +// }, +// "meta": { +// "package": { +// "name": "woodstox-core", +// "type": "maven", +// "url": "pkg:maven/com.fasterxml.woodstox/woodstox-core@6.4.0", +// "version": "6.4.0" +// } +// } +// } +// """)); +// +// var project = new Project(); +// project.setName("acme-app"); +// project = qm.createProject(project, null, false); +// +// var component = new Component(); +// component.setProject(project); +// component.setGroup("com.fasterxml.woodstox"); +// component.setName("woodstox-core"); +// component.setVersion("5.0.0"); +// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); +// component = qm.createComponent(component, false); +// +// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); +// +// assertConditionWithTimeout(() -> NOTIFICATIONS.size() > 0, Duration.ofSeconds(5)); +// assertThat(NOTIFICATIONS).anySatisfy(notification -> { +// assertThat(notification.getScope()).isEqualTo(NotificationScope.SYSTEM.name()); +// assertThat(notification.getLevel()).isEqualTo(NotificationLevel.WARNING); +// assertThat(notification.getGroup()).isEqualTo(NotificationGroup.ANALYZER.name()); +// assertThat(notification.getTitle()).isNotEmpty(); +// assertThat(notification.getContent()).contains("Wed, 11 Nov 2021 11:11:11 GMT"); +// assertThat(notification.getSubject()).isNull(); +// }); +// } +// +// @Test +// public void testSendsUserAgent() { +// mockServer +// .when(request() +// .withMethod("GET") +// .withPath("/rest/.+")) +// .respond(response() +// .withStatusCode(404)); +// +// var project = new Project(); +// project.setName("acme-app"); +// project = qm.createProject(project, null, false); +// +// var component = new Component(); +// component.setProject(project); +// component.setGroup("com.fasterxml.woodstox"); +// component.setName("woodstox-core"); +// component.setVersion("5.0.0"); +// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); +// component = qm.createComponent(component, false); +// +// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); +// +// mockServer.verify( +// request().withHeader("User-Agent", ManagedHttpClientFactory.getUserAgent()), +// VerificationTimes.once() +// ); +// } private static final ConcurrentLinkedQueue NOTIFICATIONS = new ConcurrentLinkedQueue<>(); From abba6a7fc5fdf9ac76ae85923a759d7604f658c0 Mon Sep 17 00:00:00 2001 From: mehab Date: Tue, 31 Jan 2023 13:25:12 +0000 Subject: [PATCH 10/31] test updated Signed-off-by: mehab --- .../scanners/VulnDBAnalysisTaskTest.java | 97 +++++++++++++++---- 1 file changed, 80 insertions(+), 17 deletions(-) diff --git a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java index 0390c3f8b7..7674aed62e 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java @@ -135,24 +135,87 @@ public void testAnalyzeWithNoIssues() { .respond(response() .withStatusCode(200) .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") - .withBody(""" + .withBody(""" { - "jsonapi": { - "version": "1.0" - }, - "data": [], - "links": { - "self": "/orgs/da563045-a462-421a-ae47-53239fe46612/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues?version=2023-01-04&limit=1000&offset=0" - }, - "meta": { - "package": { - "name": "woodstox-core", - "type": "maven", - "url": "pkg:maven/com.fasterxml.woodstox/woodstox-core@6.4.0", - "version": "6.4.0" - } - } - } + "current_page": 1, + "total_entries": 1, + "results": [ + { + "vulndb_id": 1, + "title": "test title", + "classifications": [ + { + "id": 1, + "name": "test vulnerability", + "longname": "test vulnerability 1 1", + "description": "test test", + "mediumtext": "some text" + } + ], + "authors": [ + { + "id": 23, + "name": "test author", + "company": "test company" + } + ], + "ext_references": [ + { + "type": "external test reference", + "value": "external test reference value" + } + ], + "ext_texts": [ + { + "type": "external test texts", + "value": "external test texts value" + } + ], + "cvss_metrics": [ + + ], + "cvss_version_three_metrics": [ + + ], + "nvd_additional_information": [ + { + "summary": "test summary", + "cwe_id": "test1", + "cve_id": "test4" + } + ], + "vendors": [ + { + "vendor": { + "id": 1, + "name": "vendor one test", + "short_name": "test", + "vendor_url": "http://test.com", + "products": [ + { + "id": 45, + "name": "test product name", + "versions": [ + { + "id": 2, + "name": "version 2", + "affected": false, + "cpe": [ + { + "cpe": "test cpe", + "type": "test type" + } + ] + } + ] + } + ] + } + } + ] + } + ] + } """)); var project = new Project(); From abd98a9af5623c6edf0c88da35b504f463706115 Mon Sep 17 00:00:00 2001 From: mehab Date: Tue, 31 Jan 2023 13:38:55 +0000 Subject: [PATCH 11/31] test updated Signed-off-by: mehab --- .../persistence/VulnerabilityQueryManager.java | 7 ++++++- .../tasks/scanners/VulnDBAnalysisTaskTest.java | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java b/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java index e4495d32db..b11efefe03 100644 --- a/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java @@ -564,7 +564,12 @@ public List getVulnerabilityAliases(Vulnerability vulnerabil } else { query = pm.newQuery(VulnerabilityAlias.class, "internalId == :internalId"); } - return (List)query.execute(vulnerability.getVulnId()); + try{ + return (List)query.execute(vulnerability.getVulnId()); + } catch (Exception ex){ + return Collections.emptyList(); + } +// return (List)query.execute(vulnerability.getVulnId()); } /** diff --git a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java index 7674aed62e..41328e5f23 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java @@ -233,12 +233,12 @@ public void testAnalyzeWithNoIssues() { new VulnDbAnalysisTask("http://localhost:1080").inform(new VulnDbAnalysisEvent(component)); final List vulnerabilities = qm.getAllVulnerabilities(component); - String logMessages = mockServer - .retrieveLogMessages( - request() - ); +// String logMessages = mockServer +// .retrieveLogMessages( +// request() +// ); - assertThat(vulnerabilities).hasSize(0); + assertThat(vulnerabilities).hasSize(1); final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); final List cacheEntries = cacheQuery.executeList(); From 3ccef341a6d86054a3463bd6a9ce486e412ceb5a Mon Sep 17 00:00:00 2001 From: mehab Date: Tue, 31 Jan 2023 14:43:21 +0000 Subject: [PATCH 12/31] test changes Signed-off-by: mehab --- .../persistence/VulnerabilityQueryManager.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java b/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java index b11efefe03..26db6f352d 100644 --- a/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java @@ -22,6 +22,7 @@ import alpine.persistence.PaginatedResult; import alpine.resources.AlpineRequest; import org.apache.commons.lang3.StringUtils; +import org.datanucleus.exceptions.NucleusUserException; import org.dependencytrack.event.IndexEvent; import org.dependencytrack.model.AffectedVersionAttribution; import org.dependencytrack.model.Analysis; @@ -33,6 +34,7 @@ import org.dependencytrack.model.VulnerableSoftware; import org.dependencytrack.tasks.scanners.AnalyzerIdentity; +import javax.jdo.JDOUserException; import javax.jdo.PersistenceManager; import javax.jdo.Query; import java.util.ArrayList; @@ -566,10 +568,10 @@ public List getVulnerabilityAliases(Vulnerability vulnerabil } try{ return (List)query.execute(vulnerability.getVulnId()); - } catch (Exception ex){ + } catch (JDOUserException ex){ return Collections.emptyList(); } -// return (List)query.execute(vulnerability.getVulnId()); + // return (List)query.execute(vulnerability.getVulnId()); } /** From 7298bdef2e01aaabac01d1748eae6e5b5251e6fd Mon Sep 17 00:00:00 2001 From: mehab Date: Tue, 31 Jan 2023 15:01:28 +0000 Subject: [PATCH 13/31] proper fix --- .../persistence/VulnerabilityQueryManager.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java b/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java index 26db6f352d..0e154e1a1c 100644 --- a/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java @@ -562,16 +562,11 @@ public List getVulnerabilityAliases(Vulnerability vulnerabil } else if (Vulnerability.Source.SNYK.name().equals(vulnerability.getSource())) { query = pm.newQuery(VulnerabilityAlias.class, "snykId == :snykId"); } else if (Vulnerability.Source.VULNDB.name().equals(vulnerability.getSource())) { - query = pm.newQuery(VulnerabilityAlias.class, "vulnDb == :vulnDb"); + query = pm.newQuery(VulnerabilityAlias.class, "vulnDbId == :vulnDb"); } else { query = pm.newQuery(VulnerabilityAlias.class, "internalId == :internalId"); } - try{ - return (List)query.execute(vulnerability.getVulnId()); - } catch (JDOUserException ex){ - return Collections.emptyList(); - } - // return (List)query.execute(vulnerability.getVulnId()); + return (List)query.execute(vulnerability.getVulnId()); } /** From bedb3832495471ef4413a9330b906016f3c589b9 Mon Sep 17 00:00:00 2001 From: mehab Date: Tue, 31 Jan 2023 22:09:24 +0000 Subject: [PATCH 14/31] tests added and workiing Signed-off-by: mehab --- .../VulnerabilityQueryManager.java | 2 - .../tasks/scanners/VulnDbAnalysisTask.java | 9 +- .../scanners/VulnDBAnalysisTaskTest.java | 335 +++++------------- 3 files changed, 92 insertions(+), 254 deletions(-) diff --git a/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java b/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java index 0e154e1a1c..30b0508f43 100644 --- a/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java @@ -22,7 +22,6 @@ import alpine.persistence.PaginatedResult; import alpine.resources.AlpineRequest; import org.apache.commons.lang3.StringUtils; -import org.datanucleus.exceptions.NucleusUserException; import org.dependencytrack.event.IndexEvent; import org.dependencytrack.model.AffectedVersionAttribution; import org.dependencytrack.model.Analysis; @@ -34,7 +33,6 @@ import org.dependencytrack.model.VulnerableSoftware; import org.dependencytrack.tasks.scanners.AnalyzerIdentity; -import javax.jdo.JDOUserException; import javax.jdo.PersistenceManager; import javax.jdo.Query; import java.util.ArrayList; diff --git a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java index b4fb0ef5a9..c5582e2d7e 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java @@ -104,7 +104,7 @@ public void inform(final Event e) { final VulnDbAnalysisEvent event = (VulnDbAnalysisEvent) e; vulnerabilityAnalysisLevel = event.getVulnerabilityAnalysisLevel(); LOGGER.info("Starting VulnDB analysis task"); - if (event.getComponents().size() > 0) { + if (!event.getComponents().isEmpty()) { analyze(event.getComponents()); } LOGGER.info("VulnDB analysis complete"); @@ -129,6 +129,10 @@ public boolean isCapable(final Component component) { public void analyze(final List components) { final VulnDBUtil api = new VulnDBUtil(this.apiConsumerKey, this.apiConsumerSecret, this.apiBaseUrl); for (final Component component : components) { + if (isCacheCurrent(Vulnerability.Source.VULNDB, apiBaseUrl, component.getCpe())) { + applyAnalysisFromCache(Vulnerability.Source.VULNDB, apiBaseUrl, component.getCpe(),component, AnalyzerIdentity.VULNDB_ANALYZER, vulnerabilityAnalysisLevel); + }else + { if (!component.isInternal() && isCapable(component) && !isCacheCurrent(Vulnerability.Source.VULNDB, TARGET_HOST, component.getCpe())) { int page = 1; @@ -144,6 +148,7 @@ public void analyze(final List components) { } } } + } } } @@ -162,7 +167,7 @@ private boolean processResults(final Results results, final Component component) qm.addVulnerability(vulnerability, vulnerableComponent, this.getAnalyzerIdentity()); addVulnerabilityToCache(vulnerableComponent, vulnerability); } - updateAnalysisCacheStats(qm, Vulnerability.Source.VULNDB, TARGET_HOST, vulnerableComponent.getCpe(), component.getCacheResult()); + updateAnalysisCacheStats(qm, Vulnerability.Source.VULNDB, TARGET_HOST, vulnerableComponent.getCpe(), vulnerableComponent.getCacheResult()); return results.getPage() * PAGE_SIZE < results.getTotal(); } } diff --git a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java index 41328e5f23..ad5416dc73 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java @@ -20,7 +20,6 @@ import alpine.model.IConfigProperty; import alpine.notification.Notification; -import alpine.notification.NotificationLevel; import alpine.notification.NotificationService; import alpine.notification.Subscriber; import alpine.notification.Subscription; @@ -28,37 +27,30 @@ import org.apache.http.HttpHeaders; import org.assertj.core.api.SoftAssertions; import org.dependencytrack.PersistenceCapableTest; -import org.dependencytrack.common.ManagedHttpClientFactory; import org.dependencytrack.event.VulnDbAnalysisEvent; import org.dependencytrack.model.Component; import org.dependencytrack.model.ComponentAnalysisCache; import org.dependencytrack.model.Project; import org.dependencytrack.model.Severity; import org.dependencytrack.model.Vulnerability; -import org.dependencytrack.notification.NotificationGroup; -import org.dependencytrack.notification.NotificationScope; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.mockserver.client.MockServerClient; import org.mockserver.integration.ClientAndServer; import org.mockserver.model.Header; -import org.mockserver.verify.VerificationTimes; import javax.jdo.Query; import javax.json.Json; -import java.time.Duration; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentLinkedQueue; import static org.assertj.core.api.Assertions.assertThat; -import static org.dependencytrack.assertion.Assertions.assertConditionWithTimeout; import static org.dependencytrack.model.ConfigPropertyConstants.*; -import static org.mockserver.model.HttpError.error; import static org.mockserver.model.HttpRequest.request; import static org.mockserver.model.HttpResponse.response; @@ -125,7 +117,7 @@ public void testIsCapable() { } @Test - public void testAnalyzeWithNoIssues() { + public void testAnalyzeWithOneIssue() { mockServer .when(request() .withMethod("GET") @@ -233,10 +225,6 @@ public void testAnalyzeWithNoIssues() { new VulnDbAnalysisTask("http://localhost:1080").inform(new VulnDbAnalysisEvent(component)); final List vulnerabilities = qm.getAllVulnerabilities(component); -// String logMessages = mockServer -// .retrieveLogMessages( -// request() -// ); assertThat(vulnerabilities).hasSize(1); @@ -246,245 +234,92 @@ public void testAnalyzeWithNoIssues() { final ComponentAnalysisCache cacheEntry = cacheEntries.get(0); assertThat(cacheEntry.getTarget()).isEqualTo("cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*"); + List result = new ArrayList(); + result.add(1); assertThat(cacheEntry.getResult()) - .containsEntry("vulnIds", Json.createArrayBuilder().build()); + .containsEntry("vulnIds", Json.createArrayBuilder(result).build()); } -// @Test -// public void testAnalyzeWithError() { -// mockServer -// .when(request() -// .withMethod("GET") -// .withPath("/rest/orgs/orgid/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0/issues") -// .withQueryStringParameter("version", "version")) -// .respond(response() -// .withStatusCode(400) -// .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") -// .withBody(""" -// { -// "jsonapi": { -// "version": "1.0" -// }, -// "errors": [ -// { -// "id": "0f12fd75-c80a-4c15-929b-f7794eb3dd4f", -// "links": { -// "about": "https://docs.snyk.io/more-info/error-catalog#snyk-ossi-2010-invalid-purl-has-been-provided" -// }, -// "status": "400", -// "code": "SNYK-OSSI-2010", -// "title": "Invalid PURL has been provided", -// "detail": "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0%", -// "source": { -// "pointer": "/orgs/0d581750-c5d7-4acf-9ff9-4a5bae31cbf1/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0%25/issues" -// }, -// "meta": { -// "links": [ -// "https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst" -// ] -// } -// } -// ] -// } -// """)); -// -// var project = new Project(); -// project.setName("acme-app"); -// project = qm.createProject(project, null, false); -// -// var component = new Component(); -// component.setProject(project); -// component.setGroup("com.fasterxml.woodstox"); -// component.setName("woodstox-core"); -// component.setVersion("5.0.0"); -// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); -// component = qm.createComponent(component, false); -// -// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); -// -// final List vulnerabilities = qm.getAllVulnerabilities(component); -// assertThat(vulnerabilities).hasSize(0); -// -// final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); -// assertThat(cacheQuery.executeList()).isEmpty(); -// } -// -// @Test -// public void testAnalyzeWithUnspecifiedError() { -// mockServer -// .when(request() -// .withMethod("GET") -// .withPath("/rest/orgs/orgid/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%405.0.0/issues") -// .withQueryStringParameter("version", "version")) -// .respond(response() -// .withStatusCode(403) -// ); -// -// var project = new Project(); -// project.setName("acme-app"); -// project = qm.createProject(project, null, false); -// -// var component = new Component(); -// component.setProject(project); -// component.setGroup("com.fasterxml.woodstox"); -// component.setName("woodstox-core"); -// component.setVersion("5.0.0"); -// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); -// component = qm.createComponent(component, false); -// -// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); -// -// final List vulnerabilities = qm.getAllVulnerabilities(component); -// assertThat(vulnerabilities).hasSize(0); -// -// final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); -// assertThat(cacheQuery.executeList()).isEmpty(); -// } -// -// @Test -// public void testAnalyzeWithConnectionError() { -// mockServer -// .when(request().withPath("/rest/.+")) -// .error(error().withDropConnection(true)); -// -// var project = new Project(); -// project.setName("acme-app"); -// project = qm.createProject(project, null, false); -// -// var component = new Component(); -// component.setProject(project); -// component.setGroup("com.fasterxml.woodstox"); -// component.setName("woodstox-core"); -// component.setVersion("5.0.0"); -// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); -// component = qm.createComponent(component, false); -// -// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(List.of(component))); -// -// final List vulnerabilities = qm.getAllVulnerabilities(component); -// assertThat(vulnerabilities).hasSize(0); -// -// final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); -// assertThat(cacheQuery.executeList()).isEmpty(); -// } -// -// @Test -// public void testAnalyzeWithCurrentCache() { -// var vuln = new Vulnerability(); -// vuln.setVulnId("VULNDB-001"); -// vuln.setSource(Vulnerability.Source.VULNDB); -// vuln.setSeverity(Severity.HIGH); -// vuln = qm.createVulnerability(vuln, false); -// -// qm.updateComponentAnalysisCache(ComponentAnalysisCache.CacheType.VULNERABILITY, "http://localhost:1080", -// Vulnerability.Source.VULNDB.name(), "pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0", new Date(), -// Json.createObjectBuilder() -// .add("vulnIds", Json.createArrayBuilder().add(vuln.getId())) -// .build()); -// -// var project = new Project(); -// project.setName("acme-app"); -// project = qm.createProject(project, null, false); -// -// var component = new Component(); -// component.setProject(project); -// component.setGroup("com.fasterxml.woodstox"); -// component.setName("woodstox-core"); -// component.setVersion("5.0.0"); -// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); -// component = qm.createComponent(component, false); -// -// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); -// -// final List vulnerabilities = qm.getAllVulnerabilities(component); -// assertThat(vulnerabilities).hasSize(1); -// -// mockServer.verifyZeroInteractions(); -// } -// -// @Test -// public void testAnalyzeWithDeprecatedApiVersion() throws Exception { -// mockServer -// .when(request() -// .withMethod("GET") -// .withPath("/rest/.+")) -// .respond(response() -// .withStatusCode(200) -// .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") -// .withHeader("Sunset", "Wed, 11 Nov 2021 11:11:11 GMT") -// .withBody(""" -// { -// "jsonapi": { -// "version": "1.0" -// }, -// "data": [], -// "links": { -// "self": "/orgs/da563045-a462-421a-ae47-53239fe46612/packages/pkg%3Amaven%2Fcom.fasterxml.woodstox%2Fwoodstox-core%406.4.0/issues?version=2023-01-04&limit=1000&offset=0" -// }, -// "meta": { -// "package": { -// "name": "woodstox-core", -// "type": "maven", -// "url": "pkg:maven/com.fasterxml.woodstox/woodstox-core@6.4.0", -// "version": "6.4.0" -// } -// } -// } -// """)); -// -// var project = new Project(); -// project.setName("acme-app"); -// project = qm.createProject(project, null, false); -// -// var component = new Component(); -// component.setProject(project); -// component.setGroup("com.fasterxml.woodstox"); -// component.setName("woodstox-core"); -// component.setVersion("5.0.0"); -// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); -// component = qm.createComponent(component, false); -// -// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); -// -// assertConditionWithTimeout(() -> NOTIFICATIONS.size() > 0, Duration.ofSeconds(5)); -// assertThat(NOTIFICATIONS).anySatisfy(notification -> { -// assertThat(notification.getScope()).isEqualTo(NotificationScope.SYSTEM.name()); -// assertThat(notification.getLevel()).isEqualTo(NotificationLevel.WARNING); -// assertThat(notification.getGroup()).isEqualTo(NotificationGroup.ANALYZER.name()); -// assertThat(notification.getTitle()).isNotEmpty(); -// assertThat(notification.getContent()).contains("Wed, 11 Nov 2021 11:11:11 GMT"); -// assertThat(notification.getSubject()).isNull(); -// }); -// } -// -// @Test -// public void testSendsUserAgent() { -// mockServer -// .when(request() -// .withMethod("GET") -// .withPath("/rest/.+")) -// .respond(response() -// .withStatusCode(404)); -// -// var project = new Project(); -// project.setName("acme-app"); -// project = qm.createProject(project, null, false); -// -// var component = new Component(); -// component.setProject(project); -// component.setGroup("com.fasterxml.woodstox"); -// component.setName("woodstox-core"); -// component.setVersion("5.0.0"); -// component.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0?foo=bar#baz"); -// component = qm.createComponent(component, false); -// -// new VulnDbAnalysisTask().inform(new VulnDbAnalysisEvent(component)); -// -// mockServer.verify( -// request().withHeader("User-Agent", ManagedHttpClientFactory.getUserAgent()), -// VerificationTimes.once() -// ); -// } + @Test + public void testAnalyzeWithNoIssue() { + mockServer + .when(request() + .withMethod("GET") + .withPath("/api/v1/vulnerabilities/find_by_cpe") + .withHeader(new Header("X-User-Agent", "VulnDB Data Mirror (https://github.com/stevespringett/vulndb-data-mirror)")) + .withQueryStringParameter("cpe", "cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*" )) + .respond(response() + .withStatusCode(200) + .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") + .withBody(""" + { + "current_page": 1, + "total_entries": 1, + "results": [] + } + """)); + + var project = new Project(); + project.setName("acme-app"); + project = qm.createProject(project, null, false); + + var component = new Component(); + component.setProject(project); + component.setGroup("com.fasterxml.woodstox"); + component.setName("woodstox-core"); + component.setVersion("6.4.0"); + component.setCpe("cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*"); + component = qm.createComponent(component, false); + + new VulnDbAnalysisTask("http://localhost:1080").inform(new VulnDbAnalysisEvent(component)); + + final List vulnerabilities = qm.getAllVulnerabilities(component); + + assertThat(vulnerabilities).hasSize(0); + + final Query cacheQuery = qm.getPersistenceManager().newQuery(ComponentAnalysisCache.class); + final List cacheEntries = cacheQuery.executeList(); + assertThat(cacheEntries).hasSize(1); + + final ComponentAnalysisCache cacheEntry = cacheEntries.get(0); + assertThat(cacheEntry.getTarget()).isEqualTo("cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*"); + assertThat(cacheEntry.getResult()) + .isNull(); + } + + @Test + public void testAnalyzeWithCurrentCache() { + var vuln = new Vulnerability(); + vuln.setVulnId("VULNDB-001"); + vuln.setSource(Vulnerability.Source.VULNDB); + vuln.setSeverity(Severity.HIGH); + vuln = qm.createVulnerability(vuln, false); + + qm.updateComponentAnalysisCache(ComponentAnalysisCache.CacheType.VULNERABILITY, "http://localhost:1080", + Vulnerability.Source.VULNDB.name(), "cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*", new Date(), + Json.createObjectBuilder() + .add("vulnIds", Json.createArrayBuilder().add(vuln.getId())) + .build()); + + var project = new Project(); + project.setName("acme-app"); + project = qm.createProject(project, null, false); + + var component = new Component(); + component.setProject(project); + component.setGroup("com.fasterxml.woodstox"); + component.setName("woodstox-core"); + component.setVersion("5.0.0"); + component.setCpe("cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*"); + component = qm.createComponent(component, false); + + new VulnDbAnalysisTask("http://localhost:1080").inform(new VulnDbAnalysisEvent(component)); + + final List vulnerabilities = qm.getAllVulnerabilities(component); + assertThat(vulnerabilities).hasSize(1); + + mockServer.verifyZeroInteractions(); + } private static final ConcurrentLinkedQueue NOTIFICATIONS = new ConcurrentLinkedQueue<>(); From f24701a0cea7c27cab8ab1e87eefa2f8c1613e87 Mon Sep 17 00:00:00 2001 From: mehab Date: Wed, 1 Feb 2023 09:53:15 +0000 Subject: [PATCH 15/31] PR review fixes Signed-off-by: mehab --- .../defectdojo/DefectDojoClient.java | 4 +-- .../publisher/AbstractWebhookPublisher.java | 25 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java index b7a36c3825..f6a5ca4b58 100644 --- a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java +++ b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java @@ -41,6 +41,7 @@ import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.List; @@ -87,8 +88,7 @@ public void uploadDependencyTrackFindings(final String token, final String engag uploader.handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } } catch (IOException ex) { - LOGGER.error("Error while sending request from upload DT findings defectDojo Client" + ex.getMessage()); - LOGGER.error("Error while sending request from upload DT findings defectDojo Client" + ex.getStackTrace()); + LOGGER.error("Error while sending request from upload DT findings defectDojo Client" + ex.getMessage()+" Stack trace: "+ Arrays.toString(ex.getStackTrace())); } } diff --git a/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java b/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java index 3fc2765d21..7f87d2f300 100644 --- a/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java +++ b/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java @@ -18,7 +18,6 @@ */ package org.dependencytrack.notification.publisher; -import alpine.common.logging.Logger; import alpine.notification.Notification; import alpine.notification.NotificationLevel; import io.pebbletemplates.pebble.template.PebbleTemplate; @@ -32,25 +31,25 @@ import org.dependencytrack.notification.NotificationGroup; import org.dependencytrack.notification.NotificationScope; import org.dependencytrack.util.HttpUtil; +import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.json.JsonObject; import java.io.IOException; public abstract class AbstractWebhookPublisher implements Publisher { - private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AbstractWebhookPublisher.class); - + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractWebhookPublisher.class); public void publish(final String publisherName, final PebbleTemplate template, final Notification notification, final JsonObject config) { - final Logger logger = Logger.getLogger(this.getClass()); - logger.debug("Preparing to publish " + publisherName + " notification"); + + LOGGER.debug("Preparing to publish " + publisherName + " notification"); if (config == null) { - logger.warn("No configuration found. Skipping notification."); + LOGGER.warn("No configuration found. Skipping notification."); return; } final String destination = getDestinationUrl(config); final String content = prepareTemplate(notification, template); if (destination == null || content == null) { - logger.warn("A destination or template was not found. Skipping notification"); + LOGGER.warn("A destination or template was not found. Skipping notification"); return; } final String mimeType = getTemplateMimeType(config); @@ -62,7 +61,7 @@ public void publish(final String publisherName, final PebbleTemplate template, f try { credentials = getBasicAuthCredentials(); } catch (PublisherException e) { - logger.warn("An error occurred during the retrieval of credentials needed for notification publication. Skipping notification", e); + LOGGER.warn("An error occurred during the retrieval of credentials needed for notification publication. Skipping notification", e); return; } if (credentials != null) { @@ -71,11 +70,11 @@ public void publish(final String publisherName, final PebbleTemplate template, f request.setEntity(new StringEntity(content)); final CloseableHttpResponse response = HttpClientPool.getClient().execute(request); if (response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() >= 300) { - logger.error("An error was encountered publishing notification to " + publisherName); - logger.error("HTTP Status : " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); - logger.error("Destination: " + destination); - logger.error("Response: " + EntityUtils.toString(response.getEntity())); - logger.debug(content); + LOGGER.error("An error was encountered publishing notification to " + publisherName); + LOGGER.error("HTTP Status : " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); + LOGGER.error("Destination: " + destination); + LOGGER.error("Response: " + EntityUtils.toString(response.getEntity())); + LOGGER.debug(content); } }catch (IOException ex){ handleRequestException(LOGGER, ex); From d2bdcad3a93cc03ffeed7e5229416fbb81d15c7f Mon Sep 17 00:00:00 2001 From: mehab Date: Wed, 1 Feb 2023 12:37:54 +0000 Subject: [PATCH 16/31] removed problematic dependency Signed-off-by: mehab --- pom.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pom.xml b/pom.xml index 0b659c94f7..67904749c3 100644 --- a/pom.xml +++ b/pom.xml @@ -236,6 +236,10 @@ io.github.openunirest open-unirest-java + + com.google.code.gson + gson + @@ -243,6 +247,14 @@ woodstox-core ${lib.woodstox.version} + + + + com.google.code.gson + gson + 2.8.9 + + org.apache.maven From 18524f76e8b4fd04c719d1870db81015c2c2094d Mon Sep 17 00:00:00 2001 From: mehab Date: Wed, 1 Feb 2023 14:36:48 +0000 Subject: [PATCH 17/31] removed vulndbdatamirror library Signed-off-by: mehab --- pom.xml | 49 +-- .../model/VulnDb/ApiObject.java | 7 + .../dependencytrack/model/VulnDb/Author.java | 62 ++++ .../model/VulnDb/Classification.java | 52 +++ .../org/dependencytrack/model/VulnDb/Cpe.java | 25 ++ .../model/VulnDb/CvssV2Metric.java | 146 ++++++++ .../model/VulnDb/CvssV3Metric.java | 161 +++++++++ .../model/VulnDb/ExternalReference.java | 25 ++ .../model/VulnDb/ExternalText.java | 26 ++ .../model/VulnDb/NvdAdditionalInfo.java | 34 ++ .../dependencytrack/model/VulnDb/Product.java | 46 +++ .../dependencytrack/model/VulnDb/Results.java | 63 ++++ .../dependencytrack/model/VulnDb/Status.java | 79 +++++ .../dependencytrack/model/VulnDb/Vendor.java | 62 ++++ .../dependencytrack/model/VulnDb/Version.java | 53 +++ .../model/VulnDb/VulnDbParser.java | 329 ++++++++++++++++++ .../model/VulnDb/Vulnerability.java | 255 ++++++++++++++ .../parser/vulndb/ModelConverter.java | 12 +- .../dependencytrack/tasks/VulnDbSyncTask.java | 21 +- .../tasks/scanners/VulnDbAnalysisTask.java | 4 +- .../org/dependencytrack/util/VulnDBUtil.java | 34 +- 21 files changed, 1488 insertions(+), 57 deletions(-) create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/ApiObject.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/Author.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/Classification.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/Cpe.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/CvssV2Metric.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/CvssV3Metric.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/ExternalReference.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/ExternalText.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/NvdAdditionalInfo.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/Product.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/Results.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/Status.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/Vendor.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/Version.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java create mode 100644 src/main/java/org/dependencytrack/model/VulnDb/Vulnerability.java diff --git a/pom.xml b/pom.xml index 67904749c3..699a2d4dd7 100644 --- a/pom.xml +++ b/pom.xml @@ -96,6 +96,7 @@ 2.0.1 6.5.0 1.1.1 + 2.1.1 11.2.3.jre17 @@ -225,37 +226,41 @@ pebble ${lib.pebble.version} - + - us.springett - vulndb-data-mirror - ${lib.vulndb-data-mirror.version} - - - - io.github.openunirest - open-unirest-java - - - com.google.code.gson - gson - - + org.apache.httpcomponents + httpclient + 4.5.14 + + + + oauth.signpost + signpost-core + ${lib.signpost-core.version} + compile + + + org.apache.httpcomponents + httpmime + 4.5.14 + + + com.fasterxml.woodstox woodstox-core ${lib.woodstox.version} - - - com.google.code.gson - gson - 2.8.9 - + + + + + + - + org.apache.maven maven-artifact diff --git a/src/main/java/org/dependencytrack/model/VulnDb/ApiObject.java b/src/main/java/org/dependencytrack/model/VulnDb/ApiObject.java new file mode 100644 index 0000000000..a212d3757a --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/ApiObject.java @@ -0,0 +1,7 @@ +package org.dependencytrack.model.VulnDb; + +public interface ApiObject { + int getId(); + + void setId(int var1); +} diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Author.java b/src/main/java/org/dependencytrack/model/VulnDb/Author.java new file mode 100644 index 0000000000..c2de577920 --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/Author.java @@ -0,0 +1,62 @@ +package org.dependencytrack.model.VulnDb; + +public class Author { + private int id; + private String name; + private String company; + private String email; + private String companyUrl; + private String country; + + public Author() { + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCompany() { + return this.company; + } + + public void setCompany(String company) { + this.company = company; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getCompanyUrl() { + return this.companyUrl; + } + + public void setCompanyUrl(String companyUrl) { + this.companyUrl = companyUrl; + } + + public String getCountry() { + return this.country; + } + + public void setCountry(String country) { + this.country = country; + } +} + diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Classification.java b/src/main/java/org/dependencytrack/model/VulnDb/Classification.java new file mode 100644 index 0000000000..493e673ab6 --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/Classification.java @@ -0,0 +1,52 @@ +package org.dependencytrack.model.VulnDb; + +public class Classification { + private int id; + private String name; + private String longname; + private String description; + private String mediumtext; + + public Classification() { + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLongname() { + return this.longname; + } + + public void setLongname(String longname) { + this.longname = longname; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getMediumtext() { + return this.mediumtext; + } + + public void setMediumtext(String mediumtext) { + this.mediumtext = mediumtext; + } +} diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Cpe.java b/src/main/java/org/dependencytrack/model/VulnDb/Cpe.java new file mode 100644 index 0000000000..c2d9e52edc --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/Cpe.java @@ -0,0 +1,25 @@ +package org.dependencytrack.model.VulnDb; + +public class Cpe { + private String cpe; + private String type; + + public Cpe() { + } + + public String getCpe() { + return this.cpe; + } + + public void setCpe(String cpe) { + this.cpe = cpe; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/src/main/java/org/dependencytrack/model/VulnDb/CvssV2Metric.java b/src/main/java/org/dependencytrack/model/VulnDb/CvssV2Metric.java new file mode 100644 index 0000000000..2a7c7a504b --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/CvssV2Metric.java @@ -0,0 +1,146 @@ +package org.dependencytrack.model.VulnDb; + +import us.springett.cvss.CvssV2; + +import java.math.BigDecimal; + +public class CvssV2Metric { + private int id; + private String accessComplexity; + private String cveId; + private String source; + private String availabilityImpact; + private String confidentialityImpact; + private String authentication; + private BigDecimal calculatedCvssBaseScore; + private String generatedOn; + private BigDecimal score; + private String accessVector; + private String integrityImpact; + + public CvssV2Metric() { + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getAccessComplexity() { + return this.accessComplexity; + } + + public void setAccessComplexity(String accessComplexity) { + this.accessComplexity = accessComplexity; + } + + public String getCveId() { + return this.cveId; + } + + public void setCveId(String cveId) { + this.cveId = cveId; + } + + public String getSource() { + return this.source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getAvailabilityImpact() { + return this.availabilityImpact; + } + + public void setAvailabilityImpact(String availabilityImpact) { + this.availabilityImpact = availabilityImpact; + } + + public String getConfidentialityImpact() { + return this.confidentialityImpact; + } + + public void setConfidentialityImpact(String confidentialityImpact) { + this.confidentialityImpact = confidentialityImpact; + } + + public String getAuthentication() { + return this.authentication; + } + + public void setAuthentication(String authentication) { + this.authentication = authentication; + } + + public BigDecimal getCalculatedCvssBaseScore() { + return this.calculatedCvssBaseScore; + } + + public void setCalculatedCvssBaseScore(BigDecimal calculatedCvssBaseScore) { + this.calculatedCvssBaseScore = calculatedCvssBaseScore; + } + + public String getGeneratedOn() { + return this.generatedOn; + } + + public void setGeneratedOn(String generatedOn) { + this.generatedOn = generatedOn; + } + + public BigDecimal getScore() { + return this.score; + } + + public void setScore(BigDecimal score) { + this.score = score; + } + + public String getAccessVector() { + return this.accessVector; + } + + public void setAccessVector(String accessVector) { + this.accessVector = accessVector; + } + + public String getIntegrityImpact() { + return this.integrityImpact; + } + + public void setIntegrityImpact(String integrityImpact) { + this.integrityImpact = integrityImpact; + } + + public CvssV2 toNormalizedMetric() { + CvssV2 cvss = new CvssV2(); + if (!"ADJACENT_NETWORK".equals(this.accessVector) && !"ADJACENT".equals(this.accessVector)) { + if ("LOCAL".equals(this.accessVector)) { + cvss.attackVector(CvssV2.AttackVector.LOCAL); + } else if ("NETWORK".equals(this.accessVector)) { + cvss.attackVector(CvssV2.AttackVector.NETWORK); + } + } else { + cvss.attackVector(CvssV2.AttackVector.ADJACENT); + } + + if ("SINGLE_INSTANCE".equals(this.authentication)) { + cvss.authentication(CvssV2.Authentication.SINGLE); + } else if ("MULTIPLE_INSTANCES".equals(this.authentication)) { + cvss.authentication(CvssV2.Authentication.MULTIPLE); + } else if ("NONE".equals(this.authentication)) { + cvss.authentication(CvssV2.Authentication.NONE); + } + + cvss.attackComplexity(CvssV2.AttackComplexity.valueOf(this.accessComplexity)); + cvss.confidentiality(CvssV2.CIA.valueOf(this.confidentialityImpact)); + cvss.integrity(CvssV2.CIA.valueOf(this.integrityImpact)); + cvss.availability(CvssV2.CIA.valueOf(this.availabilityImpact)); + return cvss; + } +} diff --git a/src/main/java/org/dependencytrack/model/VulnDb/CvssV3Metric.java b/src/main/java/org/dependencytrack/model/VulnDb/CvssV3Metric.java new file mode 100644 index 0000000000..5580dd5c2c --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/CvssV3Metric.java @@ -0,0 +1,161 @@ +package org.dependencytrack.model.VulnDb; + +import us.springett.cvss.CvssV3; + +import java.math.BigDecimal; + +public class CvssV3Metric { + private String attackComplexity; + private String scope; + private String attackVector; + private String availabilityImpact; + private BigDecimal score; + private String privilegesRequired; + private String userInteraction; + private int id; + private String source; + private String cveId; + private String confidentialityImpact; + private BigDecimal calculatedCvssBaseScore; + private String generatedOn; + private String integrityImpact; + + public CvssV3Metric() { + } + + public String getAttackComplexity() { + return this.attackComplexity; + } + + public void setAttackComplexity(String attackComplexity) { + this.attackComplexity = attackComplexity; + } + + public String getScope() { + return this.scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public String getAttackVector() { + return this.attackVector; + } + + public void setAttackVector(String attackVector) { + this.attackVector = attackVector; + } + + public String getAvailabilityImpact() { + return this.availabilityImpact; + } + + public void setAvailabilityImpact(String availabilityImpact) { + this.availabilityImpact = availabilityImpact; + } + + public BigDecimal getScore() { + return this.score; + } + + public void setScore(BigDecimal score) { + this.score = score; + } + + public String getPrivilegesRequired() { + return this.privilegesRequired; + } + + public void setPrivilegesRequired(String privilegesRequired) { + this.privilegesRequired = privilegesRequired; + } + + public String getUserInteraction() { + return this.userInteraction; + } + + public void setUserInteraction(String userInteraction) { + this.userInteraction = userInteraction; + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getSource() { + return this.source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getCveId() { + return this.cveId; + } + + public void setCveId(String cveId) { + this.cveId = cveId; + } + + public String getConfidentialityImpact() { + return this.confidentialityImpact; + } + + public void setConfidentialityImpact(String confidentialityImpact) { + this.confidentialityImpact = confidentialityImpact; + } + + public BigDecimal getCalculatedCvssBaseScore() { + return this.calculatedCvssBaseScore; + } + + public void setCalculatedCvssBaseScore(BigDecimal calculatedCvssBaseScore) { + this.calculatedCvssBaseScore = calculatedCvssBaseScore; + } + + public String getGeneratedOn() { + return this.generatedOn; + } + + public void setGeneratedOn(String generatedOn) { + this.generatedOn = generatedOn; + } + + public String getIntegrityImpact() { + return this.integrityImpact; + } + + public void setIntegrityImpact(String integrityImpact) { + this.integrityImpact = integrityImpact; + } + + public CvssV3 toNormalizedMetric() { + CvssV3 cvss = new CvssV3(); + if (!"ADJACENT_NETWORK".equals(this.attackVector) && !"ADJACENT".equals(this.attackVector)) { + if ("LOCAL".equals(this.attackVector)) { + cvss.attackVector(CvssV3.AttackVector.LOCAL); + } else if ("NETWORK".equals(this.attackVector)) { + cvss.attackVector(CvssV3.AttackVector.NETWORK); + } else if ("PHYSICAL".equals(this.attackVector)) { + cvss.attackVector(CvssV3.AttackVector.PHYSICAL); + } + } else { + cvss.attackVector(CvssV3.AttackVector.ADJACENT); + } + + cvss.attackComplexity(CvssV3.AttackComplexity.valueOf(this.attackComplexity)); + cvss.privilegesRequired(CvssV3.PrivilegesRequired.valueOf(this.privilegesRequired)); + cvss.userInteraction(CvssV3.UserInteraction.valueOf(this.userInteraction)); + cvss.scope(CvssV3.Scope.valueOf(this.scope)); + cvss.confidentiality(CvssV3.CIA.valueOf(this.confidentialityImpact)); + cvss.integrity(CvssV3.CIA.valueOf(this.integrityImpact)); + cvss.availability(CvssV3.CIA.valueOf(this.availabilityImpact)); + return cvss; + } +} diff --git a/src/main/java/org/dependencytrack/model/VulnDb/ExternalReference.java b/src/main/java/org/dependencytrack/model/VulnDb/ExternalReference.java new file mode 100644 index 0000000000..6c58be8b59 --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/ExternalReference.java @@ -0,0 +1,25 @@ +package org.dependencytrack.model.VulnDb; + +public class ExternalReference { + private String type; + private String value; + + public ExternalReference() { + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/dependencytrack/model/VulnDb/ExternalText.java b/src/main/java/org/dependencytrack/model/VulnDb/ExternalText.java new file mode 100644 index 0000000000..52f4d2a168 --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/ExternalText.java @@ -0,0 +1,26 @@ +package org.dependencytrack.model.VulnDb; + +public class ExternalText { + private String type; + private String value; + + public ExternalText() { + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } +} + diff --git a/src/main/java/org/dependencytrack/model/VulnDb/NvdAdditionalInfo.java b/src/main/java/org/dependencytrack/model/VulnDb/NvdAdditionalInfo.java new file mode 100644 index 0000000000..af486e1f5c --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/NvdAdditionalInfo.java @@ -0,0 +1,34 @@ +package org.dependencytrack.model.VulnDb; + +public class NvdAdditionalInfo { + private String summary; + private String cweId; + private String cveId; + + public NvdAdditionalInfo() { + } + + public String getSummary() { + return this.summary; + } + + public void setSummary(String summary) { + this.summary = summary; + } + + public String getCweId() { + return this.cweId; + } + + public void setCweId(String cweId) { + this.cweId = cweId; + } + + public String getCveId() { + return this.cveId; + } + + public void setCveId(String cveId) { + this.cveId = cveId; + } +} diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Product.java b/src/main/java/org/dependencytrack/model/VulnDb/Product.java new file mode 100644 index 0000000000..d4cd4d7858 --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/Product.java @@ -0,0 +1,46 @@ +package org.dependencytrack.model.VulnDb; + + +import org.dependencytrack.model.VulnDb.ApiObject; +import org.dependencytrack.model.VulnDb.Version; + +import java.util.ArrayList; +import java.util.List; + +public class Product implements ApiObject { + private int id; + private String name; + private List versions = new ArrayList(); + + public Product() { + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public List getVersions() { + return this.versions; + } + + public void setVersions(List versions) { + this.versions = versions; + } + + public void addVersion(Version version) { + this.versions.add(version); + } +} + diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Results.java b/src/main/java/org/dependencytrack/model/VulnDb/Results.java new file mode 100644 index 0000000000..0487e9f550 --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/Results.java @@ -0,0 +1,63 @@ +package org.dependencytrack.model.VulnDb; + +import java.util.ArrayList; +import java.util.List; + +public class Results { + private int page; + private int total; + private List results = new ArrayList(); + private String rawResults; + private String errorCondition; + + public Results() { + } + + public int getPage() { + return this.page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getTotal() { + return this.total; + } + + public void setTotal(int total) { + this.total = total; + } + + public List getResults() { + return this.results; + } + + public void setResults(List objects) { + this.results = objects; + } + + public void add(T object) { + this.results.add(object); + } + + public String getRawResults() { + return this.rawResults; + } + + public void setRawResults(String rawResults) { + this.rawResults = rawResults; + } + + public boolean isSuccessful() { + return this.errorCondition == null; + } + + public String getErrorCondition() { + return this.errorCondition; + } + + public void setErrorCondition(String errorCondition) { + this.errorCondition = errorCondition; + } +} diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Status.java b/src/main/java/org/dependencytrack/model/VulnDb/Status.java new file mode 100644 index 0000000000..1298dea0f5 --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/Status.java @@ -0,0 +1,79 @@ +package org.dependencytrack.model.VulnDb; + +public class Status { + private String organizationName; + private String userNameRequesting; + private String userEmailRequesting; + private String subscriptionEndDate; + private String apiCallsAllowedPerMonth; + private String apiCallsMadeThisMonth; + private String vulnDbStatistics; + private String rawStatus; + + public Status() { + } + + public String getOrganizationName() { + return this.organizationName; + } + + public void setOrganizationName(String organizationName) { + this.organizationName = organizationName; + } + + public String getUserNameRequesting() { + return this.userNameRequesting; + } + + public void setUserNameRequesting(String userNameRequesting) { + this.userNameRequesting = userNameRequesting; + } + + public String getUserEmailRequesting() { + return this.userEmailRequesting; + } + + public void setUserEmailRequesting(String userEmailRequesting) { + this.userEmailRequesting = userEmailRequesting; + } + + public String getSubscriptionEndDate() { + return this.subscriptionEndDate; + } + + public void setSubscriptionEndDate(String subscriptionEndDate) { + this.subscriptionEndDate = subscriptionEndDate; + } + + public String getApiCallsAllowedPerMonth() { + return this.apiCallsAllowedPerMonth; + } + + public void setApiCallsAllowedPerMonth(String apiCallsAllowedPerMonth) { + this.apiCallsAllowedPerMonth = apiCallsAllowedPerMonth; + } + + public String getApiCallsMadeThisMonth() { + return this.apiCallsMadeThisMonth; + } + + public void setApiCallsMadeThisMonth(String apiCallsMadeThisMonth) { + this.apiCallsMadeThisMonth = apiCallsMadeThisMonth; + } + + public String getVulnDbStatistics() { + return this.vulnDbStatistics; + } + + public void setVulnDbStatistics(String vulnDbStatistics) { + this.vulnDbStatistics = vulnDbStatistics; + } + + public String getRawStatus() { + return this.rawStatus; + } + + public void setRawStatus(String rawStatus) { + this.rawStatus = rawStatus; + } +} diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Vendor.java b/src/main/java/org/dependencytrack/model/VulnDb/Vendor.java new file mode 100644 index 0000000000..8ecbbc624f --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/Vendor.java @@ -0,0 +1,62 @@ +package org.dependencytrack.model.VulnDb; + +import org.dependencytrack.model.VulnDb.ApiObject; +import org.dependencytrack.model.VulnDb.Product; + +import java.util.ArrayList; +import java.util.List; + +public class Vendor implements ApiObject { + private int id; + private String name; + private String shortName; + private String vendorUrl; + private List products = new ArrayList(); + + public Vendor() { + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getShortName() { + return this.shortName; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } + + public String getVendorUrl() { + return this.vendorUrl; + } + + public void setVendorUrl(String vendorUrl) { + this.vendorUrl = vendorUrl; + } + + public List getProducts() { + return this.products; + } + + public void setProducts(List products) { + this.products = products; + } + + public void addProduct(Product product) { + this.products.add(product); + } +} diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Version.java b/src/main/java/org/dependencytrack/model/VulnDb/Version.java new file mode 100644 index 0000000000..ef84fa8951 --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/Version.java @@ -0,0 +1,53 @@ +package org.dependencytrack.model.VulnDb; + +import org.dependencytrack.model.VulnDb.ApiObject; +import org.dependencytrack.model.VulnDb.Cpe; + +import java.util.ArrayList; +import java.util.List; + +public class Version implements ApiObject { + private int id; + private String name; + private boolean affected; + private List cpes = new ArrayList(); + + public Version() { + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isAffected() { + return this.affected; + } + + public void setAffected(boolean affected) { + this.affected = affected; + } + + public List getCpes() { + return this.cpes; + } + + public void setCpes(List cpes) { + this.cpes = cpes; + } + + public void addCpe(Cpe cpe) { + this.cpes.add(cpe); + } +} diff --git a/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java b/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java new file mode 100644 index 0000000000..78f126655a --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java @@ -0,0 +1,329 @@ +package org.dependencytrack.model.VulnDb; + +import java.io.File; +import java.io.IOException; +import java.math.BigDecimal; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.dependencytrack.model.VulnDb.ApiObject; +import org.dependencytrack.model.VulnDb.Author; +import org.dependencytrack.model.VulnDb.Cpe; +import org.dependencytrack.model.VulnDb.Classification; +import org.dependencytrack.model.VulnDb.CvssV2Metric; +import org.dependencytrack.model.VulnDb.CvssV3Metric; +import org.dependencytrack.model.VulnDb.ExternalReference; +import org.dependencytrack.model.VulnDb.ExternalText; +import org.dependencytrack.model.VulnDb.NvdAdditionalInfo; +import org.dependencytrack.model.VulnDb.Product; +import org.dependencytrack.model.VulnDb.Results; +import org.dependencytrack.model.VulnDb.Status; +import org.dependencytrack.model.VulnDb.Vendor; +import org.dependencytrack.model.VulnDb.Version; +import org.dependencytrack.model.VulnDb.Vulnerability; + +public class VulnDbParser { + private static final Logger LOGGER = LoggerFactory.getLogger(VulnDbParser.class); + + public VulnDbParser() { + } + + public Status parseStatus(JSONObject root) { + LOGGER.debug("Parsing JSON node"); + Status status = new Status(); + status.setOrganizationName(root.optString("organization_name")); + status.setUserNameRequesting(root.optString("user_name_requesting")); + status.setUserEmailRequesting(root.optString("user_email_address_requesting")); + status.setSubscriptionEndDate(root.optString("subscription_end_date")); + status.setApiCallsAllowedPerMonth(root.optString("number_of_api_calls_allowed_per_month")); + status.setApiCallsMadeThisMonth(root.optString("number_of_api_calls_made_this_month")); + status.setVulnDbStatistics(root.optString("vulndb_statistics")); + status.setRawStatus(root.toString()); + return status; + } + + public Results parse(Object jsonNode, Class apiObject) { + LOGGER.debug("Parsing JSON node"); + Results results = new Results(); + JSONObject root; + root = (JSONObject) jsonNode; + + results.setPage(root.getInt("current_page")); + results.setTotal(root.getInt("total_entries")); + results.setRawResults(jsonNode.toString()); + JSONArray rso = root.getJSONArray("results"); + if (Product.class == apiObject) { + results.setResults(this.parseProducts(rso)); + } else if (Vendor.class == apiObject) { + results.setResults(this.parseVendors(rso)); + } else if (Version.class == apiObject) { + results.setResults(this.parseVersions(rso)); + } else if (Vulnerability.class == apiObject) { + results.setResults(this.parseVulnerabilities(rso)); + } + + return results; + } + + public Results parse(String jsonData, Class apiObject) { + Object result = null; + try{ + result = new JSONObject(jsonData); + }catch (JSONException ex){ + result = new JSONArray(jsonData); + } + if(result instanceof JSONObject){ + return this.parse((JSONObject)result, apiObject); + } else{ + return this.parse((JSONArray) result, apiObject); + } + } + + public Results parse(File file, Class apiObject) throws IOException { + String jsonData = new String(Files.readAllBytes(Paths.get(file.toURI()))); + Object result = null; + try{ + result = new JSONObject(jsonData); + }catch (JSONException ex){ + result = new JSONArray(jsonData); + } + if(result instanceof JSONObject){ + return this.parse((JSONObject)result, apiObject); + } else{ + return this.parse((JSONArray) result, apiObject); + } + + } + + private List parseCpes(JSONArray rso) { + List cpes = null; + if (rso != null) { + cpes = new ArrayList(); + + for(int i = 0; i < rso.length(); ++i) { + JSONObject object = rso.getJSONObject(i); + Cpe cpe = new Cpe(); + cpe.setCpe(StringUtils.trimToNull(object.optString("cpe", (String)null))); + cpe.setType(StringUtils.trimToNull(object.optString("type", (String)null))); + cpes.add(cpe); + } + } + + return cpes; + } + + private List parseProducts(JSONArray rso) { + List products = null; + if (rso != null) { + products = new ArrayList(); + + for(int i = 0; i < rso.length(); ++i) { + JSONObject object = rso.getJSONObject(i); + Product product = new Product(); + product.setId(object.getInt("id")); + product.setName(StringUtils.trimToNull(object.optString("name", (String)null))); + product.setVersions(this.parseVersions(object.optJSONArray("versions"))); + products.add(product); + } + } + + return products; + } + + private List parseVendors(JSONArray rso) { + List vendors = null; + if (rso != null) { + vendors = new ArrayList(); + + for(int i = 0; i < rso.length(); ++i) { + JSONObject object = rso.getJSONObject(i); + if (object.has("vendor")) { + JSONObject childObject = object.getJSONObject("vendor"); + Vendor vendor = this.parseVendor(childObject); + vendors.add(vendor); + } else { + Vendor vendor = this.parseVendor(object); + vendors.add(vendor); + } + } + } + + return vendors; + } + + private Vendor parseVendor(JSONObject object) { + Vendor vendor = new Vendor(); + vendor.setId(object.getInt("id")); + vendor.setName(StringUtils.trimToNull(object.optString("name", (String)null))); + vendor.setShortName(StringUtils.trimToNull(object.optString("short_name", (String)null))); + vendor.setVendorUrl(StringUtils.trimToNull(object.optString("vendor_url", (String)null))); + vendor.setProducts(this.parseProducts(object.optJSONArray("products"))); + return vendor; + } + + private List parseVersions(JSONArray rso) { + List versions = null; + if (rso != null) { + versions = new ArrayList(); + + for(int i = 0; i < rso.length(); ++i) { + JSONObject object = rso.getJSONObject(i); + Version version = new Version(); + version.setId(object.getInt("id")); + version.setName(StringUtils.trimToNull(object.optString("name", (String)null))); + version.setAffected(object.optBoolean("affected", false)); + version.setCpes(this.parseCpes(object.optJSONArray("cpe"))); + versions.add(version); + } + } + + return versions; + } + + private List parseVulnerabilities(JSONArray rso) { + List vulnerabilities = null; + if (rso != null) { + vulnerabilities = new ArrayList(); + + for(int i = 0; i < rso.length(); ++i) { + JSONObject object = rso.getJSONObject(i); + Vulnerability vulnerability = new Vulnerability(); + vulnerability.setId(object.getInt("vulndb_id")); + vulnerability.setTitle(StringUtils.trimToNull(object.optString("title", (String)null))); + vulnerability.setDisclosureDate(StringUtils.trimToNull(object.optString("disclosure_date", (String)null))); + vulnerability.setDiscoveryDate(StringUtils.trimToNull(object.optString("discovery_date", (String)null))); + vulnerability.setExploitPublishDate(StringUtils.trimToNull(object.optString("exploit_publish_date", (String)null))); + vulnerability.setKeywords(StringUtils.trimToNull(object.optString("keywords", (String)null))); + vulnerability.setShortDescription(StringUtils.trimToNull(object.optString("short_description", (String)null))); + vulnerability.setDescription(StringUtils.trimToNull(object.optString("description", (String)null))); + vulnerability.setSolution(StringUtils.trimToNull(object.optString("solution", (String)null))); + vulnerability.setManualNotes(StringUtils.trimToNull(object.optString("manual_notes", (String)null))); + vulnerability.setTechnicalDescription(StringUtils.trimToNull(object.optString("t_description", (String)null))); + vulnerability.setSolutionDate(StringUtils.trimToNull(object.optString("solution_date", (String)null))); + vulnerability.setVendorInformedDate(StringUtils.trimToNull(object.optString("vendor_informed_date", (String)null))); + vulnerability.setVendorAckDate(StringUtils.trimToNull(object.optString("vendor_ack_date", (String)null))); + vulnerability.setThirdPartySolutionDate(StringUtils.trimToNull(object.optString("third_party_solution_date", (String)null))); + JSONArray classifications = object.optJSONArray("classifications"); + if (classifications != null) { + for(int j = 0; j < classifications.length(); ++j) { + JSONObject jso = classifications.getJSONObject(j); + Classification classification = new Classification(); + classification.setId(jso.getInt("id")); + classification.setName(StringUtils.trimToNull(jso.optString("name", (String)null))); + classification.setLongname(StringUtils.trimToNull(jso.optString("longname", (String)null))); + classification.setDescription(StringUtils.trimToNull(jso.optString("description", (String)null))); + classification.setMediumtext(StringUtils.trimToNull(jso.optString("mediumtext", (String)null))); + vulnerability.addClassifications(classification); + } + } + + JSONArray authors = object.optJSONArray("authors"); + if (authors != null) { + for(int j = 0; j < authors.length(); ++j) { + JSONObject jso = authors.getJSONObject(j); + Author author = new Author(); + author.setId(jso.getInt("id")); + author.setName(StringUtils.trimToNull(jso.optString("name", (String)null))); + author.setCompany(StringUtils.trimToNull(jso.optString("company", (String)null))); + author.setEmail(StringUtils.trimToNull(jso.optString("email", (String)null))); + author.setCompanyUrl(StringUtils.trimToNull(jso.optString("company_url", (String)null))); + author.setCountry(StringUtils.trimToNull(jso.optString("country", (String)null))); + vulnerability.addAuthor(author); + } + } + + JSONArray extRefs = object.optJSONArray("ext_references"); + if (extRefs != null) { + for(int j = 0; j < extRefs.length(); ++j) { + JSONObject jso = extRefs.getJSONObject(j); + ExternalReference externalReference = new ExternalReference(); + externalReference.setType(StringUtils.trimToNull(jso.optString("type", (String)null))); + externalReference.setValue(StringUtils.trimToNull(jso.optString("value", (String)null))); + vulnerability.addExtReference(externalReference); + } + } + + JSONArray extTexts = object.optJSONArray("ext_texts"); + if (extTexts != null) { + for(int j = 0; j < extTexts.length(); ++j) { + JSONObject jso = extTexts.getJSONObject(j); + ExternalText externalText = new ExternalText(); + externalText.setType(StringUtils.trimToNull(jso.optString("type", (String)null))); + externalText.setValue(StringUtils.trimToNull(jso.optString("value", (String)null))); + vulnerability.addExtText(externalText); + } + } + + JSONArray cvssv2Metrics = object.optJSONArray("cvss_metrics"); + if (cvssv2Metrics != null) { + for(int j = 0; j < cvssv2Metrics.length(); ++j) { + JSONObject jso = cvssv2Metrics.getJSONObject(j); + CvssV2Metric metric = new CvssV2Metric(); + metric.setId(jso.getInt("id")); + metric.setAccessComplexity(StringUtils.trimToNull(jso.optString("access_complexity", (String)null))); + metric.setCveId(StringUtils.trimToNull(jso.optString("cve_id", (String)null))); + metric.setSource(StringUtils.trimToNull(jso.optString("source", (String)null))); + metric.setAvailabilityImpact(StringUtils.trimToNull(jso.optString("availability_impact", (String)null))); + metric.setConfidentialityImpact(StringUtils.trimToNull(jso.optString("confidentiality_impact", (String)null))); + metric.setAuthentication(StringUtils.trimToNull(jso.optString("authentication", (String)null))); + metric.setCalculatedCvssBaseScore(jso.optBigDecimal("calculated_cvss_base_score", (BigDecimal)null)); + metric.setGeneratedOn(StringUtils.trimToNull(jso.optString("generated_on", (String)null))); + metric.setScore(jso.optBigDecimal("score", (BigDecimal)null)); + metric.setAccessVector(StringUtils.trimToNull(jso.optString("access_vector", (String)null))); + metric.setIntegrityImpact(StringUtils.trimToNull(jso.optString("integrity_impact", (String)null))); + vulnerability.addCvssV2Metric(metric); + } + } + + JSONArray cvssv3Metrics = object.optJSONArray("cvss_version_three_metrics"); + if (cvssv3Metrics != null) { + for(int j = 0; j < cvssv3Metrics.length(); ++j) { + JSONObject jso = cvssv3Metrics.getJSONObject(j); + CvssV3Metric metric = new CvssV3Metric(); + metric.setId(jso.getInt("id")); + metric.setAttackComplexity(StringUtils.trimToNull(jso.optString("attack_complexity", (String)null))); + metric.setScope(StringUtils.trimToNull(jso.optString("scope", (String)null))); + metric.setAttackVector(StringUtils.trimToNull(jso.optString("attack_vector", (String)null))); + metric.setAvailabilityImpact(StringUtils.trimToNull(jso.optString("availability_impact", (String)null))); + metric.setScore(jso.optBigDecimal("score", (BigDecimal)null)); + metric.setPrivilegesRequired(StringUtils.trimToNull(jso.optString("privileges_required", (String)null))); + metric.setUserInteraction(StringUtils.trimToNull(jso.optString("user_interaction", (String)null))); + metric.setCveId(StringUtils.trimToNull(jso.optString("cve_id", (String)null))); + metric.setSource(StringUtils.trimToNull(jso.optString("source", (String)null))); + metric.setConfidentialityImpact(StringUtils.trimToNull(jso.optString("confidentiality_impact", (String)null))); + metric.setCalculatedCvssBaseScore(jso.optBigDecimal("calculated_cvss_base_score", (BigDecimal)null)); + metric.setGeneratedOn(StringUtils.trimToNull(jso.optString("generated_on", (String)null))); + metric.setIntegrityImpact(StringUtils.trimToNull(jso.optString("integrity_impact", (String)null))); + vulnerability.addCvssV3Metric(metric); + } + } + + JSONArray nvdInfo = object.optJSONArray("nvd_additional_information"); + if (nvdInfo != null) { + for(int j = 0; j < nvdInfo.length(); ++j) { + JSONObject jso = nvdInfo.getJSONObject(j); + NvdAdditionalInfo nvdAdditionalInfo = new NvdAdditionalInfo(); + nvdAdditionalInfo.setSummary(StringUtils.trimToNull(jso.optString("summary", (String)null))); + nvdAdditionalInfo.setCweId(StringUtils.trimToNull(jso.optString("cwe_id", (String)null))); + nvdAdditionalInfo.setCveId(StringUtils.trimToNull(jso.optString("cve_id", (String)null))); + vulnerability.setNvdAdditionalInfo(nvdAdditionalInfo); + } + } + + JSONArray vendors = object.optJSONArray("vendors"); + vulnerability.setVendors(this.parseVendors(vendors)); + vulnerabilities.add(vulnerability); + } + } + + return vulnerabilities; + } +} + diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Vulnerability.java b/src/main/java/org/dependencytrack/model/VulnDb/Vulnerability.java new file mode 100644 index 0000000000..503bbb1a84 --- /dev/null +++ b/src/main/java/org/dependencytrack/model/VulnDb/Vulnerability.java @@ -0,0 +1,255 @@ +package org.dependencytrack.model.VulnDb; + +import org.dependencytrack.model.VulnDb.ApiObject; +import org.dependencytrack.model.VulnDb.Author; +import org.dependencytrack.model.VulnDb.Classification; +import org.dependencytrack.model.VulnDb.CvssV2Metric; +import org.dependencytrack.model.VulnDb.CvssV3Metric; +import org.dependencytrack.model.VulnDb.ExternalReference; +import org.dependencytrack.model.VulnDb.ExternalText; +import org.dependencytrack.model.VulnDb.NvdAdditionalInfo; +import org.dependencytrack.model.VulnDb.Vendor; + +import java.util.ArrayList; +import java.util.List; + +public class Vulnerability implements ApiObject { + private int id; + private String title; + private String disclosureDate; + private String discoveryDate; + private String exploitPublishDate; + private String keywords; + private String shortDescription; + private String description; + private String solution; + private String manualNotes; + private String technicalDescription; + private String solutionDate; + private String vendorInformedDate; + private String vendorAckDate; + private String thirdPartySolutionDate; + private List classifications = new ArrayList(); + private List authors = new ArrayList(); + private List extReferences = new ArrayList(); + private List extTexts = new ArrayList(); + private List vendors = new ArrayList(); + private List cvssV2Metrics = new ArrayList(); + private List cvssV3Metrics = new ArrayList(); + private NvdAdditionalInfo nvdAdditionalInfo; + + public Vulnerability() { + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDisclosureDate() { + return this.disclosureDate; + } + + public void setDisclosureDate(String disclosureDate) { + this.disclosureDate = disclosureDate; + } + + public String getDiscoveryDate() { + return this.discoveryDate; + } + + public void setDiscoveryDate(String discoveryDate) { + this.discoveryDate = discoveryDate; + } + + public String getExploitPublishDate() { + return this.exploitPublishDate; + } + + public void setExploitPublishDate(String exploitPublishDate) { + this.exploitPublishDate = exploitPublishDate; + } + + public String getKeywords() { + return this.keywords; + } + + public void setKeywords(String keywords) { + this.keywords = keywords; + } + + public String getShortDescription() { + return this.shortDescription; + } + + public void setShortDescription(String shortDescription) { + this.shortDescription = shortDescription; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getSolution() { + return this.solution; + } + + public void setSolution(String solution) { + this.solution = solution; + } + + public String getManualNotes() { + return this.manualNotes; + } + + public void setManualNotes(String manualNotes) { + this.manualNotes = manualNotes; + } + + public String getTechnicalDescription() { + return this.technicalDescription; + } + + public void setTechnicalDescription(String technicalDescription) { + this.technicalDescription = technicalDescription; + } + + public String getSolutionDate() { + return this.solutionDate; + } + + public void setSolutionDate(String solutionDate) { + this.solutionDate = solutionDate; + } + + public String getVendorInformedDate() { + return this.vendorInformedDate; + } + + public void setVendorInformedDate(String vendorInformedDate) { + this.vendorInformedDate = vendorInformedDate; + } + + public String getVendorAckDate() { + return this.vendorAckDate; + } + + public void setVendorAckDate(String vendorAckDate) { + this.vendorAckDate = vendorAckDate; + } + + public String getThirdPartySolutionDate() { + return this.thirdPartySolutionDate; + } + + public void setThirdPartySolutionDate(String thirdPartySolutionDate) { + this.thirdPartySolutionDate = thirdPartySolutionDate; + } + + public List getClassifications() { + return this.classifications; + } + + public void setClassifications(List classifications) { + this.classifications = classifications; + } + + public void addClassifications(Classification classification) { + this.classifications.add(classification); + } + + public List getAuthors() { + return this.authors; + } + + public void setAuthors(List authors) { + this.authors = authors; + } + + public void addAuthor(Author author) { + this.authors.add(author); + } + + public List getExtReferences() { + return this.extReferences; + } + + public void setExtReferences(List extReferences) { + this.extReferences = extReferences; + } + + public void addExtReference(ExternalReference externalReference) { + this.extReferences.add(externalReference); + } + + public List getExtTexts() { + return this.extTexts; + } + + public void setExtTexts(List extTexts) { + this.extTexts = extTexts; + } + + public void addExtText(ExternalText externalText) { + this.extTexts.add(externalText); + } + + public List getVendors() { + return this.vendors; + } + + public void setVendors(List vendors) { + this.vendors = vendors; + } + + public void addVendor(Vendor vendor) { + this.vendors.add(vendor); + } + + public List getCvssV2Metrics() { + return this.cvssV2Metrics; + } + + public void setCvssV2Metrics(List cvssV2Metrics) { + this.cvssV2Metrics = cvssV2Metrics; + } + + public void addCvssV2Metric(CvssV2Metric metric) { + this.cvssV2Metrics.add(metric); + } + + public List getCvssV3Metrics() { + return this.cvssV3Metrics; + } + + public void setCvssV3Metrics(List cvssV3Metrics) { + this.cvssV3Metrics = cvssV3Metrics; + } + + public void addCvssV3Metric(CvssV3Metric metric) { + this.cvssV3Metrics.add(metric); + } + + public NvdAdditionalInfo getNvdAdditionalInfo() { + return this.nvdAdditionalInfo; + } + + public void setNvdAdditionalInfo(NvdAdditionalInfo nvdAdditionalInfo) { + this.nvdAdditionalInfo = nvdAdditionalInfo; + } +} diff --git a/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java b/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java index 8d5a260ecb..8f69693c12 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java @@ -21,14 +21,16 @@ import alpine.common.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.dependencytrack.model.Cwe; +import org.dependencytrack.model.VulnDb.Author; +import org.dependencytrack.model.VulnDb.ExternalReference; import org.dependencytrack.model.Vulnerability; import org.dependencytrack.parser.common.resolver.CweResolver; import org.dependencytrack.persistence.QueryManager; import us.springett.cvss.CvssV2; import us.springett.cvss.CvssV3; import us.springett.cvss.Score; -import us.springett.vulndbdatamirror.parser.model.CvssV2Metric; -import us.springett.vulndbdatamirror.parser.model.CvssV3Metric; +import org.dependencytrack.model.VulnDb.CvssV2Metric; +import org.dependencytrack.model.VulnDb.CvssV3Metric; import java.math.BigDecimal; import java.time.OffsetDateTime; @@ -54,7 +56,7 @@ private ModelConverter() { } * @param vulnDbVuln the VulnDB vulnerability to convert * @return a Dependency-Track Vulnerability object */ - public static Vulnerability convert(final QueryManager qm, final us.springett.vulndbdatamirror.parser.model.Vulnerability vulnDbVuln) { + public static Vulnerability convert(final QueryManager qm, final org.dependencytrack.model.VulnDb.Vulnerability vulnDbVuln) { final org.dependencytrack.model.Vulnerability vuln = new org.dependencytrack.model.Vulnerability(); vuln.setSource(org.dependencytrack.model.Vulnerability.Source.VULNDB); vuln.setVulnId(sanitize(String.valueOf(vulnDbVuln.getId()))); @@ -96,7 +98,7 @@ public static Vulnerability convert(final QueryManager qm, final us.springett.vu /* References */ final StringBuilder references = new StringBuilder(); - for (final us.springett.vulndbdatamirror.parser.model.ExternalReference reference : vulnDbVuln.getExtReferences()) { + for (final ExternalReference reference : vulnDbVuln.getExtReferences()) { final String sType = sanitize(reference.getType()); final String sValue = sanitize(reference.getValue()); // Convert reference to Markdown format @@ -111,7 +113,7 @@ public static Vulnerability convert(final QueryManager qm, final us.springett.vu /* Credits */ final StringBuilder credits = new StringBuilder(); - for (final us.springett.vulndbdatamirror.parser.model.Author author : vulnDbVuln.getAuthors()) { + for (final Author author : vulnDbVuln.getAuthors()) { final String name = sanitize(author.getName()); final String company = sanitize(author.getCompany()); if (name != null && company != null) { diff --git a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java index 61eeb5ea42..94f34c088b 100644 --- a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java +++ b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java @@ -37,12 +37,11 @@ import us.springett.parsers.cpe.CpeParser; import us.springett.parsers.cpe.exceptions.CpeEncodingException; import us.springett.parsers.cpe.exceptions.CpeParsingException; -import us.springett.vulndbdatamirror.parser.VulnDbParser; -import us.springett.vulndbdatamirror.parser.model.CPE; -import us.springett.vulndbdatamirror.parser.model.Product; -import us.springett.vulndbdatamirror.parser.model.Results; -import us.springett.vulndbdatamirror.parser.model.Vendor; -import us.springett.vulndbdatamirror.parser.model.Version; +import org.dependencytrack.model.VulnDb.VulnDbParser; +import org.dependencytrack.model.VulnDb.Product; +import org.dependencytrack.model.VulnDb.Results; +import org.dependencytrack.model.VulnDb.Vendor; +import org.dependencytrack.model.VulnDb.Version; import java.io.File; import java.io.IOException; @@ -85,7 +84,7 @@ public void inform(final Event e) { LOGGER.info("Parsing: " + file.getName()); final VulnDbParser parser = new VulnDbParser(); try { - final Results results = parser.parse(file, us.springett.vulndbdatamirror.parser.model.Vulnerability.class); + final Results results = parser.parse(file, org.dependencytrack.model.VulnDb.Vulnerability.class); updateDatasource(results); } catch (IOException ex) { LOGGER.error("An error occurred while parsing VulnDB payload: " + file.getName(), ex); @@ -122,8 +121,8 @@ private void updateDatasource(final Results results) { LOGGER.info("Updating datasource with VulnDB vulnerabilities"); try (QueryManager qm = new QueryManager()) { for (final Object o: results.getResults()) { - if (o instanceof us.springett.vulndbdatamirror.parser.model.Vulnerability) { - final us.springett.vulndbdatamirror.parser.model.Vulnerability vulnDbVuln = (us.springett.vulndbdatamirror.parser.model.Vulnerability)o; + if (o instanceof org.dependencytrack.model.VulnDb.Vulnerability) { + final org.dependencytrack.model.VulnDb.Vulnerability vulnDbVuln = (org.dependencytrack.model.VulnDb.Vulnerability)o; final org.dependencytrack.model.Vulnerability vulnerability = ModelConverter.convert(qm, vulnDbVuln); final Vulnerability synchronizeVulnerability = qm.synchronizeVulnerability(vulnerability, false); final List vsListOld = qm.detach(qm.getVulnerableSoftwareByVulnId(synchronizeVulnerability.getSource(), synchronizeVulnerability.getVulnId())); @@ -138,7 +137,7 @@ private void updateDatasource(final Results results) { } public static List parseCpes(final QueryManager qm, final Vulnerability vulnerability, - final us.springett.vulndbdatamirror.parser.model.Vulnerability vulnDbVuln) { + final org.dependencytrack.model.VulnDb.Vulnerability vulnDbVuln) { // cpe:2.3:a:belavier_commerce:abantecart:1.2.8:*:*:*:*:*:*:* final List vsList = new ArrayList<>(); if (vulnDbVuln.getVendors() != null) { @@ -150,7 +149,7 @@ public static List parseCpes(final QueryManager qm, final Vu if (version != null) { if (version.isAffected()) { if (version.getCpes() != null) { - for (CPE cpeObject : version.getCpes()) { + for (org.dependencytrack.model.VulnDb.Cpe cpeObject : version.getCpes()) { try { final Cpe cpe = CpeParser.parse(cpeObject.getCpe(), true); final VulnerableSoftware vs = generateVulnerableSoftware(qm, cpe, vulnerability); diff --git a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java index 669a886ae2..59b7383eea 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java @@ -32,7 +32,7 @@ import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.util.NotificationUtil; import org.dependencytrack.util.VulnDBUtil; -import us.springett.vulndbdatamirror.parser.model.Results; +import org.dependencytrack.model.VulnDb.Results; import java.util.List; @@ -154,7 +154,7 @@ public void analyze(final List components) { private boolean processResults(final Results results, final Component component) { try (final QueryManager qm = new QueryManager()) { final Component vulnerableComponent = qm.getObjectByUuid(Component.class, component.getUuid()); // Refresh component and attach to current pm. - for (us.springett.vulndbdatamirror.parser.model.Vulnerability vulnDbVuln : (List) results.getResults()) { + for (org.dependencytrack.model.VulnDb.Vulnerability vulnDbVuln : (List) results.getResults()) { Vulnerability vulnerability = qm.getVulnerabilityByVulnId(Vulnerability.Source.VULNDB, String.valueOf(vulnDbVuln.getId())); if (vulnerability == null) { vulnerability = qm.createVulnerability(ModelConverter.convert(qm, vulnDbVuln), false); diff --git a/src/main/java/org/dependencytrack/util/VulnDBUtil.java b/src/main/java/org/dependencytrack/util/VulnDBUtil.java index 304eb9951b..d703f9b521 100644 --- a/src/main/java/org/dependencytrack/util/VulnDBUtil.java +++ b/src/main/java/org/dependencytrack/util/VulnDBUtil.java @@ -12,20 +12,20 @@ import org.dependencytrack.common.HttpClientPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import us.springett.vulndbdatamirror.parser.model.CPE; -import us.springett.vulndbdatamirror.parser.model.Product; -import us.springett.vulndbdatamirror.parser.model.Results; -import us.springett.vulndbdatamirror.parser.model.Vendor; -import us.springett.vulndbdatamirror.parser.model.Version; -import us.springett.vulndbdatamirror.parser.model.ApiObject; -import us.springett.vulndbdatamirror.parser.model.Vulnerability; -import us.springett.vulndbdatamirror.parser.model.Classification; -import us.springett.vulndbdatamirror.parser.model.Author; -import us.springett.vulndbdatamirror.parser.model.CvssV2Metric; -import us.springett.vulndbdatamirror.parser.model.CvssV3Metric; -import us.springett.vulndbdatamirror.parser.model.NvdAdditionalInfo; -import us.springett.vulndbdatamirror.parser.model.ExternalText; -import us.springett.vulndbdatamirror.parser.model.ExternalReference; +import org.dependencytrack.model.VulnDb.Cpe; +import org.dependencytrack.model.VulnDb.Product; +import org.dependencytrack.model.VulnDb.Results; +import org.dependencytrack.model.VulnDb.Vendor; +import org.dependencytrack.model.VulnDb.Version; +import org.dependencytrack.model.VulnDb.ApiObject; +import org.dependencytrack.model.VulnDb.Vulnerability; +import org.dependencytrack.model.VulnDb.Classification; +import org.dependencytrack.model.VulnDb.Author; +import org.dependencytrack.model.VulnDb.CvssV2Metric; +import org.dependencytrack.model.VulnDb.CvssV3Metric; +import org.dependencytrack.model.VulnDb.NvdAdditionalInfo; +import org.dependencytrack.model.VulnDb.ExternalText; +import org.dependencytrack.model.VulnDb.ExternalReference; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -197,14 +197,14 @@ private List parseVersions(JSONArray rso) { return versions; } - private List parseCpes(JSONArray rso) { - List cpes = null; + private List parseCpes(JSONArray rso) { + List cpes = null; if (rso != null) { cpes = new ArrayList(); for(int i = 0; i < rso.length(); ++i) { JSONObject object = rso.getJSONObject(i); - CPE cpe = new CPE(); + Cpe cpe = new Cpe(); cpe.setCpe(StringUtils.trimToNull(object.optString("cpe", (String)null))); cpe.setType(StringUtils.trimToNull(object.optString("type", (String)null))); cpes.add(cpe); From 5c5da895bcf9a7635257b879e469b2c1f671e8f8 Mon Sep 17 00:00:00 2001 From: mehab Date: Thu, 2 Feb 2023 12:01:50 +0000 Subject: [PATCH 18/31] changes pulled in from citi fork Signed-off-by: mehab --- pom.xml | 9 --------- .../integrations/defectdojo/DefectDojoClient.java | 4 ++-- .../integrations/fortifyssc/FortifySscClient.java | 4 ++-- .../org/dependencytrack/model/VulnDb/VulnDbParser.java | 3 ++- .../notification/publisher/AbstractWebhookPublisher.java | 4 ++-- .../org/dependencytrack/persistence/CweImporter.java | 2 +- .../dependencytrack/tasks/GitHubAdvisoryMirrorTask.java | 8 ++++---- .../tasks/repositories/CargoMetaAnalyzer.java | 2 +- .../tasks/repositories/GemMetaAnalyzer.java | 2 +- .../tasks/repositories/GoModulesMetaAnalyzer.java | 2 +- .../tasks/repositories/HexMetaAnalyzer.java | 2 +- .../tasks/repositories/MavenMetaAnalyzer.java | 6 +++--- .../tasks/repositories/NpmMetaAnalyzer.java | 2 +- .../tasks/repositories/NugetMetaAnalyzer.java | 6 +++--- .../tasks/scanners/OssIndexAnalysisTask.java | 2 +- .../tasks/scanners/VulnDbAnalysisTask.java | 4 ++-- src/main/java/org/dependencytrack/util/VulnDBUtil.java | 5 +++-- 17 files changed, 30 insertions(+), 37 deletions(-) diff --git a/pom.xml b/pom.xml index 699a2d4dd7..5cd038c087 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,6 @@ 8.11.2 1.4.1 3.2.0 - 1.0.1 2.0.1 6.5.0 1.1.1 @@ -253,14 +252,6 @@ ${lib.woodstox.version} - - - - - - - - org.apache.maven maven-artifact diff --git a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java index f6a5ca4b58..c2ed5494c1 100644 --- a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java +++ b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java @@ -19,6 +19,7 @@ package org.dependencytrack.integrations.defectdojo; import alpine.common.logging.Logger; +import com.google.common.base.Throwables; import org.apache.http.HttpStatus; import org.json.JSONArray; import org.json.JSONObject; @@ -193,8 +194,7 @@ public void reimportDependencyTrackFindings(final String token, final String eng uploader.handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } }catch (IOException ex){ - LOGGER.error("Error while sending request from reimport DT findings defectDojo Client" + ex.getMessage()); - LOGGER.error("Error while sending request from reimport DT findings defectDojo Client" + ex.getStackTrace()); + LOGGER.error("Error while sending request from reimport DT findings defectDojo Client" + ex.getMessage()+" with stack trace: "+ Throwables.getStackTraceAsString(ex)); } } diff --git a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java index 546aa6bfa1..803efe29b6 100644 --- a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java +++ b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java @@ -50,7 +50,7 @@ public FortifySscClient(final FortifySscUploader uploader, final URL baseURL) { public String generateOneTimeUploadToken(final String citoken) { LOGGER.debug("Generating one-time upload token"); - HttpPost request = new HttpPost(baseURL + "/api/v1/fileTokens"); + var request = new HttpPost(baseURL + "/api/v1/fileTokens"); final JSONObject payload = new JSONObject().put("fileTokenType", "UPLOAD"); request.addHeader("Content-Type", "application/json"); request.addHeader("Authorization", "FortifyToken " + Base64.getEncoder().encodeToString(citoken.getBytes(StandardCharsets.UTF_8))); @@ -79,7 +79,7 @@ public String generateOneTimeUploadToken(final String citoken) { public void uploadDependencyTrackFindings(final String token, final String applicationVersion, final InputStream findingsJson) { try { LOGGER.debug("Uploading Dependency-Track findings to Fortify SSC"); - URIBuilder builder = new URIBuilder(baseURL + "/upload/resultFileUpload.html"); + var builder = new URIBuilder(baseURL + "/upload/resultFileUpload.html"); builder.setParameter("engineType", "DEPENDENCY_TRACK").setParameter("mat", token).setParameter("entityId", applicationVersion); HttpPost request = new HttpPost(builder.build()); request.addHeader("accept", "application/xml"); diff --git a/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java b/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java index 78f126655a..05686d43a3 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java +++ b/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java @@ -3,6 +3,7 @@ import java.io.File; import java.io.IOException; import java.math.BigDecimal; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -87,7 +88,7 @@ public Results parse(String jsonData, Class apiObjec } public Results parse(File file, Class apiObject) throws IOException { - String jsonData = new String(Files.readAllBytes(Paths.get(file.toURI()))); + String jsonData = new String(Files.readAllBytes(Paths.get(file.toURI())), Charset.defaultCharset()); Object result = null; try{ result = new JSONObject(jsonData); diff --git a/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java b/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java index 7f87d2f300..48f8adc303 100644 --- a/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java +++ b/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java @@ -54,7 +54,7 @@ public void publish(final String publisherName, final PebbleTemplate template, f } final String mimeType = getTemplateMimeType(config); try { - HttpPost request = new HttpPost(destination); + var request = new HttpPost(destination); request.addHeader("content-type", mimeType); request.addHeader("accept", mimeType); final BasicAuthCredentials credentials; @@ -92,7 +92,7 @@ protected BasicAuthCredentials getBasicAuthCredentials() { protected record BasicAuthCredentials(String user, String password) { } - protected void handleRequestException(final org.slf4j.Logger logger, final Exception e) { + protected void handleRequestException(final Logger logger, final Exception e) { logger.error("Request failure", e); Notification.dispatch(new Notification() .scope(NotificationScope.SYSTEM) diff --git a/src/main/java/org/dependencytrack/persistence/CweImporter.java b/src/main/java/org/dependencytrack/persistence/CweImporter.java index 63a1ad8f3e..d89d0339f8 100644 --- a/src/main/java/org/dependencytrack/persistence/CweImporter.java +++ b/src/main/java/org/dependencytrack/persistence/CweImporter.java @@ -66,7 +66,7 @@ public void processCweDefinitions() throws ParserConfigurationException, SAXExce final DocumentBuilder builder = factory.newDocumentBuilder(); final Document doc = builder.parse(is); - final XPathFactory xPathfactory = XPathFactory.newInstance(); + final var xPathfactory = XPathFactory.newInstance(); final XPath xpath = xPathfactory.newXPath(); final XPathExpression expr1 = xpath.compile("/Weakness_Catalog/Categories/Category"); diff --git a/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java b/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java index 0ce2f8144d..eb29aa16ef 100644 --- a/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java +++ b/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java @@ -135,9 +135,9 @@ private void retrieveAdvisories(final String advisoriesEndCursor) throws IOExcep request.addHeader("Authorization", "bearer " + accessToken); request.addHeader("content-type", "application/json"); request.addHeader("accept", "application/json"); - JSONObject jsonBody = new JSONObject(); + var jsonBody = new JSONObject(); jsonBody.put("query", queryTemplate); - StringEntity stringEntity = new StringEntity(jsonBody.toString()); + var stringEntity = new StringEntity(jsonBody.toString()); request.setEntity(stringEntity); CloseableHttpResponse response = HttpClientPool.getClient().execute(request); @@ -147,9 +147,9 @@ private void retrieveAdvisories(final String advisoriesEndCursor) throws IOExcep LOGGER.debug(queryTemplate); mirroredWithoutErrors = false; } else { - GitHubSecurityAdvisoryParser parser = new GitHubSecurityAdvisoryParser(); + var parser = new GitHubSecurityAdvisoryParser(); String responseString = EntityUtils.toString(response.getEntity()); - JSONObject jsonObject = new JSONObject(responseString); + var jsonObject = new JSONObject(responseString); final PageableList pageableList = parser.parse(jsonObject); updateDatasource(pageableList.getAdvisories()); if (pageableList.isHasNextPage()) { diff --git a/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java index aad477afef..4bdfefac3c 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java @@ -75,7 +75,7 @@ public MetaModel analyze(final Component component) { final HttpEntity entity = response.getEntity(); if (entity != null) { String responseString = EntityUtils.toString(entity); - JSONObject jsonObject = new JSONObject(responseString); + var jsonObject = new JSONObject(responseString); final JSONObject crate = jsonObject.optJSONObject("crate"); if (crate != null) { final String latest = crate.getString("newest_version"); diff --git a/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java index bc881f4f47..eeb9cdf59d 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/GemMetaAnalyzer.java @@ -70,7 +70,7 @@ public MetaModel analyze(final Component component) { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ if(response.getEntity()!=null){ String responseString = EntityUtils.toString(response.getEntity()); - JSONObject jsonObject = new JSONObject(responseString); + var jsonObject = new JSONObject(responseString); final String latest = jsonObject.getString("version"); meta.setLatestVersion(latest); } diff --git a/src/main/java/org/dependencytrack/tasks/repositories/GoModulesMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/GoModulesMetaAnalyzer.java index 696f5f3305..d6f8eaaa8d 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/GoModulesMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/GoModulesMetaAnalyzer.java @@ -69,7 +69,7 @@ public MetaModel analyze(final Component component) { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (response.getEntity()!=null) { String responseString = EntityUtils.toString(response.getEntity()); - final JSONObject responseJson = new org.json.JSONObject(responseString); + final var responseJson = new JSONObject(responseString); meta.setLatestVersion(responseJson.getString("Version")); // Module versions are prefixed with "v" in the Go ecosystem. diff --git a/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java index 3de2698d60..a3a0f747ed 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/HexMetaAnalyzer.java @@ -83,7 +83,7 @@ public MetaModel analyze(final Component component) { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (response.getEntity()!=null) { String responseString = EntityUtils.toString(response.getEntity()); - JSONObject jsonObject = new JSONObject(responseString); + var jsonObject = new JSONObject(responseString); final JSONArray releasesArray = jsonObject.getJSONArray("releases"); if (releasesArray.length() > 0) { // The first one in the array is always the latest version diff --git a/src/main/java/org/dependencytrack/tasks/repositories/MavenMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/MavenMetaAnalyzer.java index 0dc73707c5..dd2c2193e1 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/MavenMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/MavenMetaAnalyzer.java @@ -83,16 +83,16 @@ public MetaModel analyze(final Component component) { if (entity != null) { try (InputStream in = entity.getContent()) { final Document document = XmlUtil.buildSecureDocumentBuilder().parse(in); - final XPathFactory xpathFactory = XPathFactory.newInstance(); + final var xpathFactory = XPathFactory.newInstance(); final XPath xpath = xpathFactory.newXPath(); final XPathExpression releaseExpression = xpath.compile("/metadata/versioning/release"); final XPathExpression latestExpression = xpath.compile("/metadata/versioning/latest"); - final String release = (String) releaseExpression.evaluate(document, XPathConstants.STRING); + final var release = (String) releaseExpression.evaluate(document, XPathConstants.STRING); final String latest = (String) latestExpression.evaluate(document, XPathConstants.STRING); final XPathExpression lastUpdatedExpression = xpath.compile("/metadata/versioning/lastUpdated"); - final String lastUpdated = (String) lastUpdatedExpression.evaluate(document, XPathConstants.STRING); + final var lastUpdated = (String) lastUpdatedExpression.evaluate(document, XPathConstants.STRING); meta.setLatestVersion(release != null ? release : latest); if (lastUpdated != null) { diff --git a/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java index 2677519da3..0186f8af68 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/NpmMetaAnalyzer.java @@ -78,7 +78,7 @@ public MetaModel analyze(final Component component) { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (response.getEntity()!=null) { String responseString = EntityUtils.toString(response.getEntity()); - JSONObject jsonObject = new JSONObject(responseString); + var jsonObject = new JSONObject(responseString); final String latest = jsonObject.optString("latest"); if (latest != null) { meta.setLatestVersion(latest); diff --git a/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java index aaba26680c..dba7b99ddd 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzer.java @@ -108,7 +108,7 @@ private boolean performVersionCheck(final MetaModel meta, final Component compon if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (response.getEntity() != null) { String responseString = EntityUtils.toString(response.getEntity()); - JSONObject jsonObject = new JSONObject(responseString); + var jsonObject = new JSONObject(responseString); final JSONArray versions = jsonObject.getJSONArray("versions"); final String latest = findLatestVersion(versions); // get the last version in the array meta.setLatestVersion(latest); @@ -143,7 +143,7 @@ private String findLatestVersion(JSONArray versions) { private boolean performLastPublishedCheck(final MetaModel meta, final Component component) { final String url = String.format(registrationUrl, component.getPurl().getName().toLowerCase(), meta.getLatestVersion()); try (final CloseableHttpResponse response = processHttpRequest(url)) { - if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (response.getEntity() != null) { String stringResponse = EntityUtils.toString(response.getEntity()); if (!stringResponse.equalsIgnoreCase("") && !stringResponse.equalsIgnoreCase("{}")) { @@ -168,7 +168,7 @@ private void initializeEndpoints() { final String url = baseUrl + INDEX_URL; try { try (final CloseableHttpResponse response = processHttpRequest(url)) { - if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if(response.getEntity()!=null){ String responseString = EntityUtils.toString(response.getEntity()); JSONObject responseJson = new JSONObject(responseString); diff --git a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java index 55e5b12d74..af2888d88f 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java @@ -145,7 +145,7 @@ public void inform(final Event e) { } } } - final OssIndexAnalysisEvent event = (OssIndexAnalysisEvent) e; + final var event = (OssIndexAnalysisEvent) e; LOGGER.info("Starting Sonatype OSS Index analysis task"); vulnerabilityAnalysisLevel = event.getVulnerabilityAnalysisLevel(); if (event.getComponents().size() > 0) { diff --git a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java index 59b7383eea..e261944bb8 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java @@ -99,7 +99,7 @@ public void inform(final Event e) { return; } } - final VulnDbAnalysisEvent event = (VulnDbAnalysisEvent) e; + final var event = (VulnDbAnalysisEvent) e; vulnerabilityAnalysisLevel = event.getVulnerabilityAnalysisLevel(); LOGGER.info("Starting VulnDB analysis task"); if (!event.getComponents().isEmpty()) { @@ -125,7 +125,7 @@ public boolean isCapable(final Component component) { * @param components a list of Components */ public void analyze(final List components) { - final VulnDBUtil api = new VulnDBUtil(this.apiConsumerKey, this.apiConsumerSecret, this.apiBaseUrl); + final var api = new VulnDBUtil(this.apiConsumerKey, this.apiConsumerSecret, this.apiBaseUrl); for (final Component component : components) { if(isCacheCurrent(Vulnerability.Source.VULNDB, apiBaseUrl, component.getCpe())){ applyAnalysisFromCache(Vulnerability.Source.VULNDB, apiBaseUrl, component.getCpe(),component, AnalyzerIdentity.VULNDB_ANALYZER, vulnerabilityAnalysisLevel); diff --git a/src/main/java/org/dependencytrack/util/VulnDBUtil.java b/src/main/java/org/dependencytrack/util/VulnDBUtil.java index d703f9b521..1d36e5be12 100644 --- a/src/main/java/org/dependencytrack/util/VulnDBUtil.java +++ b/src/main/java/org/dependencytrack/util/VulnDBUtil.java @@ -1,6 +1,7 @@ package org.dependencytrack.util; import oauth.signpost.OAuthConsumer; +import org.apache.http.HttpStatus; import org.json.JSONArray; import org.json.JSONObject; import oauth.signpost.basic.DefaultOAuthConsumer; @@ -69,9 +70,9 @@ private Results getResults(String url, Class clazz, int size, int page) { Results results; try{ if (response != null) { - if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { String responseString = EntityUtils.toString(response.getEntity()); - JSONObject jsonObject = new JSONObject(responseString); + var jsonObject = new JSONObject(responseString); results = parse(jsonObject, clazz); return results; } else { From 5b2bcd08a2b766b1aa4620bec2315f075b53b008 Mon Sep 17 00:00:00 2001 From: mehab Date: Thu, 2 Feb 2023 12:36:07 +0000 Subject: [PATCH 19/31] some fixes Signed-off-by: mehab --- .../defectdojo/DefectDojoClient.java | 14 +++++++--- .../fortifyssc/FortifySscClient.java | 3 ++- .../model/VulnDb/VulnDbParser.java | 26 ++++++++++--------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java index c2ed5494c1..7f41170f7e 100644 --- a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java +++ b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java @@ -21,6 +21,7 @@ import alpine.common.logging.Logger; import com.google.common.base.Throwables; import org.apache.http.HttpStatus; +import org.apache.http.client.utils.URIBuilder; import org.json.JSONArray; import org.json.JSONObject; import org.apache.http.HttpEntity; @@ -36,8 +37,10 @@ import org.apache.http.util.EntityUtils; import org.dependencytrack.common.HttpClientPool; +import javax.ws.rs.core.UriBuilder; import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; @@ -96,12 +99,15 @@ public void uploadDependencyTrackFindings(final String token, final String engag // Pulling DefectDojo 'tests' API endpoint with engagementID filter on, and retrieve a list of existing tests public ArrayList getDojoTestIds(final String token, final String eid) { LOGGER.debug("Pulling DefectDojo Tests API ..."); - String tests_uri = "/api/v2/tests/"; + String testsUri = "/api/v2/tests/"; LOGGER.debug("Make the first pagination call"); - HttpGet request = new HttpGet(baseURL + tests_uri + "?limit=100&engagement=" + eid); + try{ + URIBuilder uriBuilder = new URIBuilder(baseURL +testsUri); + uriBuilder.addParameter("limit", "100"); + uriBuilder.addParameter("engagement", eid); + HttpGet request = new HttpGet(uriBuilder.build().toString()); request.addHeader("accept", "application/json"); request.addHeader("Authorization", "Token " + token); - try{ CloseableHttpResponse response = HttpClientPool.getClient().execute(request); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (response.getEntity()!=null) { @@ -131,6 +137,8 @@ public ArrayList getDojoTestIds(final String token, final String eid) { + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); }}catch (IOException ex){ LOGGER.error("Error while getting dojo test id's"+ex.getMessage()); + }catch (URISyntaxException ex){ + LOGGER.error("Error while creating get request url for Defect dojo client"); } return new ArrayList<>(); } diff --git a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java index 803efe29b6..1e56525bcd 100644 --- a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java +++ b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java @@ -19,6 +19,7 @@ package org.dependencytrack.integrations.fortifyssc; import alpine.common.logging.Logger; +import org.apache.http.entity.ContentType; import org.json.JSONObject; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; @@ -84,7 +85,7 @@ public void uploadDependencyTrackFindings(final String token, final String appli HttpPost request = new HttpPost(builder.build()); request.addHeader("accept", "application/xml"); HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE) - .addBinaryBody("files[]", findingsJson, org.apache.http.entity.ContentType.APPLICATION_JSON, "findings.json") + .addBinaryBody("files[]", findingsJson, ContentType.APPLICATION_JSON, "findings.json") .build(); request.setEntity(data); CloseableHttpResponse response = HttpClientPool.getClient().execute(request); diff --git a/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java b/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java index 05686d43a3..01e7505418 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java +++ b/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java @@ -88,19 +88,21 @@ public Results parse(String jsonData, Class apiObjec } public Results parse(File file, Class apiObject) throws IOException { - String jsonData = new String(Files.readAllBytes(Paths.get(file.toURI())), Charset.defaultCharset()); - Object result = null; - try{ - result = new JSONObject(jsonData); - }catch (JSONException ex){ - result = new JSONArray(jsonData); - } - if(result instanceof JSONObject){ - return this.parse((JSONObject)result, apiObject); - } else{ - return this.parse((JSONArray) result, apiObject); + if (file.isFile()) { + String jsonData = Files.readString(Paths.get(file.toURI()), Charset.defaultCharset()); + Object result = null; + try{ + result = new JSONObject(jsonData); + }catch (JSONException ex){ + result = new JSONArray(jsonData); + } + if(result instanceof JSONObject){ + return this.parse((JSONObject)result, apiObject); + } else{ + return this.parse((JSONArray) result, apiObject); + } } - + return null; } private List parseCpes(JSONArray rso) { From 3fa7d4f27e45a09df23a67efc0557d1008dadbd1 Mon Sep 17 00:00:00 2001 From: mehab Date: Thu, 2 Feb 2023 13:12:54 +0000 Subject: [PATCH 20/31] sonatype fixes Signed-off-by: mehab --- .../defectdojo/DefectDojoClient.java | 15 ++++++------- .../kenna/KennaSecurityUploader.java | 3 ++- .../model/VulnDb/VulnDbParser.java | 3 --- .../repositories/AbstractMetaAnalyzer.java | 21 +++++++++++++------ .../tasks/scanners/SnykAnalysisTask.java | 9 +++++--- .../org/dependencytrack/util/VulnDBUtil.java | 11 +++++++--- 6 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java index 7f41170f7e..d43525791e 100644 --- a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java +++ b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java @@ -19,7 +19,6 @@ package org.dependencytrack.integrations.defectdojo; import alpine.common.logging.Logger; -import com.google.common.base.Throwables; import org.apache.http.HttpStatus; import org.apache.http.client.utils.URIBuilder; import org.json.JSONArray; @@ -37,7 +36,6 @@ import org.apache.http.util.EntityUtils; import org.dependencytrack.common.HttpClientPool; -import javax.ws.rs.core.UriBuilder; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; @@ -45,7 +43,6 @@ import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; import java.util.List; @@ -92,7 +89,8 @@ public void uploadDependencyTrackFindings(final String token, final String engag uploader.handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } } catch (IOException ex) { - LOGGER.error("Error while sending request from upload DT findings defectDojo Client" + ex.getMessage()+" Stack trace: "+ Arrays.toString(ex.getStackTrace())); + LOGGER.warn("Error while sending request from upload DT findings defectDojo Client" + ex.getMessage()); + uploader.handleException(LOGGER, ex); } } @@ -136,9 +134,11 @@ public ArrayList getDojoTestIds(final String token, final String eid) { LOGGER.warn("DefectDojo Client did not receive expected response while attempting to retrieve tests list " + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); }}catch (IOException ex){ - LOGGER.error("Error while getting dojo test id's"+ex.getMessage()); + LOGGER.warn("Error while getting dojo test id's"+ex.getMessage()); + uploader.handleException(LOGGER, ex); }catch (URISyntaxException ex){ - LOGGER.error("Error while creating get request url for Defect dojo client"); + LOGGER.warn("Error while creating get request url for Defect dojo client"); + uploader.handleException(LOGGER, ex); } return new ArrayList<>(); } @@ -202,7 +202,8 @@ public void reimportDependencyTrackFindings(final String token, final String eng uploader.handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } }catch (IOException ex){ - LOGGER.error("Error while sending request from reimport DT findings defectDojo Client" + ex.getMessage()+" with stack trace: "+ Throwables.getStackTraceAsString(ex)); + LOGGER.warn("Error while sending request from reimport DT findings defectDojo Client" + ex.getMessage()); + uploader.handleException(LOGGER, ex); } } diff --git a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java index e1c8d9d895..aae99e8ce2 100644 --- a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java +++ b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java @@ -27,6 +27,7 @@ import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.message.BasicNameValuePair; @@ -103,7 +104,7 @@ public void upload(final InputStream payload) { nameValuePairList.add(new BasicNameValuePair("run", "true")); request.setEntity(new UrlEncodedFormEntity(nameValuePairList, StandardCharsets.UTF_8)); HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE) - .addBinaryBody("file", payload, org.apache.http.entity.ContentType.APPLICATION_JSON, "findings.json") + .addBinaryBody("file", payload, ContentType.APPLICATION_JSON, "findings.json") .build(); request.setEntity(data); final CloseableHttpResponse response = HttpClientPool.getClient().execute(request); diff --git a/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java b/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java index 01e7505418..fd89e81f0e 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java +++ b/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java @@ -88,7 +88,6 @@ public Results parse(String jsonData, Class apiObjec } public Results parse(File file, Class apiObject) throws IOException { - if (file.isFile()) { String jsonData = Files.readString(Paths.get(file.toURI()), Charset.defaultCharset()); Object result = null; try{ @@ -101,8 +100,6 @@ public Results parse(File file, Class apiObject) thr } else{ return this.parse((JSONArray) result, apiObject); } - } - return null; } private List parseCpes(JSONArray rso) { diff --git a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java index 03dcb4e8d9..47635e4883 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java @@ -25,6 +25,8 @@ import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.utils.URIBuilder; +import org.dependencytrack.RequirementsVerifier; import org.dependencytrack.common.HttpClientPool; import org.dependencytrack.model.Component; import org.dependencytrack.notification.NotificationConstants; @@ -33,6 +35,7 @@ import org.dependencytrack.util.HttpUtil; import java.io.IOException; +import java.net.URISyntaxException; /** * Base abstract class that all IMetaAnalyzer implementations should likely extend. @@ -47,7 +50,7 @@ public abstract class AbstractMetaAnalyzer implements IMetaAnalyzer { protected String username; protected String password; - + private static final Logger LOGGER = Logger.getLogger(AbstractMetaAnalyzer.class); /** * {@inheritDoc} */ @@ -92,12 +95,18 @@ protected void handleRequestException(final Logger logger, final Exception e) { } protected CloseableHttpResponse processHttpRequest(String url) throws IOException { - final HttpUriRequest request = new HttpGet(url); - request.addHeader("accept", "application/json"); - if (username != null || password != null) { - request.addHeader("Authorization", HttpUtil.basicAuthHeaderValue(username, password)); + try { + URIBuilder uriBuilder = new URIBuilder(url); + final HttpUriRequest request = new HttpGet(uriBuilder.build().toString()); + request.addHeader("accept", "application/json"); + if (username != null || password != null) { + request.addHeader("Authorization", HttpUtil.basicAuthHeaderValue(username, password)); + } + return HttpClientPool.getClient().execute(request); + }catch (URISyntaxException ex){ + handleRequestException(LOGGER, ex); + return null; } - return HttpClientPool.getClient().execute(request); } } diff --git a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java index 3a33aeb0ef..fadbf7521a 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java @@ -38,6 +38,7 @@ import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.utils.URIBuilder; import org.json.JSONArray; import org.json.JSONObject; import org.apache.commons.lang3.StringUtils; @@ -63,6 +64,7 @@ import org.dependencytrack.util.RoundRobinAccessor; import java.io.IOException; +import java.net.URISyntaxException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.Duration; @@ -298,11 +300,12 @@ public void applyAnalysisFromCache(final Component component) { private void analyzeComponent(final Component component) { final String encodedPurl = URLEncoder.encode(component.getPurl().getCoordinates(), StandardCharsets.UTF_8); final String requestUrl = "%s/rest/orgs/%s/packages/%s/issues?version=%s".formatted(apiBaseUrl, apiOrgId, encodedPurl, apiVersion); - final HttpUriRequest request = new HttpGet(requestUrl); + try { + URIBuilder uriBuilder = new URIBuilder(requestUrl); + final HttpUriRequest request = new HttpGet(uriBuilder.build().toString()); request.setHeader(HttpHeaders.USER_AGENT, ManagedHttpClientFactory.getUserAgent()); request.setHeader(HttpHeaders.AUTHORIZATION, "token " + apiTokenSupplier.get()); request.setHeader(HttpHeaders.ACCEPT, "application/vnd.api+json"); - try { final CloseableHttpResponse response = RETRY.executeSupplier(() -> { try { return HttpClientPool.getClient().execute(request); @@ -337,7 +340,7 @@ private void analyzeComponent(final Component component) { } else { handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } - }catch (IOException ex){ + }catch (IOException | URISyntaxException ex){ handleRequestException(LOGGER, ex); } } diff --git a/src/main/java/org/dependencytrack/util/VulnDBUtil.java b/src/main/java/org/dependencytrack/util/VulnDBUtil.java index 1d36e5be12..b9a2102a10 100644 --- a/src/main/java/org/dependencytrack/util/VulnDBUtil.java +++ b/src/main/java/org/dependencytrack/util/VulnDBUtil.java @@ -2,6 +2,8 @@ import oauth.signpost.OAuthConsumer; import org.apache.http.HttpStatus; +import org.apache.http.client.utils.URIBuilder; +import org.dependencytrack.tasks.scanners.BaseComponentAnalyzerTask; import org.json.JSONArray; import org.json.JSONObject; import oauth.signpost.basic.DefaultOAuthConsumer; @@ -31,9 +33,11 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; +import java.net.URISyntaxException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class VulnDBUtil { @@ -96,11 +100,12 @@ private CloseableHttpResponse makeRequest(String url) { try { OAuthConsumer consumer = new DefaultOAuthConsumer(this.consumerKey, this.consumerSecret); String signed = consumer.sign(url); - HttpGet request = new HttpGet(signed); + URIBuilder uriBuilder = new URIBuilder(signed); + HttpGet request = new HttpGet(uriBuilder.build().toString()); request.addHeader("X-User-Agent", "VulnDB Data Mirror (https://github.com/stevespringett/vulndb-data-mirror)"); return HttpClientPool.getClient().execute(request); - } catch (IOException | OAuthException var4) { - LOGGER.error("An error occurred making request: " + url, var4); + } catch (IOException | OAuthException | URISyntaxException var4) { + LOGGER.error("An error occurred making request: " + url, var4.getMessage()+ "stack trace: "+ Arrays.toString(var4.getStackTrace())); return null; } } From c34cec86749f933c86a51eda8efa01a9e18abf78 Mon Sep 17 00:00:00 2001 From: mehab Date: Thu, 2 Feb 2023 13:22:42 +0000 Subject: [PATCH 21/31] sonatype fixes Signed-off-by: mehab --- .../integrations/defectdojo/DefectDojoClient.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java index d43525791e..eb788c1929 100644 --- a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java +++ b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java @@ -117,7 +117,8 @@ public ArrayList getDojoTestIds(final String token, final String eid) { while (dojoObj.get("next") != null) { nextUrl = dojoObj.get("next").toString(); LOGGER.debug("Making the subsequent pagination call on " + nextUrl); - request = new HttpGet(nextUrl); + uriBuilder = new URIBuilder(nextUrl); + request = new HttpGet(uriBuilder.build().toString()); request.addHeader("accept", "application/json"); request.addHeader("Authorization", "Token " + token); response = HttpClientPool.getClient().execute(request); From 9496c4c1cc499649c0a298536c7a5cb6cc8fc239 Mon Sep 17 00:00:00 2001 From: mehab Date: Fri, 3 Feb 2023 11:28:08 +0000 Subject: [PATCH 22/31] PR review fixes Signed-off-by: mehab --- .../defectdojo/DefectDojoUploader.java | 5 +- .../fortifyssc/FortifySscClient.java | 2 +- .../fortifyssc/FortifySscUploader.java | 5 +- .../kenna/KennaSecurityUploader.java | 4 +- .../model/{VulnDb => vulnDb}/ApiObject.java | 2 +- .../model/{VulnDb => vulnDb}/Author.java | 2 +- .../{VulnDb => vulnDb}/Classification.java | 2 +- .../model/{VulnDb => vulnDb}/Cpe.java | 2 +- .../{VulnDb => vulnDb}/CvssV2Metric.java | 2 +- .../{VulnDb => vulnDb}/CvssV3Metric.java | 2 +- .../{VulnDb => vulnDb}/ExternalReference.java | 2 +- .../{VulnDb => vulnDb}/ExternalText.java | 2 +- .../{VulnDb => vulnDb}/NvdAdditionalInfo.java | 2 +- .../model/{VulnDb => vulnDb}/Product.java | 5 +- .../model/{VulnDb => vulnDb}/Results.java | 2 +- .../model/{VulnDb => vulnDb}/Status.java | 2 +- .../model/{VulnDb => vulnDb}/Vendor.java | 5 +- .../model/{VulnDb => vulnDb}/Version.java | 5 +- .../{VulnDb => vulnDb}/VulnDbParser.java | 17 +------ .../{VulnDb => vulnDb}/Vulnerability.java | 12 +---- .../parser/vulndb/ModelConverter.java | 10 ++-- .../policy/ComponentHashPolicyEvaluator.java | 4 +- .../v1/NotificationPublisherResource.java | 17 ++++++- .../FuzzyVulnerableSoftwareSearchManager.java | 11 ++++- .../dependencytrack/tasks/VulnDbSyncTask.java | 20 ++++---- .../repositories/AbstractMetaAnalyzer.java | 1 - .../tasks/scanners/VulnDbAnalysisTask.java | 17 +++++-- .../org/dependencytrack/util/VulnDBUtil.java | 47 ++++++++++--------- .../org/dependencytrack/util/XmlUtil.java | 4 +- .../dependencytrack/auth/PermissionsTest.java | 14 +++++- .../ProjectQueryFilterBuilderTest.java | 4 +- .../policy/CwePolicyEvaluatorTest.java | 6 ++- .../policy/PolicyEngineTest.java | 9 +++- ...zyVulnerableSoftwareSearchManagerTest.java | 18 +++++-- .../scanners/VulnDBAnalysisTaskTest.java | 6 ++- 35 files changed, 158 insertions(+), 112 deletions(-) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/ApiObject.java (64%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/Author.java (96%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/Classification.java (95%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/Cpe.java (89%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/CvssV2Metric.java (98%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/CvssV3Metric.java (99%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/ExternalReference.java (90%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/ExternalText.java (90%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/NvdAdditionalInfo.java (93%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/Product.java (83%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/Results.java (96%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/Status.java (98%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/Vendor.java (88%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/Version.java (86%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/VulnDbParser.java (95%) rename src/main/java/org/dependencytrack/model/{VulnDb => vulnDb}/Vulnerability.java (92%) diff --git a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoUploader.java b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoUploader.java index 53273c9f1a..213dcf92c6 100644 --- a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoUploader.java +++ b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoUploader.java @@ -33,7 +33,10 @@ import java.util.ArrayList; import java.util.List; -import static org.dependencytrack.model.ConfigPropertyConstants.*; +import static org.dependencytrack.model.ConfigPropertyConstants.DEFECTDOJO_API_KEY; +import static org.dependencytrack.model.ConfigPropertyConstants.DEFECTDOJO_ENABLED; +import static org.dependencytrack.model.ConfigPropertyConstants.DEFECTDOJO_URL; +import static org.dependencytrack.model.ConfigPropertyConstants.DEFECTDOJO_REIMPORT_ENABLED; public class DefectDojoUploader extends AbstractIntegrationPoint implements ProjectFindingUploader { diff --git a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java index 1e56525bcd..089bd24760 100644 --- a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java +++ b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java @@ -36,7 +36,7 @@ import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.Base64; public class FortifySscClient { diff --git a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscUploader.java b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscUploader.java index d6e3d9b705..06cd136762 100644 --- a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscUploader.java +++ b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscUploader.java @@ -34,7 +34,10 @@ import java.net.URL; import java.util.List; -import static org.dependencytrack.model.ConfigPropertyConstants.*; +import static org.dependencytrack.model.ConfigPropertyConstants.FORTIFY_SSC_ENABLED; +import static org.dependencytrack.model.ConfigPropertyConstants.FORTIFY_SSC_URL; +import static org.dependencytrack.model.ConfigPropertyConstants.FORTIFY_SSC_TOKEN; + public class FortifySscUploader extends AbstractIntegrationPoint implements ProjectFindingUploader { diff --git a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java index aae99e8ce2..68c780fbbc 100644 --- a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java +++ b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java @@ -45,7 +45,9 @@ import java.util.ArrayList; import java.util.List; -import static org.dependencytrack.model.ConfigPropertyConstants.*; +import static org.dependencytrack.model.ConfigPropertyConstants.KENNA_ENABLED; +import static org.dependencytrack.model.ConfigPropertyConstants.KENNA_CONNECTOR_ID; +import static org.dependencytrack.model.ConfigPropertyConstants.KENNA_TOKEN; public class KennaSecurityUploader extends AbstractIntegrationPoint implements PortfolioFindingUploader { diff --git a/src/main/java/org/dependencytrack/model/VulnDb/ApiObject.java b/src/main/java/org/dependencytrack/model/vulnDb/ApiObject.java similarity index 64% rename from src/main/java/org/dependencytrack/model/VulnDb/ApiObject.java rename to src/main/java/org/dependencytrack/model/vulnDb/ApiObject.java index a212d3757a..faf5835ab5 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/ApiObject.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/ApiObject.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; public interface ApiObject { int getId(); diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Author.java b/src/main/java/org/dependencytrack/model/vulnDb/Author.java similarity index 96% rename from src/main/java/org/dependencytrack/model/VulnDb/Author.java rename to src/main/java/org/dependencytrack/model/vulnDb/Author.java index c2de577920..704f61b263 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/Author.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/Author.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; public class Author { private int id; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Classification.java b/src/main/java/org/dependencytrack/model/vulnDb/Classification.java similarity index 95% rename from src/main/java/org/dependencytrack/model/VulnDb/Classification.java rename to src/main/java/org/dependencytrack/model/vulnDb/Classification.java index 493e673ab6..37d899835f 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/Classification.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/Classification.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; public class Classification { private int id; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Cpe.java b/src/main/java/org/dependencytrack/model/vulnDb/Cpe.java similarity index 89% rename from src/main/java/org/dependencytrack/model/VulnDb/Cpe.java rename to src/main/java/org/dependencytrack/model/vulnDb/Cpe.java index c2d9e52edc..be145afff1 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/Cpe.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/Cpe.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; public class Cpe { private String cpe; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/CvssV2Metric.java b/src/main/java/org/dependencytrack/model/vulnDb/CvssV2Metric.java similarity index 98% rename from src/main/java/org/dependencytrack/model/VulnDb/CvssV2Metric.java rename to src/main/java/org/dependencytrack/model/vulnDb/CvssV2Metric.java index 2a7c7a504b..aa5c6a9843 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/CvssV2Metric.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/CvssV2Metric.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; import us.springett.cvss.CvssV2; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/CvssV3Metric.java b/src/main/java/org/dependencytrack/model/vulnDb/CvssV3Metric.java similarity index 99% rename from src/main/java/org/dependencytrack/model/VulnDb/CvssV3Metric.java rename to src/main/java/org/dependencytrack/model/vulnDb/CvssV3Metric.java index 5580dd5c2c..3e1da2b00c 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/CvssV3Metric.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/CvssV3Metric.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; import us.springett.cvss.CvssV3; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/ExternalReference.java b/src/main/java/org/dependencytrack/model/vulnDb/ExternalReference.java similarity index 90% rename from src/main/java/org/dependencytrack/model/VulnDb/ExternalReference.java rename to src/main/java/org/dependencytrack/model/vulnDb/ExternalReference.java index 6c58be8b59..0cfa333419 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/ExternalReference.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/ExternalReference.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; public class ExternalReference { private String type; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/ExternalText.java b/src/main/java/org/dependencytrack/model/vulnDb/ExternalText.java similarity index 90% rename from src/main/java/org/dependencytrack/model/VulnDb/ExternalText.java rename to src/main/java/org/dependencytrack/model/vulnDb/ExternalText.java index 52f4d2a168..3ab72ffd5f 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/ExternalText.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/ExternalText.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; public class ExternalText { private String type; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/NvdAdditionalInfo.java b/src/main/java/org/dependencytrack/model/vulnDb/NvdAdditionalInfo.java similarity index 93% rename from src/main/java/org/dependencytrack/model/VulnDb/NvdAdditionalInfo.java rename to src/main/java/org/dependencytrack/model/vulnDb/NvdAdditionalInfo.java index af486e1f5c..4906588458 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/NvdAdditionalInfo.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/NvdAdditionalInfo.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; public class NvdAdditionalInfo { private String summary; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Product.java b/src/main/java/org/dependencytrack/model/vulnDb/Product.java similarity index 83% rename from src/main/java/org/dependencytrack/model/VulnDb/Product.java rename to src/main/java/org/dependencytrack/model/vulnDb/Product.java index d4cd4d7858..514b731424 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/Product.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/Product.java @@ -1,9 +1,6 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; -import org.dependencytrack.model.VulnDb.ApiObject; -import org.dependencytrack.model.VulnDb.Version; - import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Results.java b/src/main/java/org/dependencytrack/model/vulnDb/Results.java similarity index 96% rename from src/main/java/org/dependencytrack/model/VulnDb/Results.java rename to src/main/java/org/dependencytrack/model/vulnDb/Results.java index 0487e9f550..3191558491 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/Results.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/Results.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Status.java b/src/main/java/org/dependencytrack/model/vulnDb/Status.java similarity index 98% rename from src/main/java/org/dependencytrack/model/VulnDb/Status.java rename to src/main/java/org/dependencytrack/model/vulnDb/Status.java index 1298dea0f5..4d94d6461e 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/Status.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/Status.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; public class Status { private String organizationName; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Vendor.java b/src/main/java/org/dependencytrack/model/vulnDb/Vendor.java similarity index 88% rename from src/main/java/org/dependencytrack/model/VulnDb/Vendor.java rename to src/main/java/org/dependencytrack/model/vulnDb/Vendor.java index 8ecbbc624f..cab2f064da 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/Vendor.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/Vendor.java @@ -1,7 +1,4 @@ -package org.dependencytrack.model.VulnDb; - -import org.dependencytrack.model.VulnDb.ApiObject; -import org.dependencytrack.model.VulnDb.Product; +package org.dependencytrack.model.vulnDb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Version.java b/src/main/java/org/dependencytrack/model/vulnDb/Version.java similarity index 86% rename from src/main/java/org/dependencytrack/model/VulnDb/Version.java rename to src/main/java/org/dependencytrack/model/vulnDb/Version.java index ef84fa8951..f680cb470f 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/Version.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/Version.java @@ -1,7 +1,4 @@ -package org.dependencytrack.model.VulnDb; - -import org.dependencytrack.model.VulnDb.ApiObject; -import org.dependencytrack.model.VulnDb.Cpe; +package org.dependencytrack.model.vulnDb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java b/src/main/java/org/dependencytrack/model/vulnDb/VulnDbParser.java similarity index 95% rename from src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java rename to src/main/java/org/dependencytrack/model/vulnDb/VulnDbParser.java index fd89e81f0e..02e830cdb4 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/VulnDbParser.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/VulnDbParser.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.VulnDb; +package org.dependencytrack.model.vulnDb; import java.io.File; import java.io.IOException; @@ -14,21 +14,6 @@ import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.dependencytrack.model.VulnDb.ApiObject; -import org.dependencytrack.model.VulnDb.Author; -import org.dependencytrack.model.VulnDb.Cpe; -import org.dependencytrack.model.VulnDb.Classification; -import org.dependencytrack.model.VulnDb.CvssV2Metric; -import org.dependencytrack.model.VulnDb.CvssV3Metric; -import org.dependencytrack.model.VulnDb.ExternalReference; -import org.dependencytrack.model.VulnDb.ExternalText; -import org.dependencytrack.model.VulnDb.NvdAdditionalInfo; -import org.dependencytrack.model.VulnDb.Product; -import org.dependencytrack.model.VulnDb.Results; -import org.dependencytrack.model.VulnDb.Status; -import org.dependencytrack.model.VulnDb.Vendor; -import org.dependencytrack.model.VulnDb.Version; -import org.dependencytrack.model.VulnDb.Vulnerability; public class VulnDbParser { private static final Logger LOGGER = LoggerFactory.getLogger(VulnDbParser.class); diff --git a/src/main/java/org/dependencytrack/model/VulnDb/Vulnerability.java b/src/main/java/org/dependencytrack/model/vulnDb/Vulnerability.java similarity index 92% rename from src/main/java/org/dependencytrack/model/VulnDb/Vulnerability.java rename to src/main/java/org/dependencytrack/model/vulnDb/Vulnerability.java index 503bbb1a84..3b27cf9d6f 100644 --- a/src/main/java/org/dependencytrack/model/VulnDb/Vulnerability.java +++ b/src/main/java/org/dependencytrack/model/vulnDb/Vulnerability.java @@ -1,14 +1,4 @@ -package org.dependencytrack.model.VulnDb; - -import org.dependencytrack.model.VulnDb.ApiObject; -import org.dependencytrack.model.VulnDb.Author; -import org.dependencytrack.model.VulnDb.Classification; -import org.dependencytrack.model.VulnDb.CvssV2Metric; -import org.dependencytrack.model.VulnDb.CvssV3Metric; -import org.dependencytrack.model.VulnDb.ExternalReference; -import org.dependencytrack.model.VulnDb.ExternalText; -import org.dependencytrack.model.VulnDb.NvdAdditionalInfo; -import org.dependencytrack.model.VulnDb.Vendor; +package org.dependencytrack.model.vulnDb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java b/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java index 8f69693c12..a81a68d084 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java @@ -21,16 +21,16 @@ import alpine.common.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.dependencytrack.model.Cwe; -import org.dependencytrack.model.VulnDb.Author; -import org.dependencytrack.model.VulnDb.ExternalReference; +import org.dependencytrack.model.vulnDb.Author; +import org.dependencytrack.model.vulnDb.ExternalReference; import org.dependencytrack.model.Vulnerability; import org.dependencytrack.parser.common.resolver.CweResolver; import org.dependencytrack.persistence.QueryManager; import us.springett.cvss.CvssV2; import us.springett.cvss.CvssV3; import us.springett.cvss.Score; -import org.dependencytrack.model.VulnDb.CvssV2Metric; -import org.dependencytrack.model.VulnDb.CvssV3Metric; +import org.dependencytrack.model.vulnDb.CvssV2Metric; +import org.dependencytrack.model.vulnDb.CvssV3Metric; import java.math.BigDecimal; import java.time.OffsetDateTime; @@ -56,7 +56,7 @@ private ModelConverter() { } * @param vulnDbVuln the VulnDB vulnerability to convert * @return a Dependency-Track Vulnerability object */ - public static Vulnerability convert(final QueryManager qm, final org.dependencytrack.model.VulnDb.Vulnerability vulnDbVuln) { + public static Vulnerability convert(final QueryManager qm, final org.dependencytrack.model.vulnDb.Vulnerability vulnDbVuln) { final org.dependencytrack.model.Vulnerability vuln = new org.dependencytrack.model.Vulnerability(); vuln.setSource(org.dependencytrack.model.Vulnerability.Source.VULNDB); vuln.setVulnId(sanitize(String.valueOf(vulnDbVuln.getId()))); diff --git a/src/main/java/org/dependencytrack/policy/ComponentHashPolicyEvaluator.java b/src/main/java/org/dependencytrack/policy/ComponentHashPolicyEvaluator.java index 35e224ff5e..7aac2ec5c6 100644 --- a/src/main/java/org/dependencytrack/policy/ComponentHashPolicyEvaluator.java +++ b/src/main/java/org/dependencytrack/policy/ComponentHashPolicyEvaluator.java @@ -21,7 +21,9 @@ import alpine.common.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.cyclonedx.model.Hash; -import org.dependencytrack.model.*; +import org.dependencytrack.model.Policy; +import org.dependencytrack.model.Component; +import org.dependencytrack.model.PolicyCondition; import org.json.JSONObject; import java.util.ArrayList; diff --git a/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java b/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java index e1d767c06e..b8bf769e01 100644 --- a/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java @@ -24,7 +24,12 @@ import alpine.notification.NotificationLevel; import alpine.server.auth.PermissionRequired; import alpine.server.resources.AlpineResource; -import io.swagger.annotations.*; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.Api; +import io.swagger.annotations.Authorization; import org.dependencytrack.auth.Permissions; import org.dependencytrack.model.ConfigPropertyConstants; import org.dependencytrack.model.NotificationPublisher; @@ -40,7 +45,15 @@ import javax.json.Json; import javax.json.JsonObject; import javax.validation.Validator; -import javax.ws.rs.*; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.GET; +import javax.ws.rs.Produces; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.PathParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.IOException; diff --git a/src/main/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManager.java b/src/main/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManager.java index 769cd99562..e5d32c9788 100644 --- a/src/main/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManager.java +++ b/src/main/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManager.java @@ -27,7 +27,16 @@ import us.springett.parsers.cpe.values.Part; import java.io.IOException; -import java.util.*; +import java.util.Set; +import java.util.Objects; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.LinkedList; + public class FuzzyVulnerableSoftwareSearchManager { diff --git a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java index 94f34c088b..56b38c6cb9 100644 --- a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java +++ b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java @@ -37,11 +37,11 @@ import us.springett.parsers.cpe.CpeParser; import us.springett.parsers.cpe.exceptions.CpeEncodingException; import us.springett.parsers.cpe.exceptions.CpeParsingException; -import org.dependencytrack.model.VulnDb.VulnDbParser; -import org.dependencytrack.model.VulnDb.Product; -import org.dependencytrack.model.VulnDb.Results; -import org.dependencytrack.model.VulnDb.Vendor; -import org.dependencytrack.model.VulnDb.Version; +import org.dependencytrack.model.vulnDb.VulnDbParser; +import org.dependencytrack.model.vulnDb.Product; +import org.dependencytrack.model.vulnDb.Results; +import org.dependencytrack.model.vulnDb.Vendor; +import org.dependencytrack.model.vulnDb.Version; import java.io.File; import java.io.IOException; @@ -84,7 +84,7 @@ public void inform(final Event e) { LOGGER.info("Parsing: " + file.getName()); final VulnDbParser parser = new VulnDbParser(); try { - final Results results = parser.parse(file, org.dependencytrack.model.VulnDb.Vulnerability.class); + final Results results = parser.parse(file, org.dependencytrack.model.vulnDb.Vulnerability.class); updateDatasource(results); } catch (IOException ex) { LOGGER.error("An error occurred while parsing VulnDB payload: " + file.getName(), ex); @@ -121,8 +121,8 @@ private void updateDatasource(final Results results) { LOGGER.info("Updating datasource with VulnDB vulnerabilities"); try (QueryManager qm = new QueryManager()) { for (final Object o: results.getResults()) { - if (o instanceof org.dependencytrack.model.VulnDb.Vulnerability) { - final org.dependencytrack.model.VulnDb.Vulnerability vulnDbVuln = (org.dependencytrack.model.VulnDb.Vulnerability)o; + if (o instanceof org.dependencytrack.model.vulnDb.Vulnerability) { + final org.dependencytrack.model.vulnDb.Vulnerability vulnDbVuln = (org.dependencytrack.model.vulnDb.Vulnerability)o; final org.dependencytrack.model.Vulnerability vulnerability = ModelConverter.convert(qm, vulnDbVuln); final Vulnerability synchronizeVulnerability = qm.synchronizeVulnerability(vulnerability, false); final List vsListOld = qm.detach(qm.getVulnerableSoftwareByVulnId(synchronizeVulnerability.getSource(), synchronizeVulnerability.getVulnId())); @@ -137,7 +137,7 @@ private void updateDatasource(final Results results) { } public static List parseCpes(final QueryManager qm, final Vulnerability vulnerability, - final org.dependencytrack.model.VulnDb.Vulnerability vulnDbVuln) { + final org.dependencytrack.model.vulnDb.Vulnerability vulnDbVuln) { // cpe:2.3:a:belavier_commerce:abantecart:1.2.8:*:*:*:*:*:*:* final List vsList = new ArrayList<>(); if (vulnDbVuln.getVendors() != null) { @@ -149,7 +149,7 @@ public static List parseCpes(final QueryManager qm, final Vu if (version != null) { if (version.isAffected()) { if (version.getCpes() != null) { - for (org.dependencytrack.model.VulnDb.Cpe cpeObject : version.getCpes()) { + for (org.dependencytrack.model.vulnDb.Cpe cpeObject : version.getCpes()) { try { final Cpe cpe = CpeParser.parse(cpeObject.getCpe(), true); final VulnerableSoftware vs = generateVulnerableSoftware(qm, cpe, vulnerability); diff --git a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java index 47635e4883..cdb35ac1b0 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java @@ -26,7 +26,6 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.utils.URIBuilder; -import org.dependencytrack.RequirementsVerifier; import org.dependencytrack.common.HttpClientPool; import org.dependencytrack.model.Component; import org.dependencytrack.notification.NotificationConstants; diff --git a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java index e261944bb8..b03e007349 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java @@ -23,17 +23,22 @@ import alpine.event.framework.Subscriber; import alpine.model.ConfigProperty; import alpine.security.crypto.DataEncryption; +import oauth.signpost.exception.OAuthCommunicationException; +import oauth.signpost.exception.OAuthExpectationFailedException; +import oauth.signpost.exception.OAuthMessageSignerException; import org.dependencytrack.event.VulnDbAnalysisEvent; import org.dependencytrack.model.Component; import org.dependencytrack.model.ConfigPropertyConstants; import org.dependencytrack.model.Vulnerability; import org.dependencytrack.model.VulnerabilityAnalysisLevel; +import org.dependencytrack.model.vulnDb.Results; import org.dependencytrack.parser.vulndb.ModelConverter; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.util.NotificationUtil; import org.dependencytrack.util.VulnDBUtil; -import org.dependencytrack.model.VulnDb.Results; +import java.io.IOException; +import java.net.URISyntaxException; import java.util.List; /** @@ -136,14 +141,20 @@ public void analyze(final List components) { int page = 1; boolean more = true; while (more) { + try{ final Results results = api.getVulnerabilitiesByCpe(component.getCpe(), PAGE_SIZE, page); if (results.isSuccessful()) { more = processResults(results, component); page++; } else { - LOGGER.error(results.getErrorCondition()); + LOGGER.warn(results.getErrorCondition()); + handleRequestException(LOGGER, new Exception(results.getErrorCondition())); return; } + }catch (IOException | OAuthMessageSignerException | OAuthExpectationFailedException | + URISyntaxException | OAuthCommunicationException ex){ + handleRequestException(LOGGER, ex); + } } } } @@ -154,7 +165,7 @@ public void analyze(final List components) { private boolean processResults(final Results results, final Component component) { try (final QueryManager qm = new QueryManager()) { final Component vulnerableComponent = qm.getObjectByUuid(Component.class, component.getUuid()); // Refresh component and attach to current pm. - for (org.dependencytrack.model.VulnDb.Vulnerability vulnDbVuln : (List) results.getResults()) { + for (org.dependencytrack.model.vulnDb.Vulnerability vulnDbVuln : (List) results.getResults()) { Vulnerability vulnerability = qm.getVulnerabilityByVulnId(Vulnerability.Source.VULNDB, String.valueOf(vulnDbVuln.getId())); if (vulnerability == null) { vulnerability = qm.createVulnerability(ModelConverter.convert(qm, vulnDbVuln), false); diff --git a/src/main/java/org/dependencytrack/util/VulnDBUtil.java b/src/main/java/org/dependencytrack/util/VulnDBUtil.java index b9a2102a10..ed780ccf27 100644 --- a/src/main/java/org/dependencytrack/util/VulnDBUtil.java +++ b/src/main/java/org/dependencytrack/util/VulnDBUtil.java @@ -1,9 +1,11 @@ package org.dependencytrack.util; import oauth.signpost.OAuthConsumer; +import oauth.signpost.exception.OAuthCommunicationException; +import oauth.signpost.exception.OAuthExpectationFailedException; +import oauth.signpost.exception.OAuthMessageSignerException; import org.apache.http.HttpStatus; import org.apache.http.client.utils.URIBuilder; -import org.dependencytrack.tasks.scanners.BaseComponentAnalyzerTask; import org.json.JSONArray; import org.json.JSONObject; import oauth.signpost.basic.DefaultOAuthConsumer; @@ -15,20 +17,20 @@ import org.dependencytrack.common.HttpClientPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.dependencytrack.model.VulnDb.Cpe; -import org.dependencytrack.model.VulnDb.Product; -import org.dependencytrack.model.VulnDb.Results; -import org.dependencytrack.model.VulnDb.Vendor; -import org.dependencytrack.model.VulnDb.Version; -import org.dependencytrack.model.VulnDb.ApiObject; -import org.dependencytrack.model.VulnDb.Vulnerability; -import org.dependencytrack.model.VulnDb.Classification; -import org.dependencytrack.model.VulnDb.Author; -import org.dependencytrack.model.VulnDb.CvssV2Metric; -import org.dependencytrack.model.VulnDb.CvssV3Metric; -import org.dependencytrack.model.VulnDb.NvdAdditionalInfo; -import org.dependencytrack.model.VulnDb.ExternalText; -import org.dependencytrack.model.VulnDb.ExternalReference; +import org.dependencytrack.model.vulnDb.Cpe; +import org.dependencytrack.model.vulnDb.Product; +import org.dependencytrack.model.vulnDb.Results; +import org.dependencytrack.model.vulnDb.Vendor; +import org.dependencytrack.model.vulnDb.Version; +import org.dependencytrack.model.vulnDb.ApiObject; +import org.dependencytrack.model.vulnDb.Vulnerability; +import org.dependencytrack.model.vulnDb.Classification; +import org.dependencytrack.model.vulnDb.Author; +import org.dependencytrack.model.vulnDb.CvssV2Metric; +import org.dependencytrack.model.vulnDb.CvssV3Metric; +import org.dependencytrack.model.vulnDb.NvdAdditionalInfo; +import org.dependencytrack.model.vulnDb.ExternalText; +import org.dependencytrack.model.vulnDb.ExternalReference; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -56,19 +58,20 @@ public VulnDBUtil(String consumerKey, String consumerSecret, String apiBaseUrl) private static final Logger LOGGER = LoggerFactory.getLogger(VulnDBUtil.class); - public Results getVulnerabilitiesByCpe(String cpe, int size, int page) { + public Results getVulnerabilitiesByCpe(String cpe, int size, int page) throws IOException, OAuthMessageSignerException, OAuthExpectationFailedException, URISyntaxException, OAuthCommunicationException { String encodedCpe = cpe; try { encodedCpe = URLEncoder.encode(cpe, StandardCharsets.UTF_8.name()); } catch (UnsupportedEncodingException var6) { - LOGGER.error("An error occurred while URL encoding a CPE", var6); + LOGGER.warn("An error occurred while URL encoding a CPE", var6); + throw new UnsupportedEncodingException(); } return this.getResults(apiBaseUrl+"/api/v1/vulnerabilities/find_by_cpe?&cpe=" + encodedCpe, Vulnerability.class, size, page); } - private Results getResults(String url, Class clazz, int size, int page) { + private Results getResults(String url, Class clazz, int size, int page) throws IOException, OAuthMessageSignerException, OAuthExpectationFailedException, URISyntaxException, OAuthCommunicationException { String modifiedUrl = url.contains("?") ? url + "&" : url + "?"; CloseableHttpResponse response = this.makeRequest(modifiedUrl + "size=" + size + "&page=" + page); Results results; @@ -91,12 +94,11 @@ private Results getResults(String url, Class clazz, int size, int page) { return results; } }catch (IOException ex){ - LOGGER.error("An error occurred making request: " + url); - return null; + throw ex; } } - private CloseableHttpResponse makeRequest(String url) { + private CloseableHttpResponse makeRequest(String url) throws OAuthMessageSignerException, OAuthExpectationFailedException, IOException, URISyntaxException, OAuthCommunicationException { try { OAuthConsumer consumer = new DefaultOAuthConsumer(this.consumerKey, this.consumerSecret); String signed = consumer.sign(url); @@ -105,8 +107,7 @@ private CloseableHttpResponse makeRequest(String url) { request.addHeader("X-User-Agent", "VulnDB Data Mirror (https://github.com/stevespringett/vulndb-data-mirror)"); return HttpClientPool.getClient().execute(request); } catch (IOException | OAuthException | URISyntaxException var4) { - LOGGER.error("An error occurred making request: " + url, var4.getMessage()+ "stack trace: "+ Arrays.toString(var4.getStackTrace())); - return null; + throw var4; } } diff --git a/src/main/java/org/dependencytrack/util/XmlUtil.java b/src/main/java/org/dependencytrack/util/XmlUtil.java index f54ab8f617..a4787f8cea 100644 --- a/src/main/java/org/dependencytrack/util/XmlUtil.java +++ b/src/main/java/org/dependencytrack/util/XmlUtil.java @@ -30,7 +30,9 @@ import javax.xml.parsers.SAXParserFactory; import java.io.InputStream; -import static org.apache.xerces.jaxp.JAXPConstants.*; +import static org.apache.xerces.jaxp.JAXPConstants.JAXP_SCHEMA_LANGUAGE; +import static org.apache.xerces.jaxp.JAXPConstants.W3C_XML_SCHEMA; +import static org.apache.xerces.jaxp.JAXPConstants.JAXP_SCHEMA_SOURCE; public final class XmlUtil { diff --git a/src/test/java/org/dependencytrack/auth/PermissionsTest.java b/src/test/java/org/dependencytrack/auth/PermissionsTest.java index 997174970b..5d7408b6e1 100644 --- a/src/test/java/org/dependencytrack/auth/PermissionsTest.java +++ b/src/test/java/org/dependencytrack/auth/PermissionsTest.java @@ -21,8 +21,18 @@ import org.junit.Assert; import org.junit.Test; -import static org.dependencytrack.auth.Permissions.Constants.*; - +import static org.dependencytrack.auth.Permissions.Constants.PORTFOLIO_MANAGEMENT; +import static org.dependencytrack.auth.Permissions.Constants.BOM_UPLOAD; +import static org.dependencytrack.auth.Permissions.Constants.VIEW_PORTFOLIO; +import static org.dependencytrack.auth.Permissions.Constants.VIEW_VULNERABILITY; +import static org.dependencytrack.auth.Permissions.Constants.VULNERABILITY_ANALYSIS; +import static org.dependencytrack.auth.Permissions.Constants.VIEW_POLICY_VIOLATION; +import static org.dependencytrack.auth.Permissions.Constants.VULNERABILITY_MANAGEMENT; +import static org.dependencytrack.auth.Permissions.Constants.POLICY_VIOLATION_ANALYSIS; +import static org.dependencytrack.auth.Permissions.Constants.ACCESS_MANAGEMENT; +import static org.dependencytrack.auth.Permissions.Constants.SYSTEM_CONFIGURATION; +import static org.dependencytrack.auth.Permissions.Constants.PROJECT_CREATION_UPLOAD; +import static org.dependencytrack.auth.Permissions.Constants.POLICY_MANAGEMENT; public class PermissionsTest { @Test diff --git a/src/test/java/org/dependencytrack/persistence/ProjectQueryFilterBuilderTest.java b/src/test/java/org/dependencytrack/persistence/ProjectQueryFilterBuilderTest.java index b21a161229..0a8180b382 100644 --- a/src/test/java/org/dependencytrack/persistence/ProjectQueryFilterBuilderTest.java +++ b/src/test/java/org/dependencytrack/persistence/ProjectQueryFilterBuilderTest.java @@ -4,7 +4,9 @@ import java.util.Map; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; public class ProjectQueryFilterBuilderTest { diff --git a/src/test/java/org/dependencytrack/policy/CwePolicyEvaluatorTest.java b/src/test/java/org/dependencytrack/policy/CwePolicyEvaluatorTest.java index 1754bb4670..7c2db0c5f1 100644 --- a/src/test/java/org/dependencytrack/policy/CwePolicyEvaluatorTest.java +++ b/src/test/java/org/dependencytrack/policy/CwePolicyEvaluatorTest.java @@ -19,7 +19,11 @@ package org.dependencytrack.policy; import org.dependencytrack.PersistenceCapableTest; -import org.dependencytrack.model.*; +import org.dependencytrack.model.Project; +import org.dependencytrack.model.Policy; +import org.dependencytrack.model.Component; +import org.dependencytrack.model.PolicyCondition; +import org.dependencytrack.model.Vulnerability; import org.dependencytrack.tasks.scanners.AnalyzerIdentity; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/org/dependencytrack/policy/PolicyEngineTest.java b/src/test/java/org/dependencytrack/policy/PolicyEngineTest.java index 36a3e43c4f..b847103dba 100644 --- a/src/test/java/org/dependencytrack/policy/PolicyEngineTest.java +++ b/src/test/java/org/dependencytrack/policy/PolicyEngineTest.java @@ -19,7 +19,14 @@ package org.dependencytrack.policy; import org.dependencytrack.PersistenceCapableTest; -import org.dependencytrack.model.*; +import org.dependencytrack.model.Tag; +import org.dependencytrack.model.Policy; +import org.dependencytrack.model.Severity; +import org.dependencytrack.model.Project; +import org.dependencytrack.model.Component; +import org.dependencytrack.model.Vulnerability; +import org.dependencytrack.model.PolicyViolation; +import org.dependencytrack.model.PolicyCondition; import org.dependencytrack.tasks.scanners.AnalyzerIdentity; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManagerTest.java b/src/test/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManagerTest.java index ffba4925d2..8c38d900a3 100644 --- a/src/test/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManagerTest.java +++ b/src/test/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManagerTest.java @@ -3,10 +3,13 @@ import alpine.Config; import org.apache.commons.io.FileUtils; import org.dependencytrack.model.Component; -import org.dependencytrack.model.Vulnerability; import org.dependencytrack.model.VulnerableSoftware; import org.dependencytrack.persistence.QueryManager; -import org.junit.*; +import org.junit.Before; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; import us.springett.parsers.cpe.Cpe; import us.springett.parsers.cpe.CpeParser; import us.springett.parsers.cpe.exceptions.CpeEncodingException; @@ -20,9 +23,14 @@ import java.util.UUID; import java.util.regex.Pattern; -import static org.mockito.Mockito.*; - -import static org.junit.Assert.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class FuzzyVulnerableSoftwareSearchManagerTest { private static final File INDEX_DIRECTORY; diff --git a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java index ad5416dc73..93e6620de3 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java @@ -50,7 +50,11 @@ import java.util.concurrent.ConcurrentLinkedQueue; import static org.assertj.core.api.Assertions.assertThat; -import static org.dependencytrack.model.ConfigPropertyConstants.*; +import static org.dependencytrack.model.ConfigPropertyConstants.SCANNER_ANALYSIS_CACHE_VALIDITY_PERIOD; +import static org.dependencytrack.model.ConfigPropertyConstants.SCANNER_VULNDB_ENABLED; +import static org.dependencytrack.model.ConfigPropertyConstants.SCANNER_VULNDB_OAUTH1_CONSUMER_KEY; +import static org.dependencytrack.model.ConfigPropertyConstants.SCANNER_VULNDB_OAUTH1_CONSUMER_SECRET; + import static org.mockserver.model.HttpRequest.request; import static org.mockserver.model.HttpResponse.response; From 2a7f648e4af5e9cbfbd71a863887c5ed9e618ebc Mon Sep 17 00:00:00 2001 From: mehab Date: Fri, 3 Feb 2023 11:51:04 +0000 Subject: [PATCH 23/31] renamed package per standard Signed-off-by: mehab --- .../model/{vulnDb => vuln_vb}/ApiObject.java | 2 +- .../model/{vulnDb => vuln_vb}/Author.java | 2 +- .../{vulnDb => vuln_vb}/Classification.java | 2 +- .../model/{vulnDb => vuln_vb}/Cpe.java | 2 +- .../{vulnDb => vuln_vb}/CvssV2Metric.java | 2 +- .../{vulnDb => vuln_vb}/CvssV3Metric.java | 2 +- .../ExternalReference.java | 2 +- .../{vulnDb => vuln_vb}/ExternalText.java | 2 +- .../NvdAdditionalInfo.java | 2 +- .../model/{vulnDb => vuln_vb}/Product.java | 2 +- .../model/{vulnDb => vuln_vb}/Results.java | 2 +- .../model/{vulnDb => vuln_vb}/Status.java | 2 +- .../model/{vulnDb => vuln_vb}/Vendor.java | 2 +- .../model/{vulnDb => vuln_vb}/Version.java | 2 +- .../{vulnDb => vuln_vb}/VulnDbParser.java | 2 +- .../{vulnDb => vuln_vb}/Vulnerability.java | 2 +- .../parser/vulndb/ModelConverter.java | 10 +++---- .../dependencytrack/tasks/VulnDbSyncTask.java | 20 ++++++------- .../tasks/scanners/VulnDbAnalysisTask.java | 4 +-- .../org/dependencytrack/util/VulnDBUtil.java | 29 +++++++++---------- 20 files changed, 47 insertions(+), 48 deletions(-) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/ApiObject.java (63%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/Author.java (96%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/Classification.java (95%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/Cpe.java (89%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/CvssV2Metric.java (98%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/CvssV3Metric.java (99%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/ExternalReference.java (90%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/ExternalText.java (90%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/NvdAdditionalInfo.java (93%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/Product.java (94%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/Results.java (96%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/Status.java (97%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/Vendor.java (96%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/Version.java (95%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/VulnDbParser.java (99%) rename src/main/java/org/dependencytrack/model/{vulnDb => vuln_vb}/Vulnerability.java (99%) diff --git a/src/main/java/org/dependencytrack/model/vulnDb/ApiObject.java b/src/main/java/org/dependencytrack/model/vuln_vb/ApiObject.java similarity index 63% rename from src/main/java/org/dependencytrack/model/vulnDb/ApiObject.java rename to src/main/java/org/dependencytrack/model/vuln_vb/ApiObject.java index faf5835ab5..c106f52458 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/ApiObject.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/ApiObject.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; public interface ApiObject { int getId(); diff --git a/src/main/java/org/dependencytrack/model/vulnDb/Author.java b/src/main/java/org/dependencytrack/model/vuln_vb/Author.java similarity index 96% rename from src/main/java/org/dependencytrack/model/vulnDb/Author.java rename to src/main/java/org/dependencytrack/model/vuln_vb/Author.java index 704f61b263..aac62f31f5 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/Author.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/Author.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; public class Author { private int id; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/Classification.java b/src/main/java/org/dependencytrack/model/vuln_vb/Classification.java similarity index 95% rename from src/main/java/org/dependencytrack/model/vulnDb/Classification.java rename to src/main/java/org/dependencytrack/model/vuln_vb/Classification.java index 37d899835f..8de2e0963b 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/Classification.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/Classification.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; public class Classification { private int id; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/Cpe.java b/src/main/java/org/dependencytrack/model/vuln_vb/Cpe.java similarity index 89% rename from src/main/java/org/dependencytrack/model/vulnDb/Cpe.java rename to src/main/java/org/dependencytrack/model/vuln_vb/Cpe.java index be145afff1..c52d7998dc 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/Cpe.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/Cpe.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; public class Cpe { private String cpe; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/CvssV2Metric.java b/src/main/java/org/dependencytrack/model/vuln_vb/CvssV2Metric.java similarity index 98% rename from src/main/java/org/dependencytrack/model/vulnDb/CvssV2Metric.java rename to src/main/java/org/dependencytrack/model/vuln_vb/CvssV2Metric.java index aa5c6a9843..0fc63ca25b 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/CvssV2Metric.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/CvssV2Metric.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; import us.springett.cvss.CvssV2; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/CvssV3Metric.java b/src/main/java/org/dependencytrack/model/vuln_vb/CvssV3Metric.java similarity index 99% rename from src/main/java/org/dependencytrack/model/vulnDb/CvssV3Metric.java rename to src/main/java/org/dependencytrack/model/vuln_vb/CvssV3Metric.java index 3e1da2b00c..44ccf1a114 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/CvssV3Metric.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/CvssV3Metric.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; import us.springett.cvss.CvssV3; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/ExternalReference.java b/src/main/java/org/dependencytrack/model/vuln_vb/ExternalReference.java similarity index 90% rename from src/main/java/org/dependencytrack/model/vulnDb/ExternalReference.java rename to src/main/java/org/dependencytrack/model/vuln_vb/ExternalReference.java index 0cfa333419..119437c9d9 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/ExternalReference.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/ExternalReference.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; public class ExternalReference { private String type; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/ExternalText.java b/src/main/java/org/dependencytrack/model/vuln_vb/ExternalText.java similarity index 90% rename from src/main/java/org/dependencytrack/model/vulnDb/ExternalText.java rename to src/main/java/org/dependencytrack/model/vuln_vb/ExternalText.java index 3ab72ffd5f..9f2dc75ec6 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/ExternalText.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/ExternalText.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; public class ExternalText { private String type; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/NvdAdditionalInfo.java b/src/main/java/org/dependencytrack/model/vuln_vb/NvdAdditionalInfo.java similarity index 93% rename from src/main/java/org/dependencytrack/model/vulnDb/NvdAdditionalInfo.java rename to src/main/java/org/dependencytrack/model/vuln_vb/NvdAdditionalInfo.java index 4906588458..438fd75b3d 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/NvdAdditionalInfo.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/NvdAdditionalInfo.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; public class NvdAdditionalInfo { private String summary; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/Product.java b/src/main/java/org/dependencytrack/model/vuln_vb/Product.java similarity index 94% rename from src/main/java/org/dependencytrack/model/vulnDb/Product.java rename to src/main/java/org/dependencytrack/model/vuln_vb/Product.java index 514b731424..7382e14539 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/Product.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/Product.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; import java.util.ArrayList; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/Results.java b/src/main/java/org/dependencytrack/model/vuln_vb/Results.java similarity index 96% rename from src/main/java/org/dependencytrack/model/vulnDb/Results.java rename to src/main/java/org/dependencytrack/model/vuln_vb/Results.java index 3191558491..0ae8149ff4 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/Results.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/Results.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/Status.java b/src/main/java/org/dependencytrack/model/vuln_vb/Status.java similarity index 97% rename from src/main/java/org/dependencytrack/model/vulnDb/Status.java rename to src/main/java/org/dependencytrack/model/vuln_vb/Status.java index 4d94d6461e..d9ed3cdb49 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/Status.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/Status.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; public class Status { private String organizationName; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/Vendor.java b/src/main/java/org/dependencytrack/model/vuln_vb/Vendor.java similarity index 96% rename from src/main/java/org/dependencytrack/model/vulnDb/Vendor.java rename to src/main/java/org/dependencytrack/model/vuln_vb/Vendor.java index cab2f064da..96c43c6b51 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/Vendor.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/Vendor.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/Version.java b/src/main/java/org/dependencytrack/model/vuln_vb/Version.java similarity index 95% rename from src/main/java/org/dependencytrack/model/vulnDb/Version.java rename to src/main/java/org/dependencytrack/model/vuln_vb/Version.java index f680cb470f..425fa41ee5 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/Version.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/Version.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/VulnDbParser.java b/src/main/java/org/dependencytrack/model/vuln_vb/VulnDbParser.java similarity index 99% rename from src/main/java/org/dependencytrack/model/vulnDb/VulnDbParser.java rename to src/main/java/org/dependencytrack/model/vuln_vb/VulnDbParser.java index 02e830cdb4..d2df0b87ae 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/VulnDbParser.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/VulnDbParser.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; import java.io.File; import java.io.IOException; diff --git a/src/main/java/org/dependencytrack/model/vulnDb/Vulnerability.java b/src/main/java/org/dependencytrack/model/vuln_vb/Vulnerability.java similarity index 99% rename from src/main/java/org/dependencytrack/model/vulnDb/Vulnerability.java rename to src/main/java/org/dependencytrack/model/vuln_vb/Vulnerability.java index 3b27cf9d6f..05ded2f230 100644 --- a/src/main/java/org/dependencytrack/model/vulnDb/Vulnerability.java +++ b/src/main/java/org/dependencytrack/model/vuln_vb/Vulnerability.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vulnDb; +package org.dependencytrack.model.vuln_vb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java b/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java index a81a68d084..5e6f6d4604 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java @@ -21,16 +21,16 @@ import alpine.common.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.dependencytrack.model.Cwe; -import org.dependencytrack.model.vulnDb.Author; -import org.dependencytrack.model.vulnDb.ExternalReference; +import org.dependencytrack.model.vuln_vb.Author; +import org.dependencytrack.model.vuln_vb.ExternalReference; import org.dependencytrack.model.Vulnerability; import org.dependencytrack.parser.common.resolver.CweResolver; import org.dependencytrack.persistence.QueryManager; import us.springett.cvss.CvssV2; import us.springett.cvss.CvssV3; import us.springett.cvss.Score; -import org.dependencytrack.model.vulnDb.CvssV2Metric; -import org.dependencytrack.model.vulnDb.CvssV3Metric; +import org.dependencytrack.model.vuln_vb.CvssV2Metric; +import org.dependencytrack.model.vuln_vb.CvssV3Metric; import java.math.BigDecimal; import java.time.OffsetDateTime; @@ -56,7 +56,7 @@ private ModelConverter() { } * @param vulnDbVuln the VulnDB vulnerability to convert * @return a Dependency-Track Vulnerability object */ - public static Vulnerability convert(final QueryManager qm, final org.dependencytrack.model.vulnDb.Vulnerability vulnDbVuln) { + public static Vulnerability convert(final QueryManager qm, final org.dependencytrack.model.vuln_vb.Vulnerability vulnDbVuln) { final org.dependencytrack.model.Vulnerability vuln = new org.dependencytrack.model.Vulnerability(); vuln.setSource(org.dependencytrack.model.Vulnerability.Source.VULNDB); vuln.setVulnId(sanitize(String.valueOf(vulnDbVuln.getId()))); diff --git a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java index 56b38c6cb9..7ae8e1a895 100644 --- a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java +++ b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java @@ -37,11 +37,11 @@ import us.springett.parsers.cpe.CpeParser; import us.springett.parsers.cpe.exceptions.CpeEncodingException; import us.springett.parsers.cpe.exceptions.CpeParsingException; -import org.dependencytrack.model.vulnDb.VulnDbParser; -import org.dependencytrack.model.vulnDb.Product; -import org.dependencytrack.model.vulnDb.Results; -import org.dependencytrack.model.vulnDb.Vendor; -import org.dependencytrack.model.vulnDb.Version; +import org.dependencytrack.model.vuln_vb.VulnDbParser; +import org.dependencytrack.model.vuln_vb.Product; +import org.dependencytrack.model.vuln_vb.Results; +import org.dependencytrack.model.vuln_vb.Vendor; +import org.dependencytrack.model.vuln_vb.Version; import java.io.File; import java.io.IOException; @@ -84,7 +84,7 @@ public void inform(final Event e) { LOGGER.info("Parsing: " + file.getName()); final VulnDbParser parser = new VulnDbParser(); try { - final Results results = parser.parse(file, org.dependencytrack.model.vulnDb.Vulnerability.class); + final Results results = parser.parse(file, org.dependencytrack.model.vuln_vb.Vulnerability.class); updateDatasource(results); } catch (IOException ex) { LOGGER.error("An error occurred while parsing VulnDB payload: " + file.getName(), ex); @@ -121,8 +121,8 @@ private void updateDatasource(final Results results) { LOGGER.info("Updating datasource with VulnDB vulnerabilities"); try (QueryManager qm = new QueryManager()) { for (final Object o: results.getResults()) { - if (o instanceof org.dependencytrack.model.vulnDb.Vulnerability) { - final org.dependencytrack.model.vulnDb.Vulnerability vulnDbVuln = (org.dependencytrack.model.vulnDb.Vulnerability)o; + if (o instanceof org.dependencytrack.model.vuln_vb.Vulnerability) { + final org.dependencytrack.model.vuln_vb.Vulnerability vulnDbVuln = (org.dependencytrack.model.vuln_vb.Vulnerability)o; final org.dependencytrack.model.Vulnerability vulnerability = ModelConverter.convert(qm, vulnDbVuln); final Vulnerability synchronizeVulnerability = qm.synchronizeVulnerability(vulnerability, false); final List vsListOld = qm.detach(qm.getVulnerableSoftwareByVulnId(synchronizeVulnerability.getSource(), synchronizeVulnerability.getVulnId())); @@ -137,7 +137,7 @@ private void updateDatasource(final Results results) { } public static List parseCpes(final QueryManager qm, final Vulnerability vulnerability, - final org.dependencytrack.model.vulnDb.Vulnerability vulnDbVuln) { + final org.dependencytrack.model.vuln_vb.Vulnerability vulnDbVuln) { // cpe:2.3:a:belavier_commerce:abantecart:1.2.8:*:*:*:*:*:*:* final List vsList = new ArrayList<>(); if (vulnDbVuln.getVendors() != null) { @@ -149,7 +149,7 @@ public static List parseCpes(final QueryManager qm, final Vu if (version != null) { if (version.isAffected()) { if (version.getCpes() != null) { - for (org.dependencytrack.model.vulnDb.Cpe cpeObject : version.getCpes()) { + for (org.dependencytrack.model.vuln_vb.Cpe cpeObject : version.getCpes()) { try { final Cpe cpe = CpeParser.parse(cpeObject.getCpe(), true); final VulnerableSoftware vs = generateVulnerableSoftware(qm, cpe, vulnerability); diff --git a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java index b03e007349..7a6a25009c 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java @@ -31,7 +31,7 @@ import org.dependencytrack.model.ConfigPropertyConstants; import org.dependencytrack.model.Vulnerability; import org.dependencytrack.model.VulnerabilityAnalysisLevel; -import org.dependencytrack.model.vulnDb.Results; +import org.dependencytrack.model.vuln_vb.Results; import org.dependencytrack.parser.vulndb.ModelConverter; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.util.NotificationUtil; @@ -165,7 +165,7 @@ public void analyze(final List components) { private boolean processResults(final Results results, final Component component) { try (final QueryManager qm = new QueryManager()) { final Component vulnerableComponent = qm.getObjectByUuid(Component.class, component.getUuid()); // Refresh component and attach to current pm. - for (org.dependencytrack.model.vulnDb.Vulnerability vulnDbVuln : (List) results.getResults()) { + for (org.dependencytrack.model.vuln_vb.Vulnerability vulnDbVuln : (List) results.getResults()) { Vulnerability vulnerability = qm.getVulnerabilityByVulnId(Vulnerability.Source.VULNDB, String.valueOf(vulnDbVuln.getId())); if (vulnerability == null) { vulnerability = qm.createVulnerability(ModelConverter.convert(qm, vulnDbVuln), false); diff --git a/src/main/java/org/dependencytrack/util/VulnDBUtil.java b/src/main/java/org/dependencytrack/util/VulnDBUtil.java index ed780ccf27..90db84f115 100644 --- a/src/main/java/org/dependencytrack/util/VulnDBUtil.java +++ b/src/main/java/org/dependencytrack/util/VulnDBUtil.java @@ -17,20 +17,20 @@ import org.dependencytrack.common.HttpClientPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.dependencytrack.model.vulnDb.Cpe; -import org.dependencytrack.model.vulnDb.Product; -import org.dependencytrack.model.vulnDb.Results; -import org.dependencytrack.model.vulnDb.Vendor; -import org.dependencytrack.model.vulnDb.Version; -import org.dependencytrack.model.vulnDb.ApiObject; -import org.dependencytrack.model.vulnDb.Vulnerability; -import org.dependencytrack.model.vulnDb.Classification; -import org.dependencytrack.model.vulnDb.Author; -import org.dependencytrack.model.vulnDb.CvssV2Metric; -import org.dependencytrack.model.vulnDb.CvssV3Metric; -import org.dependencytrack.model.vulnDb.NvdAdditionalInfo; -import org.dependencytrack.model.vulnDb.ExternalText; -import org.dependencytrack.model.vulnDb.ExternalReference; +import org.dependencytrack.model.vuln_vb.Cpe; +import org.dependencytrack.model.vuln_vb.Product; +import org.dependencytrack.model.vuln_vb.Results; +import org.dependencytrack.model.vuln_vb.Vendor; +import org.dependencytrack.model.vuln_vb.Version; +import org.dependencytrack.model.vuln_vb.ApiObject; +import org.dependencytrack.model.vuln_vb.Vulnerability; +import org.dependencytrack.model.vuln_vb.Classification; +import org.dependencytrack.model.vuln_vb.Author; +import org.dependencytrack.model.vuln_vb.CvssV2Metric; +import org.dependencytrack.model.vuln_vb.CvssV3Metric; +import org.dependencytrack.model.vuln_vb.NvdAdditionalInfo; +import org.dependencytrack.model.vuln_vb.ExternalText; +import org.dependencytrack.model.vuln_vb.ExternalReference; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -39,7 +39,6 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; public class VulnDBUtil { From 119b8f533a85e5498c9d54c58d3cf463cb157df5 Mon Sep 17 00:00:00 2001 From: mehab Date: Fri, 3 Feb 2023 14:06:29 +0000 Subject: [PATCH 24/31] changed package name to follow convention Signed-off-by: mehab --- .../model/{vuln_vb => vulndb}/ApiObject.java | 2 +- .../model/{vuln_vb => vulndb}/Author.java | 2 +- .../{vuln_vb => vulndb}/Classification.java | 2 +- .../model/{vuln_vb => vulndb}/Cpe.java | 2 +- .../{vuln_vb => vulndb}/CvssV2Metric.java | 2 +- .../{vuln_vb => vulndb}/CvssV3Metric.java | 2 +- .../ExternalReference.java | 2 +- .../{vuln_vb => vulndb}/ExternalText.java | 2 +- .../NvdAdditionalInfo.java | 2 +- .../model/{vuln_vb => vulndb}/Product.java | 2 +- .../model/{vuln_vb => vulndb}/Results.java | 2 +- .../model/{vuln_vb => vulndb}/Status.java | 2 +- .../model/{vuln_vb => vulndb}/Vendor.java | 2 +- .../model/{vuln_vb => vulndb}/Version.java | 2 +- .../{vuln_vb => vulndb}/VulnDbParser.java | 2 +- .../{vuln_vb => vulndb}/Vulnerability.java | 2 +- .../parser/vulndb/ModelConverter.java | 10 +++---- .../dependencytrack/tasks/VulnDbSyncTask.java | 20 ++++++------- .../tasks/scanners/VulnDbAnalysisTask.java | 4 +-- .../org/dependencytrack/util/VulnDBUtil.java | 28 +++++++++---------- 20 files changed, 47 insertions(+), 47 deletions(-) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/ApiObject.java (63%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/Author.java (96%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/Classification.java (95%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/Cpe.java (89%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/CvssV2Metric.java (98%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/CvssV3Metric.java (99%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/ExternalReference.java (90%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/ExternalText.java (90%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/NvdAdditionalInfo.java (93%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/Product.java (94%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/Results.java (96%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/Status.java (97%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/Vendor.java (96%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/Version.java (95%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/VulnDbParser.java (99%) rename src/main/java/org/dependencytrack/model/{vuln_vb => vulndb}/Vulnerability.java (99%) diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/ApiObject.java b/src/main/java/org/dependencytrack/model/vulndb/ApiObject.java similarity index 63% rename from src/main/java/org/dependencytrack/model/vuln_vb/ApiObject.java rename to src/main/java/org/dependencytrack/model/vulndb/ApiObject.java index c106f52458..dbc826f255 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/ApiObject.java +++ b/src/main/java/org/dependencytrack/model/vulndb/ApiObject.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; public interface ApiObject { int getId(); diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/Author.java b/src/main/java/org/dependencytrack/model/vulndb/Author.java similarity index 96% rename from src/main/java/org/dependencytrack/model/vuln_vb/Author.java rename to src/main/java/org/dependencytrack/model/vulndb/Author.java index aac62f31f5..ed3dc8d316 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/Author.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Author.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; public class Author { private int id; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/Classification.java b/src/main/java/org/dependencytrack/model/vulndb/Classification.java similarity index 95% rename from src/main/java/org/dependencytrack/model/vuln_vb/Classification.java rename to src/main/java/org/dependencytrack/model/vulndb/Classification.java index 8de2e0963b..dbcf77d56a 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/Classification.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Classification.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; public class Classification { private int id; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/Cpe.java b/src/main/java/org/dependencytrack/model/vulndb/Cpe.java similarity index 89% rename from src/main/java/org/dependencytrack/model/vuln_vb/Cpe.java rename to src/main/java/org/dependencytrack/model/vulndb/Cpe.java index c52d7998dc..f2972697a7 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/Cpe.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Cpe.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; public class Cpe { private String cpe; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/CvssV2Metric.java b/src/main/java/org/dependencytrack/model/vulndb/CvssV2Metric.java similarity index 98% rename from src/main/java/org/dependencytrack/model/vuln_vb/CvssV2Metric.java rename to src/main/java/org/dependencytrack/model/vulndb/CvssV2Metric.java index 0fc63ca25b..d66c53aa7a 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/CvssV2Metric.java +++ b/src/main/java/org/dependencytrack/model/vulndb/CvssV2Metric.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; import us.springett.cvss.CvssV2; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/CvssV3Metric.java b/src/main/java/org/dependencytrack/model/vulndb/CvssV3Metric.java similarity index 99% rename from src/main/java/org/dependencytrack/model/vuln_vb/CvssV3Metric.java rename to src/main/java/org/dependencytrack/model/vulndb/CvssV3Metric.java index 44ccf1a114..0bbc052955 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/CvssV3Metric.java +++ b/src/main/java/org/dependencytrack/model/vulndb/CvssV3Metric.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; import us.springett.cvss.CvssV3; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/ExternalReference.java b/src/main/java/org/dependencytrack/model/vulndb/ExternalReference.java similarity index 90% rename from src/main/java/org/dependencytrack/model/vuln_vb/ExternalReference.java rename to src/main/java/org/dependencytrack/model/vulndb/ExternalReference.java index 119437c9d9..bd722ad00f 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/ExternalReference.java +++ b/src/main/java/org/dependencytrack/model/vulndb/ExternalReference.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; public class ExternalReference { private String type; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/ExternalText.java b/src/main/java/org/dependencytrack/model/vulndb/ExternalText.java similarity index 90% rename from src/main/java/org/dependencytrack/model/vuln_vb/ExternalText.java rename to src/main/java/org/dependencytrack/model/vulndb/ExternalText.java index 9f2dc75ec6..fcf6e57606 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/ExternalText.java +++ b/src/main/java/org/dependencytrack/model/vulndb/ExternalText.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; public class ExternalText { private String type; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/NvdAdditionalInfo.java b/src/main/java/org/dependencytrack/model/vulndb/NvdAdditionalInfo.java similarity index 93% rename from src/main/java/org/dependencytrack/model/vuln_vb/NvdAdditionalInfo.java rename to src/main/java/org/dependencytrack/model/vulndb/NvdAdditionalInfo.java index 438fd75b3d..5772d10f5b 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/NvdAdditionalInfo.java +++ b/src/main/java/org/dependencytrack/model/vulndb/NvdAdditionalInfo.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; public class NvdAdditionalInfo { private String summary; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/Product.java b/src/main/java/org/dependencytrack/model/vulndb/Product.java similarity index 94% rename from src/main/java/org/dependencytrack/model/vuln_vb/Product.java rename to src/main/java/org/dependencytrack/model/vulndb/Product.java index 7382e14539..9a999379f9 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/Product.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Product.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; import java.util.ArrayList; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/Results.java b/src/main/java/org/dependencytrack/model/vulndb/Results.java similarity index 96% rename from src/main/java/org/dependencytrack/model/vuln_vb/Results.java rename to src/main/java/org/dependencytrack/model/vulndb/Results.java index 0ae8149ff4..72a507a1d0 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/Results.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Results.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/Status.java b/src/main/java/org/dependencytrack/model/vulndb/Status.java similarity index 97% rename from src/main/java/org/dependencytrack/model/vuln_vb/Status.java rename to src/main/java/org/dependencytrack/model/vulndb/Status.java index d9ed3cdb49..b1559cd087 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/Status.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Status.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; public class Status { private String organizationName; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/Vendor.java b/src/main/java/org/dependencytrack/model/vulndb/Vendor.java similarity index 96% rename from src/main/java/org/dependencytrack/model/vuln_vb/Vendor.java rename to src/main/java/org/dependencytrack/model/vulndb/Vendor.java index 96c43c6b51..ebfeace3ee 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/Vendor.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Vendor.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/Version.java b/src/main/java/org/dependencytrack/model/vulndb/Version.java similarity index 95% rename from src/main/java/org/dependencytrack/model/vuln_vb/Version.java rename to src/main/java/org/dependencytrack/model/vulndb/Version.java index 425fa41ee5..002bae0ec9 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/Version.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Version.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/VulnDbParser.java b/src/main/java/org/dependencytrack/model/vulndb/VulnDbParser.java similarity index 99% rename from src/main/java/org/dependencytrack/model/vuln_vb/VulnDbParser.java rename to src/main/java/org/dependencytrack/model/vulndb/VulnDbParser.java index d2df0b87ae..4ddb6d378e 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/VulnDbParser.java +++ b/src/main/java/org/dependencytrack/model/vulndb/VulnDbParser.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; import java.io.File; import java.io.IOException; diff --git a/src/main/java/org/dependencytrack/model/vuln_vb/Vulnerability.java b/src/main/java/org/dependencytrack/model/vulndb/Vulnerability.java similarity index 99% rename from src/main/java/org/dependencytrack/model/vuln_vb/Vulnerability.java rename to src/main/java/org/dependencytrack/model/vulndb/Vulnerability.java index 05ded2f230..f1a32dbe90 100644 --- a/src/main/java/org/dependencytrack/model/vuln_vb/Vulnerability.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Vulnerability.java @@ -1,4 +1,4 @@ -package org.dependencytrack.model.vuln_vb; +package org.dependencytrack.model.vulndb; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java b/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java index 5e6f6d4604..6867ba5874 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/ModelConverter.java @@ -21,16 +21,16 @@ import alpine.common.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.dependencytrack.model.Cwe; -import org.dependencytrack.model.vuln_vb.Author; -import org.dependencytrack.model.vuln_vb.ExternalReference; +import org.dependencytrack.model.vulndb.Author; +import org.dependencytrack.model.vulndb.ExternalReference; import org.dependencytrack.model.Vulnerability; import org.dependencytrack.parser.common.resolver.CweResolver; import org.dependencytrack.persistence.QueryManager; import us.springett.cvss.CvssV2; import us.springett.cvss.CvssV3; import us.springett.cvss.Score; -import org.dependencytrack.model.vuln_vb.CvssV2Metric; -import org.dependencytrack.model.vuln_vb.CvssV3Metric; +import org.dependencytrack.model.vulndb.CvssV2Metric; +import org.dependencytrack.model.vulndb.CvssV3Metric; import java.math.BigDecimal; import java.time.OffsetDateTime; @@ -56,7 +56,7 @@ private ModelConverter() { } * @param vulnDbVuln the VulnDB vulnerability to convert * @return a Dependency-Track Vulnerability object */ - public static Vulnerability convert(final QueryManager qm, final org.dependencytrack.model.vuln_vb.Vulnerability vulnDbVuln) { + public static Vulnerability convert(final QueryManager qm, final org.dependencytrack.model.vulndb.Vulnerability vulnDbVuln) { final org.dependencytrack.model.Vulnerability vuln = new org.dependencytrack.model.Vulnerability(); vuln.setSource(org.dependencytrack.model.Vulnerability.Source.VULNDB); vuln.setVulnId(sanitize(String.valueOf(vulnDbVuln.getId()))); diff --git a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java index 7ae8e1a895..8e3cf6e066 100644 --- a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java +++ b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java @@ -37,11 +37,11 @@ import us.springett.parsers.cpe.CpeParser; import us.springett.parsers.cpe.exceptions.CpeEncodingException; import us.springett.parsers.cpe.exceptions.CpeParsingException; -import org.dependencytrack.model.vuln_vb.VulnDbParser; -import org.dependencytrack.model.vuln_vb.Product; -import org.dependencytrack.model.vuln_vb.Results; -import org.dependencytrack.model.vuln_vb.Vendor; -import org.dependencytrack.model.vuln_vb.Version; +import org.dependencytrack.model.vulndb.VulnDbParser; +import org.dependencytrack.model.vulndb.Product; +import org.dependencytrack.model.vulndb.Results; +import org.dependencytrack.model.vulndb.Vendor; +import org.dependencytrack.model.vulndb.Version; import java.io.File; import java.io.IOException; @@ -84,7 +84,7 @@ public void inform(final Event e) { LOGGER.info("Parsing: " + file.getName()); final VulnDbParser parser = new VulnDbParser(); try { - final Results results = parser.parse(file, org.dependencytrack.model.vuln_vb.Vulnerability.class); + final Results results = parser.parse(file, org.dependencytrack.model.vulndb.Vulnerability.class); updateDatasource(results); } catch (IOException ex) { LOGGER.error("An error occurred while parsing VulnDB payload: " + file.getName(), ex); @@ -121,8 +121,8 @@ private void updateDatasource(final Results results) { LOGGER.info("Updating datasource with VulnDB vulnerabilities"); try (QueryManager qm = new QueryManager()) { for (final Object o: results.getResults()) { - if (o instanceof org.dependencytrack.model.vuln_vb.Vulnerability) { - final org.dependencytrack.model.vuln_vb.Vulnerability vulnDbVuln = (org.dependencytrack.model.vuln_vb.Vulnerability)o; + if (o instanceof org.dependencytrack.model.vulndb.Vulnerability) { + final org.dependencytrack.model.vulndb.Vulnerability vulnDbVuln = (org.dependencytrack.model.vulndb.Vulnerability)o; final org.dependencytrack.model.Vulnerability vulnerability = ModelConverter.convert(qm, vulnDbVuln); final Vulnerability synchronizeVulnerability = qm.synchronizeVulnerability(vulnerability, false); final List vsListOld = qm.detach(qm.getVulnerableSoftwareByVulnId(synchronizeVulnerability.getSource(), synchronizeVulnerability.getVulnId())); @@ -137,7 +137,7 @@ private void updateDatasource(final Results results) { } public static List parseCpes(final QueryManager qm, final Vulnerability vulnerability, - final org.dependencytrack.model.vuln_vb.Vulnerability vulnDbVuln) { + final org.dependencytrack.model.vulndb.Vulnerability vulnDbVuln) { // cpe:2.3:a:belavier_commerce:abantecart:1.2.8:*:*:*:*:*:*:* final List vsList = new ArrayList<>(); if (vulnDbVuln.getVendors() != null) { @@ -149,7 +149,7 @@ public static List parseCpes(final QueryManager qm, final Vu if (version != null) { if (version.isAffected()) { if (version.getCpes() != null) { - for (org.dependencytrack.model.vuln_vb.Cpe cpeObject : version.getCpes()) { + for (org.dependencytrack.model.vulndb.Cpe cpeObject : version.getCpes()) { try { final Cpe cpe = CpeParser.parse(cpeObject.getCpe(), true); final VulnerableSoftware vs = generateVulnerableSoftware(qm, cpe, vulnerability); diff --git a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java index 7a6a25009c..a9e2ea34cf 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java @@ -31,7 +31,7 @@ import org.dependencytrack.model.ConfigPropertyConstants; import org.dependencytrack.model.Vulnerability; import org.dependencytrack.model.VulnerabilityAnalysisLevel; -import org.dependencytrack.model.vuln_vb.Results; +import org.dependencytrack.model.vulndb.Results; import org.dependencytrack.parser.vulndb.ModelConverter; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.util.NotificationUtil; @@ -165,7 +165,7 @@ public void analyze(final List components) { private boolean processResults(final Results results, final Component component) { try (final QueryManager qm = new QueryManager()) { final Component vulnerableComponent = qm.getObjectByUuid(Component.class, component.getUuid()); // Refresh component and attach to current pm. - for (org.dependencytrack.model.vuln_vb.Vulnerability vulnDbVuln : (List) results.getResults()) { + for (org.dependencytrack.model.vulndb.Vulnerability vulnDbVuln : (List) results.getResults()) { Vulnerability vulnerability = qm.getVulnerabilityByVulnId(Vulnerability.Source.VULNDB, String.valueOf(vulnDbVuln.getId())); if (vulnerability == null) { vulnerability = qm.createVulnerability(ModelConverter.convert(qm, vulnDbVuln), false); diff --git a/src/main/java/org/dependencytrack/util/VulnDBUtil.java b/src/main/java/org/dependencytrack/util/VulnDBUtil.java index 90db84f115..6b70feeb05 100644 --- a/src/main/java/org/dependencytrack/util/VulnDBUtil.java +++ b/src/main/java/org/dependencytrack/util/VulnDBUtil.java @@ -17,20 +17,20 @@ import org.dependencytrack.common.HttpClientPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.dependencytrack.model.vuln_vb.Cpe; -import org.dependencytrack.model.vuln_vb.Product; -import org.dependencytrack.model.vuln_vb.Results; -import org.dependencytrack.model.vuln_vb.Vendor; -import org.dependencytrack.model.vuln_vb.Version; -import org.dependencytrack.model.vuln_vb.ApiObject; -import org.dependencytrack.model.vuln_vb.Vulnerability; -import org.dependencytrack.model.vuln_vb.Classification; -import org.dependencytrack.model.vuln_vb.Author; -import org.dependencytrack.model.vuln_vb.CvssV2Metric; -import org.dependencytrack.model.vuln_vb.CvssV3Metric; -import org.dependencytrack.model.vuln_vb.NvdAdditionalInfo; -import org.dependencytrack.model.vuln_vb.ExternalText; -import org.dependencytrack.model.vuln_vb.ExternalReference; +import org.dependencytrack.model.vulndb.Cpe; +import org.dependencytrack.model.vulndb.Product; +import org.dependencytrack.model.vulndb.Results; +import org.dependencytrack.model.vulndb.Vendor; +import org.dependencytrack.model.vulndb.Version; +import org.dependencytrack.model.vulndb.ApiObject; +import org.dependencytrack.model.vulndb.Vulnerability; +import org.dependencytrack.model.vulndb.Classification; +import org.dependencytrack.model.vulndb.Author; +import org.dependencytrack.model.vulndb.CvssV2Metric; +import org.dependencytrack.model.vulndb.CvssV3Metric; +import org.dependencytrack.model.vulndb.NvdAdditionalInfo; +import org.dependencytrack.model.vulndb.ExternalText; +import org.dependencytrack.model.vulndb.ExternalReference; import java.io.IOException; import java.io.UnsupportedEncodingException; From 8a049f1597ae2f9378beeef084d6b579c42025ae Mon Sep 17 00:00:00 2001 From: mehab Date: Mon, 6 Feb 2023 11:27:05 +0000 Subject: [PATCH 25/31] changes from merge master and pr review Signed-off-by: mehab --- .checkstyle-header | 18 +++ .checkstyle.xml | 17 +++ .github/workflows/_meta-build.yaml | 4 +- pom.xml | 25 ++++ src/main/docker/Dockerfile | 2 +- .../org/dependencytrack/common/ConfigKey.java | 18 +++ .../org/dependencytrack/event/IndexEvent.java | 1 - .../dependencytrack/event/OsvMirrorEvent.java | 18 +++ .../event/SnykAnalysisEvent.java | 18 +++ .../integrations/FindingPackagingFormat.java | 1 - .../defectdojo/DefectDojoUploader.java | 1 + .../fortifyssc/FortifySscUploader.java | 2 +- .../kenna/KennaSecurityUploader.java | 1 + .../model/PolicyCondition.java | 2 +- .../dependencytrack/model/SnykCvssSource.java | 18 +++ .../model/VulnerabilityAnalysisLevel.java | 18 +++ .../model/VulnerableSoftware.java | 9 -- .../model/vulndb/ApiObject.java | 18 +++ .../dependencytrack/model/vulndb/Author.java | 22 ++++ .../model/vulndb/Classification.java | 22 ++++ .../org/dependencytrack/model/vulndb/Cpe.java | 22 ++++ .../model/vulndb/CvssV2Metric.java | 22 ++++ .../model/vulndb/CvssV3Metric.java | 22 ++++ .../model/vulndb/ExternalReference.java | 22 ++++ .../model/vulndb/ExternalText.java | 22 ++++ .../model/vulndb/NvdAdditionalInfo.java | 22 ++++ .../dependencytrack/model/vulndb/Product.java | 22 ++++ .../dependencytrack/model/vulndb/Results.java | 22 ++++ .../dependencytrack/model/vulndb/Status.java | 22 ++++ .../dependencytrack/model/vulndb/Vendor.java | 22 ++++ .../dependencytrack/model/vulndb/Version.java | 22 ++++ .../model/vulndb/VulnDbParser.java | 22 ++++ .../model/vulndb/Vulnerability.java | 22 ++++ .../cyclonedx/CycloneDXVexImporter.java | 2 +- .../parser/osv/OsvAdvisoryParser.java | 18 +++ .../parser/osv/model/OsvAdvisory.java | 18 +++ .../parser/osv/model/OsvAffectedPackage.java | 18 +++ .../parser/snyk/SnykParser.java | 18 +++ .../persistence/DefaultObjectGenerator.java | 7 - .../persistence/NotificationQueryManager.java | 1 - .../ProjectQueryFilterBuilder.java | 18 +++ .../persistence/ProjectQueryManager.java | 2 - .../persistence/TagQueryManager.java | 18 +++ .../policy/ComponentAgePolicyEvaluator.java | 122 +++++++++++++++++ .../policy/ComponentHashPolicyEvaluator.java | 2 + .../policy/CwePolicyEvaluator.java | 2 +- .../dependencytrack/policy/PolicyEngine.java | 2 + .../policy/VersionPolicyEvaluator.java | 18 +++ .../resources/v1/AccessControlResource.java | 2 - .../resources/v1/ConfigPropertyResource.java | 1 - .../resources/v1/FindingResource.java | 1 - .../v1/NotificationPublisherResource.java | 14 +- .../resources/v1/OidcResource.java | 18 +++ .../resources/v1/SearchResource.java | 1 - .../resources/v1/TagResource.java | 18 +++ .../resources/v1/VexResource.java | 1 - .../resources/v1/vo/BomUploadResponse.java | 18 +++ .../v1/vo/IsTokenBeingProcessedResponse.java | 18 +++ .../v1/vo/MappedOidcGroupRequest.java | 18 +++ .../resources/v1/vo/TeamSelfResponse.java | 7 +- .../FuzzyVulnerableSoftwareSearchManager.java | 30 ++++- .../tasks/OsvDownloadTask.java | 19 ++- .../tasks/repositories/CargoMetaAnalyzer.java | 1 - .../repositories/ComposerMetaAnalyzer.java | 1 - .../upgrade/v440/v440Updater.java | 18 +++ .../util/CacheStampedeBlocker.java | 18 +++ .../org/dependencytrack/util/VulnDBUtil.java | 28 +++- .../org/dependencytrack/util/XmlUtil.java | 4 +- .../ComponentAgePolicyEvaluatorTest.java | 124 ++++++++++++++++++ 69 files changed, 1095 insertions(+), 52 deletions(-) create mode 100644 .checkstyle-header create mode 100644 .checkstyle.xml create mode 100644 src/main/java/org/dependencytrack/policy/ComponentAgePolicyEvaluator.java create mode 100644 src/test/java/org/dependencytrack/policy/ComponentAgePolicyEvaluatorTest.java diff --git a/.checkstyle-header b/.checkstyle-header new file mode 100644 index 0000000000..c773577a1f --- /dev/null +++ b/.checkstyle-header @@ -0,0 +1,18 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ \ No newline at end of file diff --git a/.checkstyle.xml b/.checkstyle.xml new file mode 100644 index 0000000000..3682cfab3d --- /dev/null +++ b/.checkstyle.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.github/workflows/_meta-build.yaml b/.github/workflows/_meta-build.yaml index 92070f16ab..d0768ac43e 100644 --- a/.github/workflows/_meta-build.yaml +++ b/.github/workflows/_meta-build.yaml @@ -82,7 +82,7 @@ jobs: uses: docker/setup-qemu-action@v2.1.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.3.0 + uses: docker/setup-buildx-action@v2.4.0 id: buildx with: install: true @@ -119,7 +119,7 @@ jobs: - name: Run Trivy Vulnerability Scanner if: ${{ inputs.publish-container }} - uses: aquasecurity/trivy-action@0.8.0 + uses: aquasecurity/trivy-action@0.9.0 with: image-ref: docker.io/dependencytrack/${{ matrix.distribution }}:${{ inputs.app-version }} format: 'sarif' diff --git a/pom.xml b/pom.xml index 5cd038c087..89836f683e 100644 --- a/pom.xml +++ b/pom.xml @@ -390,6 +390,31 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.2.1 + + ${project.basedir}/.checkstyle.xml + false + false + + + + validate + + check + + + + + + com.puppycrawl.tools + checkstyle + 10.6.0 + + + org.codehaus.mojo exec-maven-plugin diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile index 32fbebc7ac..3ceb75a0cf 100644 --- a/src/main/docker/Dockerfile +++ b/src/main/docker/Dockerfile @@ -1,6 +1,6 @@ FROM eclipse-temurin:17.0.5_8-jre-focal@sha256:d98a588cd72194d040c83dad4eabed97c17677d592db7b964d31f12f9686dcbc AS jre-build -FROM debian:bullseye-20230109-slim@sha256:98d3b4b0cee264301eb1354e0b549323af2d0633e1c43375d0b25c01826b6790 +FROM debian:bullseye-20230202-slim@sha256:d51d5c391d202d5e2e0294a9df6ff077ed40583b11831d347d418690da496c50 # Arguments that can be passed at build time # Directory names must end with / to avoid errors when ADDing and COPYing diff --git a/src/main/java/org/dependencytrack/common/ConfigKey.java b/src/main/java/org/dependencytrack/common/ConfigKey.java index 4e02e8932e..4560334ee4 100644 --- a/src/main/java/org/dependencytrack/common/ConfigKey.java +++ b/src/main/java/org/dependencytrack/common/ConfigKey.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.common; import alpine.Config; diff --git a/src/main/java/org/dependencytrack/event/IndexEvent.java b/src/main/java/org/dependencytrack/event/IndexEvent.java index acc76b19c7..7676246f26 100644 --- a/src/main/java/org/dependencytrack/event/IndexEvent.java +++ b/src/main/java/org/dependencytrack/event/IndexEvent.java @@ -18,7 +18,6 @@ */ package org.dependencytrack.event; -import alpine.event.framework.AbstractChainableEvent; import alpine.event.framework.SingletonCapableEvent; import org.dependencytrack.model.Component; import org.dependencytrack.model.Cpe; diff --git a/src/main/java/org/dependencytrack/event/OsvMirrorEvent.java b/src/main/java/org/dependencytrack/event/OsvMirrorEvent.java index 67a80c7fd0..659d122de3 100644 --- a/src/main/java/org/dependencytrack/event/OsvMirrorEvent.java +++ b/src/main/java/org/dependencytrack/event/OsvMirrorEvent.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.event; import alpine.event.framework.Event; diff --git a/src/main/java/org/dependencytrack/event/SnykAnalysisEvent.java b/src/main/java/org/dependencytrack/event/SnykAnalysisEvent.java index 4245158501..679578d863 100644 --- a/src/main/java/org/dependencytrack/event/SnykAnalysisEvent.java +++ b/src/main/java/org/dependencytrack/event/SnykAnalysisEvent.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.event; import org.dependencytrack.model.Component; diff --git a/src/main/java/org/dependencytrack/integrations/FindingPackagingFormat.java b/src/main/java/org/dependencytrack/integrations/FindingPackagingFormat.java index af23f7c7bf..0884d1ac88 100644 --- a/src/main/java/org/dependencytrack/integrations/FindingPackagingFormat.java +++ b/src/main/java/org/dependencytrack/integrations/FindingPackagingFormat.java @@ -25,7 +25,6 @@ import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.util.DateUtil; import org.json.JSONObject; -import us.springett.parsers.cpe.Cpe; import java.util.Date; import java.util.List; diff --git a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoUploader.java b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoUploader.java index 213dcf92c6..ebe718a3f3 100644 --- a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoUploader.java +++ b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoUploader.java @@ -27,6 +27,7 @@ import org.dependencytrack.model.Project; import org.dependencytrack.model.ProjectProperty; import org.json.JSONObject; + import java.io.ByteArrayInputStream; import java.io.InputStream; import java.net.URL; diff --git a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscUploader.java b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscUploader.java index 06cd136762..ea5f8c33bc 100644 --- a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscUploader.java +++ b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscUploader.java @@ -35,10 +35,10 @@ import java.util.List; import static org.dependencytrack.model.ConfigPropertyConstants.FORTIFY_SSC_ENABLED; + import static org.dependencytrack.model.ConfigPropertyConstants.FORTIFY_SSC_URL; import static org.dependencytrack.model.ConfigPropertyConstants.FORTIFY_SSC_TOKEN; - public class FortifySscUploader extends AbstractIntegrationPoint implements ProjectFindingUploader { private static final Logger LOGGER = Logger.getLogger(FortifySscUploader.class); diff --git a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java index 68c780fbbc..54129196cd 100644 --- a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java +++ b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java @@ -47,6 +47,7 @@ import static org.dependencytrack.model.ConfigPropertyConstants.KENNA_ENABLED; import static org.dependencytrack.model.ConfigPropertyConstants.KENNA_CONNECTOR_ID; + import static org.dependencytrack.model.ConfigPropertyConstants.KENNA_TOKEN; public class KennaSecurityUploader extends AbstractIntegrationPoint implements PortfolioFindingUploader { diff --git a/src/main/java/org/dependencytrack/model/PolicyCondition.java b/src/main/java/org/dependencytrack/model/PolicyCondition.java index b9a6703022..644e2b23e9 100644 --- a/src/main/java/org/dependencytrack/model/PolicyCondition.java +++ b/src/main/java/org/dependencytrack/model/PolicyCondition.java @@ -63,7 +63,7 @@ public enum Operator { } public enum Subject { - //AGE, + AGE, //ANALYZER, //BOM, COORDINATES, diff --git a/src/main/java/org/dependencytrack/model/SnykCvssSource.java b/src/main/java/org/dependencytrack/model/SnykCvssSource.java index 6d52d98d7c..caaa7a4fc6 100644 --- a/src/main/java/org/dependencytrack/model/SnykCvssSource.java +++ b/src/main/java/org/dependencytrack/model/SnykCvssSource.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model; public enum SnykCvssSource { diff --git a/src/main/java/org/dependencytrack/model/VulnerabilityAnalysisLevel.java b/src/main/java/org/dependencytrack/model/VulnerabilityAnalysisLevel.java index 8ee967a0cd..eab6bd6816 100644 --- a/src/main/java/org/dependencytrack/model/VulnerabilityAnalysisLevel.java +++ b/src/main/java/org/dependencytrack/model/VulnerabilityAnalysisLevel.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model; public enum VulnerabilityAnalysisLevel { diff --git a/src/main/java/org/dependencytrack/model/VulnerableSoftware.java b/src/main/java/org/dependencytrack/model/VulnerableSoftware.java index b71e51e660..129b651061 100644 --- a/src/main/java/org/dependencytrack/model/VulnerableSoftware.java +++ b/src/main/java/org/dependencytrack/model/VulnerableSoftware.java @@ -18,14 +18,9 @@ */ package org.dependencytrack.model; -import alpine.common.validation.RegexSequence; -import alpine.server.json.TrimmedStringDeserializer; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import org.dependencytrack.resources.v1.serializers.Iso8601DateSerializer; import javax.jdo.annotations.Column; import javax.jdo.annotations.Element; @@ -38,12 +33,8 @@ import javax.jdo.annotations.Persistent; import javax.jdo.annotations.PrimaryKey; import javax.jdo.annotations.Unique; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; import java.io.Serializable; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.UUID; diff --git a/src/main/java/org/dependencytrack/model/vulndb/ApiObject.java b/src/main/java/org/dependencytrack/model/vulndb/ApiObject.java index dbc826f255..9db1c8c3a7 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/ApiObject.java +++ b/src/main/java/org/dependencytrack/model/vulndb/ApiObject.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; public interface ApiObject { diff --git a/src/main/java/org/dependencytrack/model/vulndb/Author.java b/src/main/java/org/dependencytrack/model/vulndb/Author.java index ed3dc8d316..2b2361009a 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/Author.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Author.java @@ -1,5 +1,27 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class Author { private int id; private String name; diff --git a/src/main/java/org/dependencytrack/model/vulndb/Classification.java b/src/main/java/org/dependencytrack/model/vulndb/Classification.java index dbcf77d56a..6ae93e685b 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/Classification.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Classification.java @@ -1,5 +1,27 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class Classification { private int id; private String name; diff --git a/src/main/java/org/dependencytrack/model/vulndb/Cpe.java b/src/main/java/org/dependencytrack/model/vulndb/Cpe.java index f2972697a7..84a827321d 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/Cpe.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Cpe.java @@ -1,5 +1,27 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class Cpe { private String cpe; private String type; diff --git a/src/main/java/org/dependencytrack/model/vulndb/CvssV2Metric.java b/src/main/java/org/dependencytrack/model/vulndb/CvssV2Metric.java index d66c53aa7a..6beac3b3c4 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/CvssV2Metric.java +++ b/src/main/java/org/dependencytrack/model/vulndb/CvssV2Metric.java @@ -1,9 +1,31 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; import us.springett.cvss.CvssV2; import java.math.BigDecimal; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class CvssV2Metric { private int id; private String accessComplexity; diff --git a/src/main/java/org/dependencytrack/model/vulndb/CvssV3Metric.java b/src/main/java/org/dependencytrack/model/vulndb/CvssV3Metric.java index 0bbc052955..d1ab18281f 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/CvssV3Metric.java +++ b/src/main/java/org/dependencytrack/model/vulndb/CvssV3Metric.java @@ -1,9 +1,31 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; import us.springett.cvss.CvssV3; import java.math.BigDecimal; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class CvssV3Metric { private String attackComplexity; private String scope; diff --git a/src/main/java/org/dependencytrack/model/vulndb/ExternalReference.java b/src/main/java/org/dependencytrack/model/vulndb/ExternalReference.java index bd722ad00f..ef437dd438 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/ExternalReference.java +++ b/src/main/java/org/dependencytrack/model/vulndb/ExternalReference.java @@ -1,5 +1,27 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class ExternalReference { private String type; private String value; diff --git a/src/main/java/org/dependencytrack/model/vulndb/ExternalText.java b/src/main/java/org/dependencytrack/model/vulndb/ExternalText.java index fcf6e57606..97e0c93c49 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/ExternalText.java +++ b/src/main/java/org/dependencytrack/model/vulndb/ExternalText.java @@ -1,5 +1,27 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class ExternalText { private String type; private String value; diff --git a/src/main/java/org/dependencytrack/model/vulndb/NvdAdditionalInfo.java b/src/main/java/org/dependencytrack/model/vulndb/NvdAdditionalInfo.java index 5772d10f5b..f688b95cac 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/NvdAdditionalInfo.java +++ b/src/main/java/org/dependencytrack/model/vulndb/NvdAdditionalInfo.java @@ -1,5 +1,27 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class NvdAdditionalInfo { private String summary; private String cweId; diff --git a/src/main/java/org/dependencytrack/model/vulndb/Product.java b/src/main/java/org/dependencytrack/model/vulndb/Product.java index 9a999379f9..0d6334a41d 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/Product.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Product.java @@ -1,9 +1,31 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; import java.util.ArrayList; import java.util.List; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class Product implements ApiObject { private int id; private String name; diff --git a/src/main/java/org/dependencytrack/model/vulndb/Results.java b/src/main/java/org/dependencytrack/model/vulndb/Results.java index 72a507a1d0..8a0b11498c 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/Results.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Results.java @@ -1,8 +1,30 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; import java.util.ArrayList; import java.util.List; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class Results { private int page; private int total; diff --git a/src/main/java/org/dependencytrack/model/vulndb/Status.java b/src/main/java/org/dependencytrack/model/vulndb/Status.java index b1559cd087..6e421b7a07 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/Status.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Status.java @@ -1,5 +1,27 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class Status { private String organizationName; private String userNameRequesting; diff --git a/src/main/java/org/dependencytrack/model/vulndb/Vendor.java b/src/main/java/org/dependencytrack/model/vulndb/Vendor.java index ebfeace3ee..6cbe1f75f9 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/Vendor.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Vendor.java @@ -1,8 +1,30 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; import java.util.ArrayList; import java.util.List; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class Vendor implements ApiObject { private int id; private String name; diff --git a/src/main/java/org/dependencytrack/model/vulndb/Version.java b/src/main/java/org/dependencytrack/model/vulndb/Version.java index 002bae0ec9..073634f290 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/Version.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Version.java @@ -1,8 +1,30 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; import java.util.ArrayList; import java.util.List; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class Version implements ApiObject { private int id; private String name; diff --git a/src/main/java/org/dependencytrack/model/vulndb/VulnDbParser.java b/src/main/java/org/dependencytrack/model/vulndb/VulnDbParser.java index 4ddb6d378e..08987dbca8 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/VulnDbParser.java +++ b/src/main/java/org/dependencytrack/model/vulndb/VulnDbParser.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; import java.io.File; @@ -15,6 +33,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class VulnDbParser { private static final Logger LOGGER = LoggerFactory.getLogger(VulnDbParser.class); diff --git a/src/main/java/org/dependencytrack/model/vulndb/Vulnerability.java b/src/main/java/org/dependencytrack/model/vulndb/Vulnerability.java index f1a32dbe90..de58ec9b11 100644 --- a/src/main/java/org/dependencytrack/model/vulndb/Vulnerability.java +++ b/src/main/java/org/dependencytrack/model/vulndb/Vulnerability.java @@ -1,8 +1,30 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.model.vulndb; import java.util.ArrayList; import java.util.List; +/* + * Model class needed by VulnDBAnalysis task. Class brought over from the vulndb-data-mirror repo: + * ... + */ public class Vulnerability implements ApiObject { private int id; private String title; diff --git a/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXVexImporter.java b/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXVexImporter.java index 7c8a773735..ca469e205a 100644 --- a/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXVexImporter.java +++ b/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXVexImporter.java @@ -23,7 +23,6 @@ import org.cyclonedx.util.BomLink; import org.cyclonedx.util.ObjectLocator; import org.dependencytrack.model.Analysis; -import org.dependencytrack.model.AnalysisComment; import org.dependencytrack.model.AnalysisJustification; import org.dependencytrack.model.AnalysisResponse; import org.dependencytrack.model.AnalysisState; @@ -34,6 +33,7 @@ import org.dependencytrack.parser.cyclonedx.util.ModelConverter; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.util.AnalysisCommentUtil; + import java.util.List; public class CycloneDXVexImporter { diff --git a/src/main/java/org/dependencytrack/parser/osv/OsvAdvisoryParser.java b/src/main/java/org/dependencytrack/parser/osv/OsvAdvisoryParser.java index 8b1b3692b8..4f66d45d5c 100644 --- a/src/main/java/org/dependencytrack/parser/osv/OsvAdvisoryParser.java +++ b/src/main/java/org/dependencytrack/parser/osv/OsvAdvisoryParser.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.parser.osv; import org.json.JSONArray; diff --git a/src/main/java/org/dependencytrack/parser/osv/model/OsvAdvisory.java b/src/main/java/org/dependencytrack/parser/osv/model/OsvAdvisory.java index 521f62d6ca..d928912385 100644 --- a/src/main/java/org/dependencytrack/parser/osv/model/OsvAdvisory.java +++ b/src/main/java/org/dependencytrack/parser/osv/model/OsvAdvisory.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.parser.osv.model; import java.time.ZonedDateTime; diff --git a/src/main/java/org/dependencytrack/parser/osv/model/OsvAffectedPackage.java b/src/main/java/org/dependencytrack/parser/osv/model/OsvAffectedPackage.java index 7ac41e3822..83cd460d27 100644 --- a/src/main/java/org/dependencytrack/parser/osv/model/OsvAffectedPackage.java +++ b/src/main/java/org/dependencytrack/parser/osv/model/OsvAffectedPackage.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.parser.osv.model; import org.dependencytrack.model.Severity; diff --git a/src/main/java/org/dependencytrack/parser/snyk/SnykParser.java b/src/main/java/org/dependencytrack/parser/snyk/SnykParser.java index 0f6c7b9c6b..37a7fc3e01 100644 --- a/src/main/java/org/dependencytrack/parser/snyk/SnykParser.java +++ b/src/main/java/org/dependencytrack/parser/snyk/SnykParser.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.parser.snyk; import alpine.common.logging.Logger; diff --git a/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java b/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java index 029dea5392..b05f92b5b4 100644 --- a/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java +++ b/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java @@ -19,25 +19,18 @@ package org.dependencytrack.persistence; import alpine.common.logging.Logger; -import alpine.event.framework.Event; import alpine.model.ManagedUser; import alpine.model.Permission; import alpine.model.Team; import alpine.server.auth.PasswordService; import org.dependencytrack.RequirementsVerifier; import org.dependencytrack.auth.Permissions; -import org.dependencytrack.event.IndexEvent; -import org.dependencytrack.model.Component; import org.dependencytrack.model.ConfigPropertyConstants; import org.dependencytrack.model.License; -import org.dependencytrack.model.Project; import org.dependencytrack.model.RepositoryType; -import org.dependencytrack.model.Vulnerability; -import org.dependencytrack.model.VulnerableSoftware; import org.dependencytrack.notification.publisher.DefaultNotificationPublishers; import org.dependencytrack.parser.spdx.json.SpdxLicenseDetailParser; import org.dependencytrack.persistence.defaults.DefaultLicenseGroupImporter; -import org.dependencytrack.search.IndexManager; import org.dependencytrack.util.NotificationUtil; import javax.servlet.ServletContextEvent; diff --git a/src/main/java/org/dependencytrack/persistence/NotificationQueryManager.java b/src/main/java/org/dependencytrack/persistence/NotificationQueryManager.java index 72b0b5b424..1a6eab58de 100644 --- a/src/main/java/org/dependencytrack/persistence/NotificationQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/NotificationQueryManager.java @@ -31,7 +31,6 @@ import javax.jdo.PersistenceManager; import javax.jdo.Query; import java.util.List; -import java.util.UUID; public class NotificationQueryManager extends QueryManager implements IQueryManager { diff --git a/src/main/java/org/dependencytrack/persistence/ProjectQueryFilterBuilder.java b/src/main/java/org/dependencytrack/persistence/ProjectQueryFilterBuilder.java index 75b314cfeb..9dc4824682 100644 --- a/src/main/java/org/dependencytrack/persistence/ProjectQueryFilterBuilder.java +++ b/src/main/java/org/dependencytrack/persistence/ProjectQueryFilterBuilder.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.persistence; import alpine.model.Team; diff --git a/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java b/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java index ef3f93377d..59264dd5dc 100644 --- a/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java @@ -29,7 +29,6 @@ import alpine.persistence.PaginatedResult; import alpine.resources.AlpineRequest; import com.github.packageurl.PackageURL; - import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.dependencytrack.auth.Permissions; @@ -57,7 +56,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.UUID; diff --git a/src/main/java/org/dependencytrack/persistence/TagQueryManager.java b/src/main/java/org/dependencytrack/persistence/TagQueryManager.java index 6a025b8149..4d7e143fd0 100644 --- a/src/main/java/org/dependencytrack/persistence/TagQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/TagQueryManager.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.persistence; import alpine.common.logging.Logger; diff --git a/src/main/java/org/dependencytrack/policy/ComponentAgePolicyEvaluator.java b/src/main/java/org/dependencytrack/policy/ComponentAgePolicyEvaluator.java new file mode 100644 index 0000000000..1bb40f5d1c --- /dev/null +++ b/src/main/java/org/dependencytrack/policy/ComponentAgePolicyEvaluator.java @@ -0,0 +1,122 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ +package org.dependencytrack.policy; + +import alpine.common.logging.Logger; +import org.dependencytrack.model.Component; +import org.dependencytrack.model.Policy; +import org.dependencytrack.model.PolicyCondition; +import org.dependencytrack.model.RepositoryMetaComponent; +import org.dependencytrack.model.RepositoryType; +import org.dependencytrack.persistence.QueryManager; + +import java.time.LocalDate; +import java.time.Period; +import java.time.ZoneId; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Evaluates a {@link Component}'s published date against a {@link Policy}. + *

+ * Age values can be provided in ISO-8601 period format, see {@link Period#parse(CharSequence)}. + * + * @since 4.8.0 + */ +public class ComponentAgePolicyEvaluator extends AbstractPolicyEvaluator { + + private static final Logger LOGGER = Logger.getLogger(ComponentAgePolicyEvaluator.class); + + /** + * {@inheritDoc} + */ + @Override + public PolicyCondition.Subject supportedSubject() { + return PolicyCondition.Subject.AGE; + } + + /** + * {@inheritDoc} + */ + @Override + public List evaluate(final Policy policy, final Component component) { + final var violations = new ArrayList(); + if (component.getPurl() == null) { + return violations; + } + + final RepositoryType repoType = RepositoryType.resolve(component.getPurl()); + if (RepositoryType.UNSUPPORTED == repoType) { + return violations; + } + + final RepositoryMetaComponent metaComponent; + try (final var qm = new QueryManager()) { + metaComponent = qm.getRepositoryMetaComponent(repoType, + component.getPurl().getNamespace(), component.getPurl().getName()); + qm.getPersistenceManager().detachCopy(metaComponent); + } + if (metaComponent == null || metaComponent.getPublished() == null) { + return violations; + } + + for (final PolicyCondition condition : super.extractSupportedConditions(policy)) { + if (evaluate(condition, metaComponent.getPublished())) { + violations.add(new PolicyConditionViolation(condition, component)); + } + } + + return violations; + } + + private boolean evaluate(final PolicyCondition condition, final Date published) { + final Period agePeriod; + try { + agePeriod = Period.parse(condition.getValue()); + } catch (DateTimeParseException e) { + LOGGER.error("Invalid age duration format", e); + return false; + } + + if (agePeriod.isZero() || agePeriod.isNegative()) { + LOGGER.warn("Age durations must not be zero or negative"); + return false; + } + + final LocalDate publishedDate = LocalDate.ofInstant(published.toInstant(), ZoneId.systemDefault()); + final LocalDate ageDate = publishedDate.plus(agePeriod); + final LocalDate today = LocalDate.now(); + + return switch (condition.getOperator()) { + case NUMERIC_GREATER_THAN -> ageDate.isBefore(today); + case NUMERIC_GREATER_THAN_OR_EQUAL -> ageDate.isEqual(today) || ageDate.isBefore(today); + case NUMERIC_EQUAL -> ageDate.isEqual(today); + case NUMERIC_NOT_EQUAL -> !ageDate.isEqual(today); + case NUMERIC_LESSER_THAN_OR_EQUAL -> ageDate.isEqual(today) || ageDate.isAfter(today); + case NUMERIC_LESS_THAN -> ageDate.isAfter(LocalDate.now()); + default -> { + LOGGER.warn("Operator %s is not supported for component age conditions".formatted(condition.getOperator())); + yield false; + } + }; + } + +} diff --git a/src/main/java/org/dependencytrack/policy/ComponentHashPolicyEvaluator.java b/src/main/java/org/dependencytrack/policy/ComponentHashPolicyEvaluator.java index 7aac2ec5c6..70fc3c9887 100644 --- a/src/main/java/org/dependencytrack/policy/ComponentHashPolicyEvaluator.java +++ b/src/main/java/org/dependencytrack/policy/ComponentHashPolicyEvaluator.java @@ -21,8 +21,10 @@ import alpine.common.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.cyclonedx.model.Hash; + import org.dependencytrack.model.Policy; import org.dependencytrack.model.Component; + import org.dependencytrack.model.PolicyCondition; import org.json.JSONObject; diff --git a/src/main/java/org/dependencytrack/policy/CwePolicyEvaluator.java b/src/main/java/org/dependencytrack/policy/CwePolicyEvaluator.java index d91792168f..fe6d1900ef 100644 --- a/src/main/java/org/dependencytrack/policy/CwePolicyEvaluator.java +++ b/src/main/java/org/dependencytrack/policy/CwePolicyEvaluator.java @@ -1,4 +1,4 @@ - /* +/* * This file is part of Dependency-Track. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/main/java/org/dependencytrack/policy/PolicyEngine.java b/src/main/java/org/dependencytrack/policy/PolicyEngine.java index ce8821c67d..49efe39d56 100644 --- a/src/main/java/org/dependencytrack/policy/PolicyEngine.java +++ b/src/main/java/org/dependencytrack/policy/PolicyEngine.java @@ -55,6 +55,7 @@ public PolicyEngine() { evaluators.add(new CpePolicyEvaluator()); evaluators.add(new SwidTagIdPolicyEvaluator()); evaluators.add(new VersionPolicyEvaluator()); + evaluators.add(new ComponentAgePolicyEvaluator()); evaluators.add(new ComponentHashPolicyEvaluator()); evaluators.add(new CwePolicyEvaluator()); } @@ -130,6 +131,7 @@ private PolicyViolation.Type determineViolationType(final PolicyCondition.Subjec case CWE: case SEVERITY: return PolicyViolation.Type.SECURITY; + case AGE: case COORDINATES: case PACKAGE_URL: case CPE: diff --git a/src/main/java/org/dependencytrack/policy/VersionPolicyEvaluator.java b/src/main/java/org/dependencytrack/policy/VersionPolicyEvaluator.java index f99a0ecd5b..8e7b94b377 100644 --- a/src/main/java/org/dependencytrack/policy/VersionPolicyEvaluator.java +++ b/src/main/java/org/dependencytrack/policy/VersionPolicyEvaluator.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.policy; import alpine.common.logging.Logger; diff --git a/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java b/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java index 20af5ec83e..7bff4876af 100644 --- a/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java @@ -19,7 +19,6 @@ package org.dependencytrack.resources.v1; import alpine.common.logging.Logger; -import alpine.model.ConfigProperty; import alpine.model.Team; import alpine.persistence.PaginatedResult; import alpine.server.auth.PermissionRequired; @@ -31,7 +30,6 @@ import io.swagger.annotations.ApiResponses; import io.swagger.annotations.Authorization; import org.dependencytrack.auth.Permissions; -import org.dependencytrack.model.ConfigPropertyConstants; import org.dependencytrack.model.Project; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.resources.v1.vo.AclMappingRequest; diff --git a/src/main/java/org/dependencytrack/resources/v1/ConfigPropertyResource.java b/src/main/java/org/dependencytrack/resources/v1/ConfigPropertyResource.java index 034f7b0847..b3e0283c54 100644 --- a/src/main/java/org/dependencytrack/resources/v1/ConfigPropertyResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/ConfigPropertyResource.java @@ -19,7 +19,6 @@ package org.dependencytrack.resources.v1; import alpine.model.ConfigProperty; -import alpine.model.IConfigProperty; import alpine.server.auth.PermissionRequired; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; diff --git a/src/main/java/org/dependencytrack/resources/v1/FindingResource.java b/src/main/java/org/dependencytrack/resources/v1/FindingResource.java index 3a5290e4e9..f8ed552d1d 100644 --- a/src/main/java/org/dependencytrack/resources/v1/FindingResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/FindingResource.java @@ -46,7 +46,6 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; diff --git a/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java b/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java index b8bf769e01..75d9748bcd 100644 --- a/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java @@ -24,11 +24,13 @@ import alpine.notification.NotificationLevel; import alpine.server.auth.PermissionRequired; import alpine.server.resources.AlpineResource; + import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponses; import io.swagger.annotations.ApiParam; import io.swagger.annotations.Api; + import io.swagger.annotations.Authorization; import org.dependencytrack.auth.Permissions; import org.dependencytrack.model.ConfigPropertyConstants; @@ -45,15 +47,17 @@ import javax.json.Json; import javax.json.JsonObject; import javax.validation.Validator; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.GET; -import javax.ws.rs.Produces; + import javax.ws.rs.Consumes; -import javax.ws.rs.POST; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; + import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.IOException; diff --git a/src/main/java/org/dependencytrack/resources/v1/OidcResource.java b/src/main/java/org/dependencytrack/resources/v1/OidcResource.java index bb82f70173..2430a118c2 100644 --- a/src/main/java/org/dependencytrack/resources/v1/OidcResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/OidcResource.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.resources.v1; import alpine.common.logging.Logger; diff --git a/src/main/java/org/dependencytrack/resources/v1/SearchResource.java b/src/main/java/org/dependencytrack/resources/v1/SearchResource.java index 6dc467cfda..2a7df3d964 100644 --- a/src/main/java/org/dependencytrack/resources/v1/SearchResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/SearchResource.java @@ -39,7 +39,6 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.Collections; -import java.util.List; import java.util.Set; /** diff --git a/src/main/java/org/dependencytrack/resources/v1/TagResource.java b/src/main/java/org/dependencytrack/resources/v1/TagResource.java index c91b7b6197..d0b58883ec 100644 --- a/src/main/java/org/dependencytrack/resources/v1/TagResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/TagResource.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.resources.v1; import alpine.persistence.PaginatedResult; diff --git a/src/main/java/org/dependencytrack/resources/v1/VexResource.java b/src/main/java/org/dependencytrack/resources/v1/VexResource.java index c783918947..f2f59d19de 100644 --- a/src/main/java/org/dependencytrack/resources/v1/VexResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/VexResource.java @@ -34,7 +34,6 @@ import org.cyclonedx.CycloneDxMediaType; import org.cyclonedx.exception.GeneratorException; import org.dependencytrack.auth.Permissions; -import org.dependencytrack.event.BomUploadEvent; import org.dependencytrack.event.VexUploadEvent; import org.dependencytrack.model.Project; import org.dependencytrack.parser.cyclonedx.CycloneDXExporter; diff --git a/src/main/java/org/dependencytrack/resources/v1/vo/BomUploadResponse.java b/src/main/java/org/dependencytrack/resources/v1/vo/BomUploadResponse.java index 0c7dec734d..5278654b52 100644 --- a/src/main/java/org/dependencytrack/resources/v1/vo/BomUploadResponse.java +++ b/src/main/java/org/dependencytrack/resources/v1/vo/BomUploadResponse.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.resources.v1.vo; import java.io.Serializable; diff --git a/src/main/java/org/dependencytrack/resources/v1/vo/IsTokenBeingProcessedResponse.java b/src/main/java/org/dependencytrack/resources/v1/vo/IsTokenBeingProcessedResponse.java index 03cf3b8024..9854a27443 100644 --- a/src/main/java/org/dependencytrack/resources/v1/vo/IsTokenBeingProcessedResponse.java +++ b/src/main/java/org/dependencytrack/resources/v1/vo/IsTokenBeingProcessedResponse.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.resources.v1.vo; import java.io.Serializable; diff --git a/src/main/java/org/dependencytrack/resources/v1/vo/MappedOidcGroupRequest.java b/src/main/java/org/dependencytrack/resources/v1/vo/MappedOidcGroupRequest.java index a8c48189de..2350331118 100644 --- a/src/main/java/org/dependencytrack/resources/v1/vo/MappedOidcGroupRequest.java +++ b/src/main/java/org/dependencytrack/resources/v1/vo/MappedOidcGroupRequest.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.resources.v1.vo; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/src/main/java/org/dependencytrack/resources/v1/vo/TeamSelfResponse.java b/src/main/java/org/dependencytrack/resources/v1/vo/TeamSelfResponse.java index 368d7fed0c..a84a59e3b7 100644 --- a/src/main/java/org/dependencytrack/resources/v1/vo/TeamSelfResponse.java +++ b/src/main/java/org/dependencytrack/resources/v1/vo/TeamSelfResponse.java @@ -1,17 +1,20 @@ /* - * Copyright 2022 OWASP. + * This file is part of Dependency-Track. * * 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 * - * https://www.apache.org/licenses/LICENSE-2.0 + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. */ package org.dependencytrack.resources.v1.vo; diff --git a/src/main/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManager.java b/src/main/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManager.java index e5d32c9788..dcd2bcd6e1 100644 --- a/src/main/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManager.java +++ b/src/main/java/org/dependencytrack/search/FuzzyVulnerableSoftwareSearchManager.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.search; import alpine.common.logging.Logger; @@ -27,16 +45,16 @@ import us.springett.parsers.cpe.values.Part; import java.io.IOException; -import java.util.Set; -import java.util.Objects; + +import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.HashMap; -import java.util.ArrayList; -import java.util.LinkedList; - +import java.util.Objects; +import java.util.Set; public class FuzzyVulnerableSoftwareSearchManager { diff --git a/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java b/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java index 0614de9fb8..665823a742 100644 --- a/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java +++ b/src/main/java/org/dependencytrack/tasks/OsvDownloadTask.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.tasks; import alpine.common.logging.Logger; @@ -32,7 +50,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; diff --git a/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java index 4bdfefac3c..d1a9f80a79 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/CargoMetaAnalyzer.java @@ -24,7 +24,6 @@ import org.json.JSONObject; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; -import org.apache.http.StatusLine; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.util.EntityUtils; import org.dependencytrack.model.Component; diff --git a/src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java index 2cc49b8255..5cbe963f8c 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java @@ -22,7 +22,6 @@ import com.github.packageurl.PackageURL; import org.json.JSONObject; import org.apache.http.HttpStatus; -import org.apache.http.StatusLine; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.util.EntityUtils; import org.apache.maven.artifact.versioning.ComparableVersion; diff --git a/src/main/java/org/dependencytrack/upgrade/v440/v440Updater.java b/src/main/java/org/dependencytrack/upgrade/v440/v440Updater.java index 25972e7de7..b26deb746e 100644 --- a/src/main/java/org/dependencytrack/upgrade/v440/v440Updater.java +++ b/src/main/java/org/dependencytrack/upgrade/v440/v440Updater.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.upgrade.v440; import alpine.common.logging.Logger; diff --git a/src/main/java/org/dependencytrack/util/CacheStampedeBlocker.java b/src/main/java/org/dependencytrack/util/CacheStampedeBlocker.java index 304e653f5c..0def71a46e 100644 --- a/src/main/java/org/dependencytrack/util/CacheStampedeBlocker.java +++ b/src/main/java/org/dependencytrack/util/CacheStampedeBlocker.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.util; import alpine.common.logging.Logger; diff --git a/src/main/java/org/dependencytrack/util/VulnDBUtil.java b/src/main/java/org/dependencytrack/util/VulnDBUtil.java index 6b70feeb05..253e269104 100644 --- a/src/main/java/org/dependencytrack/util/VulnDBUtil.java +++ b/src/main/java/org/dependencytrack/util/VulnDBUtil.java @@ -1,3 +1,21 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.util; import oauth.signpost.OAuthConsumer; @@ -41,6 +59,12 @@ import java.util.ArrayList; import java.util.List; +/* + * Util class needed by VulnDBAnalysis Task to get vulnerabilities by the cpe provided. The result obtained from the api + * call are parsed and processed before being returned . Class brought over from the vulndb-data-mirror repo: + * ... and refactored to use the apache http client + * instead of the Unirest client it was using in the source repo. + */ public class VulnDBUtil { private final String consumerKey; @@ -70,7 +94,9 @@ public Results getVulnerabilitiesByCpe(String cpe, int size, int page) throws IO return this.getResults(apiBaseUrl+"/api/v1/vulnerabilities/find_by_cpe?&cpe=" + encodedCpe, Vulnerability.class, size, page); } - private Results getResults(String url, Class clazz, int size, int page) throws IOException, OAuthMessageSignerException, OAuthExpectationFailedException, URISyntaxException, OAuthCommunicationException { + private Results getResults(String url, Class clazz, int size, int page) throws IOException, + OAuthMessageSignerException, OAuthExpectationFailedException, URISyntaxException, + OAuthCommunicationException { String modifiedUrl = url.contains("?") ? url + "&" : url + "?"; CloseableHttpResponse response = this.makeRequest(modifiedUrl + "size=" + size + "&page=" + page); Results results; diff --git a/src/main/java/org/dependencytrack/util/XmlUtil.java b/src/main/java/org/dependencytrack/util/XmlUtil.java index a4787f8cea..f7aff024f8 100644 --- a/src/main/java/org/dependencytrack/util/XmlUtil.java +++ b/src/main/java/org/dependencytrack/util/XmlUtil.java @@ -31,8 +31,10 @@ import java.io.InputStream; import static org.apache.xerces.jaxp.JAXPConstants.JAXP_SCHEMA_LANGUAGE; -import static org.apache.xerces.jaxp.JAXPConstants.W3C_XML_SCHEMA; + import static org.apache.xerces.jaxp.JAXPConstants.JAXP_SCHEMA_SOURCE; +import static org.apache.xerces.jaxp.JAXPConstants.W3C_XML_SCHEMA; + public final class XmlUtil { diff --git a/src/test/java/org/dependencytrack/policy/ComponentAgePolicyEvaluatorTest.java b/src/test/java/org/dependencytrack/policy/ComponentAgePolicyEvaluatorTest.java new file mode 100644 index 0000000000..d5bde3b142 --- /dev/null +++ b/src/test/java/org/dependencytrack/policy/ComponentAgePolicyEvaluatorTest.java @@ -0,0 +1,124 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ +package org.dependencytrack.policy; + +import org.dependencytrack.PersistenceCapableTest; +import org.dependencytrack.model.Component; +import org.dependencytrack.model.Policy; +import org.dependencytrack.model.PolicyCondition.Operator; +import org.dependencytrack.model.PolicyCondition.Subject; +import org.dependencytrack.model.RepositoryMetaComponent; +import org.dependencytrack.model.RepositoryType; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.time.Duration; +import java.time.Instant; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(Parameterized.class) +public class ComponentAgePolicyEvaluatorTest extends PersistenceCapableTest { + + @Parameterized.Parameters(name = "[{index}] publishedDate={0} operator={1} ageValue={2} shouldViolate={3}") + public static Collection testParameters() { + return Arrays.asList(new Object[][]{ + // Component is older by one day. + {Instant.now().minus(Duration.ofDays(667)), Operator.NUMERIC_GREATER_THAN, "P666D", true}, + {Instant.now().minus(Duration.ofDays(667)), Operator.NUMERIC_GREATER_THAN_OR_EQUAL, "P666D", true}, + {Instant.now().minus(Duration.ofDays(667)), Operator.NUMERIC_EQUAL, "P666D", false}, + {Instant.now().minus(Duration.ofDays(667)), Operator.NUMERIC_NOT_EQUAL, "P666D", true}, + {Instant.now().minus(Duration.ofDays(667)), Operator.NUMERIC_LESSER_THAN_OR_EQUAL, "P666D", false}, + {Instant.now().minus(Duration.ofDays(667)), Operator.NUMERIC_LESS_THAN, "P666D", false}, + // Component is newer by one day. + {Instant.now().minus(Duration.ofDays(665)), Operator.NUMERIC_GREATER_THAN, "P666D", false}, + {Instant.now().minus(Duration.ofDays(665)), Operator.NUMERIC_GREATER_THAN_OR_EQUAL, "P666D", false}, + {Instant.now().minus(Duration.ofDays(665)), Operator.NUMERIC_EQUAL, "P666D", false}, + {Instant.now().minus(Duration.ofDays(665)), Operator.NUMERIC_NOT_EQUAL, "P666D", true}, + {Instant.now().minus(Duration.ofDays(665)), Operator.NUMERIC_LESS_THAN, "P666D", true}, + // Component is exactly as old. + {Instant.now().minus(Duration.ofDays(666)), Operator.NUMERIC_GREATER_THAN, "P666D", false}, + {Instant.now().minus(Duration.ofDays(666)), Operator.NUMERIC_GREATER_THAN_OR_EQUAL, "P666D", true}, + {Instant.now().minus(Duration.ofDays(666)), Operator.NUMERIC_EQUAL, "P666D", true}, + {Instant.now().minus(Duration.ofDays(666)), Operator.NUMERIC_NOT_EQUAL, "P666D", false}, + {Instant.now().minus(Duration.ofDays(666)), Operator.NUMERIC_LESSER_THAN_OR_EQUAL, "P666D", true}, + {Instant.now().minus(Duration.ofDays(666)), Operator.NUMERIC_LESS_THAN, "P666D", false}, + // Unsupported operator. + {Instant.now().minus(Duration.ofDays(666)), Operator.MATCHES, "P666D", false}, + // Negative age period. + {Instant.now().minus(Duration.ofDays(666)), Operator.NUMERIC_EQUAL, "P-666D", false}, + // Invalid age period format. + {Instant.now().minus(Duration.ofDays(666)), Operator.NUMERIC_EQUAL, "foobar", false}, + // No known publish date. + {null, Operator.NUMERIC_EQUAL, "P666D", false}, + }); + } + + private final Instant publishedDate; + private final Operator operator; + private final String ageValue; + private final boolean shouldViolate; + + public ComponentAgePolicyEvaluatorTest(final Instant publishedDate, final Operator operator, + final String ageValue, final boolean shouldViolate) { + this.publishedDate = publishedDate; + this.operator = operator; + this.ageValue = ageValue; + this.shouldViolate = shouldViolate; + } + + @Test + public void evaluateTest() { + final var policy = qm.createPolicy("policy", Policy.Operator.ANY, Policy.ViolationState.FAIL); + final var condition = qm.createPolicyCondition(policy, Subject.AGE, operator, ageValue); + + final var metaComponent = new RepositoryMetaComponent(); + metaComponent.setRepositoryType(RepositoryType.MAVEN); + metaComponent.setNamespace("foo"); + metaComponent.setName("bar"); + metaComponent.setLatestVersion("6.6.6"); + if (publishedDate != null) { + metaComponent.setPublished(Date.from(publishedDate)); + } + metaComponent.setLastCheck(new Date()); + qm.persist(metaComponent); + + final var component = new Component(); + component.setPurl("pkg:maven/foo/bar@1.2.3"); + + final var evaluator = new ComponentAgePolicyEvaluator(); + evaluator.setQueryManager(qm); + + final List violations = evaluator.evaluate(policy, component); + if (shouldViolate) { + assertThat(violations).hasSize(1); + final PolicyConditionViolation violation = violations.get(0); + assertThat(violation.getComponent()).isEqualTo(component); + assertThat(violation.getPolicyCondition()).isEqualTo(condition); + } else { + assertThat(violations).isEmpty(); + } + } + +} \ No newline at end of file From 860c90e5b3f2cf1b8439dad137ad3e778b29a889 Mon Sep 17 00:00:00 2001 From: mehab Date: Fri, 10 Feb 2023 20:18:57 +0000 Subject: [PATCH 26/31] all changes completed except additional unit test Signed-off-by: mehab --- .../kenna/KennaSecurityUploader.java | 27 ++--- .../publisher/AbstractWebhookPublisher.java | 65 +++++------ .../parser/ossindex/OssIndexParser.java | 29 ++--- .../parser/vulndb/VulnDbClient.java | 37 +++--- .../parser/vulndb/VulnDbParser.java | 51 +++++---- .../parser/vulndb/model/ApiObject.java | 2 +- .../parser/vulndb/model/Author.java | 5 + .../parser/vulndb/model/Classification.java | 5 + .../parser/vulndb/model/Cpe.java | 4 + .../parser/vulndb/model/CvssV2Metric.java | 5 + .../parser/vulndb/model/CvssV3Metric.java | 5 + .../vulndb/model/ExternalReference.java | 5 + .../parser/vulndb/model/ExternalText.java | 5 + .../vulndb/model/NvdAdditionalInfo.java | 5 + .../parser/vulndb/model/Product.java | 5 + .../parser/vulndb/model/Results.java | 83 +++++++++++++- .../parser/vulndb/model/Results1.java | 87 -------------- .../parser/vulndb/model/Status.java | 22 ++++ .../parser/vulndb/model/Vendor.java | 31 ++++- .../parser/vulndb/model/Version.java | 29 ++++- .../parser/vulndb/model/Vulnerability.java | 29 ++++- .../tasks/GitHubAdvisoryMirrorTask.java | 108 ++++++++++-------- .../dependencytrack/tasks/VulnDbSyncTask.java | 2 +- .../repositories/AbstractMetaAnalyzer.java | 4 +- .../tasks/scanners/OssIndexAnalysisTask.java | 17 +-- .../tasks/scanners/SnykAnalysisTask.java | 89 +++++++-------- .../tasks/scanners/VulnDbAnalysisTask.java | 6 +- 27 files changed, 425 insertions(+), 337 deletions(-) delete mode 100644 src/main/java/org/dependencytrack/parser/vulndb/model/Results1.java diff --git a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java index 54129196cd..4e164f1ba6 100644 --- a/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java +++ b/src/main/java/org/dependencytrack/integrations/kenna/KennaSecurityUploader.java @@ -45,9 +45,8 @@ import java.util.ArrayList; import java.util.List; -import static org.dependencytrack.model.ConfigPropertyConstants.KENNA_ENABLED; import static org.dependencytrack.model.ConfigPropertyConstants.KENNA_CONNECTOR_ID; - +import static org.dependencytrack.model.ConfigPropertyConstants.KENNA_ENABLED; import static org.dependencytrack.model.ConfigPropertyConstants.KENNA_TOKEN; public class KennaSecurityUploader extends AbstractIntegrationPoint implements PortfolioFindingUploader { @@ -110,20 +109,18 @@ public void upload(final InputStream payload) { .addBinaryBody("file", payload, ContentType.APPLICATION_JSON, "findings.json") .build(); request.setEntity(data); - final CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK && response.getEntity() != null) { - String responseString = EntityUtils.toString(response.getEntity()); - final JSONObject root = new JSONObject(responseString); - if (root.getString("success").equals("true")) { - LOGGER.debug("Successfully uploaded KDI"); - return; + try (CloseableHttpResponse response = HttpClientPool.getClient().execute(request)) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK && response.getEntity() != null) { + String responseString = EntityUtils.toString(response.getEntity()); + final JSONObject root = new JSONObject(responseString); + if (root.getString("success").equals("true")) { + LOGGER.debug("Successfully uploaded KDI"); + return; + } + LOGGER.warn("An unexpected response was received uploading findings to Kenna Security"); + } else { + handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } - LOGGER.warn("An unexpected response was received uploading findings to Kenna Security"); - } else { - LOGGER.warn("Kenna uploader did not receive expected response while attempting to upload " - + "Dependency-Track findings. HTTP response code: " - + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); - handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } } catch (Exception e) { LOGGER.error("An error occurred attempting to upload findings to Kenna Security", e); diff --git a/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java b/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java index 48f8adc303..878749145d 100644 --- a/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java +++ b/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java @@ -19,7 +19,6 @@ package org.dependencytrack.notification.publisher; import alpine.notification.Notification; -import alpine.notification.NotificationLevel; import io.pebbletemplates.pebble.template.PebbleTemplate; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; @@ -27,9 +26,6 @@ import org.apache.http.util.EntityUtils; import org.dependencytrack.common.HttpClientPool; import org.dependencytrack.exception.PublisherException; -import org.dependencytrack.notification.NotificationConstants; -import org.dependencytrack.notification.NotificationGroup; -import org.dependencytrack.notification.NotificationScope; import org.dependencytrack.util.HttpUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,46 +34,46 @@ import java.io.IOException; public abstract class AbstractWebhookPublisher implements Publisher { - private static final Logger LOGGER = LoggerFactory.getLogger(AbstractWebhookPublisher.class); public void publish(final String publisherName, final PebbleTemplate template, final Notification notification, final JsonObject config) { - - LOGGER.debug("Preparing to publish " + publisherName + " notification"); + final Logger logger = LoggerFactory.getLogger(AbstractWebhookPublisher.class); + logger.debug("Preparing to publish " + publisherName + " notification"); if (config == null) { - LOGGER.warn("No configuration found. Skipping notification."); + logger.warn("No configuration found. Skipping notification."); return; } final String destination = getDestinationUrl(config); final String content = prepareTemplate(notification, template); if (destination == null || content == null) { - LOGGER.warn("A destination or template was not found. Skipping notification"); + logger.warn("A destination or template was not found. Skipping notification"); return; } final String mimeType = getTemplateMimeType(config); + var request = new HttpPost(destination); + request.addHeader("content-type", mimeType); + request.addHeader("accept", mimeType); + final BasicAuthCredentials credentials; + try { + credentials = getBasicAuthCredentials(); + } catch (PublisherException e) { + logger.warn("An error occurred during the retrieval of credentials needed for notification publication. Skipping notification", e); + return; + } + if (credentials != null) { + request.addHeader("Authorization", HttpUtil.basicAuthHeaderValue(credentials.user(), credentials.password())); + } + try { - var request = new HttpPost(destination); - request.addHeader("content-type", mimeType); - request.addHeader("accept", mimeType); - final BasicAuthCredentials credentials; - try { - credentials = getBasicAuthCredentials(); - } catch (PublisherException e) { - LOGGER.warn("An error occurred during the retrieval of credentials needed for notification publication. Skipping notification", e); - return; - } - if (credentials != null) { - request.addHeader("Authorization", HttpUtil.basicAuthHeaderValue(credentials.user(), credentials.password())); - } request.setEntity(new StringEntity(content)); - final CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - if (response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() >= 300) { - LOGGER.error("An error was encountered publishing notification to " + publisherName); - LOGGER.error("HTTP Status : " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); - LOGGER.error("Destination: " + destination); - LOGGER.error("Response: " + EntityUtils.toString(response.getEntity())); - LOGGER.debug(content); + try (final CloseableHttpResponse response = HttpClientPool.getClient().execute(request)) { + if (response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() >= 300) { + logger.error("An error was encountered publishing notification to " + publisherName + + "with HTTP Status : " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase() + + " Destination: " + destination + " Response: " + EntityUtils.toString(response.getEntity())); + logger.debug(content); + } } - }catch (IOException ex){ - handleRequestException(LOGGER, ex); + } catch (IOException ex) { + handleRequestException(logger, ex); } } @@ -94,12 +90,5 @@ protected record BasicAuthCredentials(String user, String password) { protected void handleRequestException(final Logger logger, final Exception e) { logger.error("Request failure", e); - Notification.dispatch(new Notification() - .scope(NotificationScope.SYSTEM) - .group(NotificationGroup.REPOSITORY) - .title(NotificationConstants.Title.REPO_ERROR) - .content("An error occurred publishing notification. Check log for details. " + e.getMessage()) - .level(NotificationLevel.ERROR) - ); } } diff --git a/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java b/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java index 3eb670c2c4..cbe419f14b 100644 --- a/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java +++ b/src/main/java/org/dependencytrack/parser/ossindex/OssIndexParser.java @@ -19,11 +19,10 @@ package org.dependencytrack.parser.ossindex; import alpine.common.logging.Logger; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; import org.dependencytrack.parser.ossindex.model.ComponentReport; import org.dependencytrack.parser.ossindex.model.ComponentReportVulnerability; +import org.json.JSONArray; +import org.json.JSONObject; import java.util.ArrayList; import java.util.List; @@ -46,26 +45,12 @@ public class OssIndexParser { */ public List parse(final String responseString) { LOGGER.debug("Parsing JSON response"); - JSONArray arr = null; - JSONObject jsonObject = null; - try { - jsonObject = new JSONObject(responseString); - } catch (JSONException ex) { - arr = new JSONArray(responseString); - } catch (Exception ex) { - LOGGER.error("failed in parsing response"); - } - if (jsonObject != null) { - arr = new JSONArray(); - arr.put(jsonObject); - } + JSONArray arr = new JSONArray(responseString); final List componentReports = new ArrayList<>(); - if (arr != null) { - for (int i = 0; i < arr.length(); i++) { - final JSONObject object = arr.getJSONObject(i); - final ComponentReport componentReport = parse(object); - componentReports.add(componentReport); - } + for (int i = 0; i < arr.length(); i++) { + final JSONObject object = arr.getJSONObject(i); + final ComponentReport componentReport = parse(object); + componentReports.add(componentReport); } return componentReports; } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/VulnDbClient.java b/src/main/java/org/dependencytrack/parser/vulndb/VulnDbClient.java index 5e759c7466..f371f13fb8 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/VulnDbClient.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/VulnDbClient.java @@ -21,7 +21,6 @@ import oauth.signpost.OAuthConsumer; import oauth.signpost.basic.DefaultOAuthConsumer; import oauth.signpost.exception.OAuthCommunicationException; -import oauth.signpost.exception.OAuthException; import oauth.signpost.exception.OAuthExpectationFailedException; import oauth.signpost.exception.OAuthMessageSignerException; import org.apache.http.HttpStatus; @@ -30,7 +29,7 @@ import org.apache.http.client.utils.URIBuilder; import org.apache.http.util.EntityUtils; import org.dependencytrack.common.HttpClientPool; -import org.dependencytrack.parser.vulndb.model.Results1; +import org.dependencytrack.parser.vulndb.model.Results; import org.dependencytrack.parser.vulndb.model.Vulnerability; import org.json.JSONObject; import org.slf4j.Logger; @@ -64,7 +63,7 @@ public VulnDbClient(String consumerKey, String consumerSecret, String apiBaseUrl private static final Logger LOGGER = LoggerFactory.getLogger(VulnDbClient.class); - public Results1 getVulnerabilitiesByCpe(String cpe, int size, int page) throws IOException, OAuthMessageSignerException, OAuthExpectationFailedException, URISyntaxException, OAuthCommunicationException { + public Results getVulnerabilitiesByCpe(String cpe, int size, int page) throws IOException, OAuthMessageSignerException, OAuthExpectationFailedException, URISyntaxException, OAuthCommunicationException { String encodedCpe = cpe; try { @@ -77,14 +76,13 @@ public Results1 getVulnerabilitiesByCpe(String cpe, int size, int page) throws I return this.getResults(apiBaseUrl + "/api/v1/vulnerabilities/find_by_cpe?&cpe=" + encodedCpe, Vulnerability.class, size, page); } - private Results1 getResults(String url, Class clazz, int size, int page) throws IOException, + private Results getResults(String url, Class clazz, int size, int page) throws IOException, OAuthMessageSignerException, OAuthExpectationFailedException, URISyntaxException, OAuthCommunicationException { String modifiedUrl = url.contains("?") ? url + "&" : url + "?"; - CloseableHttpResponse response = this.makeRequest(modifiedUrl + "size=" + size + "&page=" + page); - VulnDbParser vulnDbParser = new VulnDbParser(); - Results1 results; - try { + try (CloseableHttpResponse response = this.makeRequest(modifiedUrl + "size=" + size + "&page=" + page)) { + VulnDbParser vulnDbParser = new VulnDbParser(); + Results results; if (response != null) { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { String responseString = EntityUtils.toString(response.getEntity()); @@ -92,36 +90,29 @@ private Results1 getResults(String url, Class clazz, int size, int page) throws results = vulnDbParser.parse(jsonObject, clazz); return results; } else { - results = new Results1(); + results = new Results(); results.setErrorCondition("An unexpected response was returned from VulnDB. Request unsuccessful: " + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); this.logHttpResponseError(response); return results; } } else { - results = new Results1(); + results = new Results(); results.setErrorCondition("No response was returned from VulnDB. No further information is available."); return results; } - } catch (IOException ex) { - throw ex; } } private CloseableHttpResponse makeRequest(String url) throws OAuthMessageSignerException, OAuthExpectationFailedException, IOException, URISyntaxException, OAuthCommunicationException { - try { - OAuthConsumer consumer = new DefaultOAuthConsumer(this.consumerKey, this.consumerSecret); - String signed = consumer.sign(url); - URIBuilder uriBuilder = new URIBuilder(signed); - HttpGet request = new HttpGet(uriBuilder.build().toString()); - request.addHeader("X-User-Agent", "Dependency Track (https://github.com/DependencyTrack/dependency-track)"); - return HttpClientPool.getClient().execute(request); - } catch (IOException | OAuthException | URISyntaxException var4) { - throw var4; - } + OAuthConsumer consumer = new DefaultOAuthConsumer(this.consumerKey, this.consumerSecret); + String signed = consumer.sign(url); + URIBuilder uriBuilder = new URIBuilder(signed); + HttpGet request = new HttpGet(uriBuilder.build().toString()); + request.addHeader("X-User-Agent", "Dependency Track (https://github.com/DependencyTrack/dependency-track)"); + return HttpClientPool.getClient().execute(request); } private void logHttpResponseError(CloseableHttpResponse response) { LOGGER.error("Response was not successful: " + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); - System.err.println("\n" + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase()); } } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/VulnDbParser.java b/src/main/java/org/dependencytrack/parser/vulndb/VulnDbParser.java index 5bae77049e..0db26820a2 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/VulnDbParser.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/VulnDbParser.java @@ -30,7 +30,6 @@ import org.dependencytrack.parser.vulndb.model.NvdAdditionalInfo; import org.dependencytrack.parser.vulndb.model.Product; import org.dependencytrack.parser.vulndb.model.Results; -import org.dependencytrack.parser.vulndb.model.Results1; import org.dependencytrack.parser.vulndb.model.Status; import org.dependencytrack.parser.vulndb.model.Vendor; import org.dependencytrack.parser.vulndb.model.Version; @@ -75,27 +74,24 @@ public Status parseStatus(JSONObject root) { public Results parse(Object jsonNode, Class apiObject) { LOGGER.debug("Parsing JSON node"); + + final Results results = new Results<>(); JSONObject root; root = (JSONObject) jsonNode; - JSONArray rso = root.getJSONArray("results"); + results.setPage(root.getInt("current_page")); + results.setTotal(root.getInt("total_entries")); + results.setRawResults(jsonNode.toString()); + final JSONArray rso = root.getJSONArray("results"); + if (Product.class == apiObject) { - results.setResults(this.parseProducts(rso)); + results.setResults(parseProducts(rso)); } else if (Vendor.class == apiObject) { - results.setResults(this.parseVendors(rso)); + results.setResults(parseVendors(rso)); } else if (Version.class == apiObject) { - results.setResults(this.parseVersions(rso)); + results.setResults(parseVersions(rso)); } else if (Vulnerability.class == apiObject) { - results.setResults(this.parseVulnerabilities(rso)); + results.setResults(parseVulnerabilities(rso)); } - Results results = new Results(root.getInt("current_page"), - root.getInt("total_entries"), - - ); - - results.setPage(root.getInt("current_page")); - results.setTotal(root.getInt("total_entries")); - results.setRawResults(jsonNode.toString()); - return results; } @@ -307,15 +303,20 @@ private List parseVulnerabilities(JSONArray rso) { } JSONArray nvdInfo = object.optJSONArray("nvd_additional_information"); - List nvdAdditionalInfos = new ArrayList<>(); + // List nvdAdditionalInfos = new ArrayList<>(); + NvdAdditionalInfo nvdAdditionalInfo = null; if (nvdInfo != null) { - for (int j = 0; j < nvdInfo.length(); ++j) { - JSONObject jso = nvdInfo.getJSONObject(j); - NvdAdditionalInfo nvdAdditionalInfo = new NvdAdditionalInfo(StringUtils.trimToNull(jso.optString("summary", (String) null)), - StringUtils.trimToNull(jso.optString("cwe_id", (String) null)), - StringUtils.trimToNull(jso.optString("cve_id", (String) null))); - nvdAdditionalInfos.add(nvdAdditionalInfo); - } +// for (int j = 0; j < nvdInfo.length(); ++j) { +// JSONObject jso = nvdInfo.getJSONObject(j); +// NvdAdditionalInfo nvdAdditionalInfo = new NvdAdditionalInfo(StringUtils.trimToNull(jso.optString("summary", (String) null)), +// StringUtils.trimToNull(jso.optString("cwe_id", (String) null)), +// StringUtils.trimToNull(jso.optString("cve_id", (String) null))); +// nvdAdditionalInfos.add(nvdAdditionalInfo); +// } + nvdAdditionalInfo = new NvdAdditionalInfo(StringUtils.trimToNull(nvdInfo.getJSONObject(nvdInfo.length()-1).optString("summary", (String) null)), + StringUtils.trimToNull(nvdInfo.getJSONObject(nvdInfo.length()-1).optString("cwe_id", (String) null)), + StringUtils.trimToNull(nvdInfo.getJSONObject(nvdInfo.length()-1).optString("cve_id", (String) null))); + } JSONArray vendors = object.optJSONArray("vendors"); @@ -341,8 +342,8 @@ private List parseVulnerabilities(JSONArray rso) { this.parseVendors(vendors), cvssV2MetricList, cvssV3MetricList, - nvdAdditionalInfos - ); + nvdAdditionalInfo + ); vulnerabilities.add(vulnerability); } } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/ApiObject.java b/src/main/java/org/dependencytrack/parser/vulndb/model/ApiObject.java index c5cf945619..d4b0e9a581 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/ApiObject.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/ApiObject.java @@ -22,7 +22,7 @@ * This interface defines the top-level (and queryable) objects that * VulnDB supports. * - * @author Steve Springett + * */ public interface ApiObject { int id(); diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/Author.java b/src/main/java/org/dependencytrack/parser/vulndb/model/Author.java index d131035638..4d2499cfe7 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/Author.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/Author.java @@ -18,5 +18,10 @@ */ package org.dependencytrack.parser.vulndb.model; +/** + * The response from VulnDB Vulnerability API will respond with 0 or more authors. + * This record defines the Author objects returned. + *Record created to replace the model class defined here: ... + */ public record Author(int id, String name, String company, String email, String companyUrl, String country) { } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/Classification.java b/src/main/java/org/dependencytrack/parser/vulndb/model/Classification.java index a51b9baa1f..32064bc066 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/Classification.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/Classification.java @@ -18,5 +18,10 @@ */ package org.dependencytrack.parser.vulndb.model; +/** + * The response from VulnDB Vulnerability API will respond with 0 or more classifications. + * This class defines the Classification objects returned. + * Record created to replace the model class defined here: ... + */ public record Classification(int id, String name, String longname, String description, String mediumtext) { } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/Cpe.java b/src/main/java/org/dependencytrack/parser/vulndb/model/Cpe.java index 43e456175f..564eda17fe 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/Cpe.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/Cpe.java @@ -18,5 +18,9 @@ */ package org.dependencytrack.parser.vulndb.model; +/** + * Defines an optional CPE returned in a response. + * Record created to replace the model class defined here: ... + */ public record Cpe(String cpe, String type) { } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/CvssV2Metric.java b/src/main/java/org/dependencytrack/parser/vulndb/model/CvssV2Metric.java index b7e2eb01f6..f1713a6177 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/CvssV2Metric.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/CvssV2Metric.java @@ -20,6 +20,11 @@ import java.math.BigDecimal; +/** + * The response from VulnDB Vulnerability API will respond with 0 or more CVSS Metrics. + * This record defines the CvssV2Metric objects returned. + * Record created to replace the model class defined here: ... + */ public record CvssV2Metric(int id, String accessComplexity, String cveId, String source, String availabilityImpact, String confidentialityImpact, String authentication, BigDecimal calculatedCvssBaseScore, String generatedOn, diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/CvssV3Metric.java b/src/main/java/org/dependencytrack/parser/vulndb/model/CvssV3Metric.java index 22ba64f1c9..d069365974 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/CvssV3Metric.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/CvssV3Metric.java @@ -20,6 +20,11 @@ import java.math.BigDecimal; +/** + * The response from VulnDB Vulnerability API will respond with 0 or more CVSS Metrics. + * This record defines the CvssV3Metric objects returned. + * Record created to replace the model class defined here: ... + */ public record CvssV3Metric(int id, String attackComplexity, String scope, String attackVector, diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/ExternalReference.java b/src/main/java/org/dependencytrack/parser/vulndb/model/ExternalReference.java index b76b573133..56bd948aad 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/ExternalReference.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/ExternalReference.java @@ -18,5 +18,10 @@ */ package org.dependencytrack.parser.vulndb.model; +/** + * The response from VulnDB Vulnerability API will respond with 0 or more external + * references. This record defines the ExternalReference objects returned. + * Record created to replace the model class defined here: ... + */ public record ExternalReference(String type, String value) { } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/ExternalText.java b/src/main/java/org/dependencytrack/parser/vulndb/model/ExternalText.java index 206896b41e..0f1cccb5ad 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/ExternalText.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/ExternalText.java @@ -18,5 +18,10 @@ */ package org.dependencytrack.parser.vulndb.model; +/** + * The response from VulnDB Vulnerability API will respond with 0 or more external + * texts. This record defines the ExternalText objects returned. + * Record created to replace the model class defined here: ... + */ public record ExternalText(String type, String value) { } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/NvdAdditionalInfo.java b/src/main/java/org/dependencytrack/parser/vulndb/model/NvdAdditionalInfo.java index 483e8add9f..1a85494506 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/NvdAdditionalInfo.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/NvdAdditionalInfo.java @@ -18,5 +18,10 @@ */ package org.dependencytrack.parser.vulndb.model; +/** + * The response from VulnDB Vulnerability API will respond with 0 or more nvd_additional_information. + * This record defines the NvdAdditionalInfo objects returned. + * Record created to replace the model class defined here: ... + */ public record NvdAdditionalInfo(String summary, String cweId, String cveId) { } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/Product.java b/src/main/java/org/dependencytrack/parser/vulndb/model/Product.java index 8e90759ec1..6152aed203 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/Product.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/Product.java @@ -20,5 +20,10 @@ import java.util.List; +/** + * The response from VulnDB Product API will respond with 0 or more products. + * This record defines the Product objects returned. + * Record created to replace the model class defined here: ... + */ public record Product(int id, String name, List versions) implements ApiObject{ } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/Results.java b/src/main/java/org/dependencytrack/parser/vulndb/model/Results.java index a63144fc36..d2146d14d1 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/Results.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/Results.java @@ -1,6 +1,87 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.parser.vulndb.model; +import java.util.ArrayList; import java.util.List; -public record Results(int page, int total, List results, String rawResults, String errorCondition) { +/** + * Defines a top-level Results object containing a list of + * possible results and count/page data. + * + * @author Steve Springett + */ +public class Results { + private int page; + private int total; + private List results = new ArrayList(); + private String rawResults; + private String errorCondition; + + public Results() { + } + + public int getPage() { + return this.page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getTotal() { + return this.total; + } + + public void setTotal(int total) { + this.total = total; + } + + public List getResults() { + return this.results; + } + + public void setResults(List objects) { + this.results = objects; + } + + public void add(T object) { + this.results.add(object); + } + + public String getRawResults() { + return this.rawResults; + } + + public void setRawResults(String rawResults) { + this.rawResults = rawResults; + } + + public boolean isSuccessful() { + return this.errorCondition == null; + } + + public String getErrorCondition() { + return this.errorCondition; + } + + public void setErrorCondition(String errorCondition) { + this.errorCondition = errorCondition; + } } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/Results1.java b/src/main/java/org/dependencytrack/parser/vulndb/model/Results1.java deleted file mode 100644 index aaf39d57c4..0000000000 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/Results1.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) Steve Springett. All Rights Reserved. - */ -package org.dependencytrack.parser.vulndb.model; - -import java.util.ArrayList; -import java.util.List; - -/** - * Defines a top-level Results object containing a list of - * possible results and count/page data. - * - * @author Steve Springett - */ -public class Results1 { - private int page; - private int total; - private List results = new ArrayList(); - private String rawResults; - private String errorCondition; - - public Results1() { - } - - public int getPage() { - return this.page; - } - - public void setPage(int page) { - this.page = page; - } - - public int getTotal() { - return this.total; - } - - public void setTotal(int total) { - this.total = total; - } - - public List getResults() { - return this.results; - } - - public void setResults(List objects) { - this.results = objects; - } - - public void add(T object) { - this.results.add(object); - } - - public String getRawResults() { - return this.rawResults; - } - - public void setRawResults(String rawResults) { - this.rawResults = rawResults; - } - - public boolean isSuccessful() { - return this.errorCondition == null; - } - - public String getErrorCondition() { - return this.errorCondition; - } - - public void setErrorCondition(String errorCondition) { - this.errorCondition = errorCondition; - } -} diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/Status.java b/src/main/java/org/dependencytrack/parser/vulndb/model/Status.java index 2da8937b89..3de8e81920 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/Status.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/Status.java @@ -1,5 +1,27 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.parser.vulndb.model; +/** + * Defines a top-level Status object. + * Record created to replace the model class defined here: ... + */ public record Status(String organizationName, String userNameRequesting, String userEmailRequesting, String subscriptionEndDate, String apiCallsAllowedPerMonth, String apiCallsMadeThisMonth, String vulnDbStatistics, diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/Vendor.java b/src/main/java/org/dependencytrack/parser/vulndb/model/Vendor.java index 953f9404d4..9e4a8014ad 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/Vendor.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/Vendor.java @@ -1,11 +1,30 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.parser.vulndb.model; import java.util.List; -public record Vendor(int id, String name, String shortName, String vendorUrl, List products) implements ApiObject{ - - @Override - public int getId() { - return this.id(); - } +/** + * The response from VulnDB Vendor API will respond with 0 or more vendors. + * This record defines the Vendor objects returned. + * Record created to replace the model class defined here: ... + */ +public record Vendor(int id, String name, String shortName, String vendorUrl, + List products) implements ApiObject { } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/Version.java b/src/main/java/org/dependencytrack/parser/vulndb/model/Version.java index 0f75783a9b..497ebe3b32 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/Version.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/Version.java @@ -1,10 +1,29 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.parser.vulndb.model; import java.util.List; -public record Version(int id, String name, boolean affected, List cpes) implements ApiObject{ - @Override - public int getId() { - return this.id(); - } +/** + * The response from VulnDB Version API will respond with 0 or more versions. + * This record defines the Version objects returned. + * Record created to replace the model class defined here: ... + */ +public record Version(int id, String name, boolean affected, List cpes) implements ApiObject { } diff --git a/src/main/java/org/dependencytrack/parser/vulndb/model/Vulnerability.java b/src/main/java/org/dependencytrack/parser/vulndb/model/Vulnerability.java index 0e648ddfad..295389db9e 100644 --- a/src/main/java/org/dependencytrack/parser/vulndb/model/Vulnerability.java +++ b/src/main/java/org/dependencytrack/parser/vulndb/model/Vulnerability.java @@ -1,7 +1,30 @@ +/* + * This file is part of Dependency-Track. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) Steve Springett. All Rights Reserved. + */ package org.dependencytrack.parser.vulndb.model; import java.util.List; +/** + * The response from VulnDB Vulnerability API will respond with 0 or more vulnerabilities. + * This record defines the Vulnerability objects returned. + * Record created to replace the model class defined here: ... + */ public record Vulnerability(int id, String title, String disclosureDate, @@ -24,9 +47,5 @@ public record Vulnerability(int id, List vendors, List cvssV2Metrics, List cvssV3Metrics, - List nvdAdditionalInfo) implements ApiObject{ - @Override - public int getId() { - return this.id(); - } + NvdAdditionalInfo nvdAdditionalInfo) implements ApiObject { } diff --git a/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java b/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java index eb29aa16ef..118bcad5c2 100644 --- a/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java +++ b/src/main/java/org/dependencytrack/tasks/GitHubAdvisoryMirrorTask.java @@ -82,7 +82,7 @@ public class GitHubAdvisoryMirrorTask implements LoggableSubscriber { public GitHubAdvisoryMirrorTask() { try (final QueryManager qm = new QueryManager()) { final ConfigProperty enabled = qm.getConfigProperty(VULNERABILITY_SOURCE_GITHUB_ADVISORIES_ENABLED.getGroupName(), VULNERABILITY_SOURCE_GITHUB_ADVISORIES_ENABLED.getPropertyName()); - this.isEnabled = enabled != null && Boolean.valueOf(enabled.getPropertyValue()); + this.isEnabled = enabled != null && Boolean.parseBoolean(enabled.getPropertyValue()); final ConfigProperty accessToken = qm.getConfigProperty(VULNERABILITY_SOURCE_GITHUB_ADVISORIES_ACCESS_TOKEN.getGroupName(), VULNERABILITY_SOURCE_GITHUB_ADVISORIES_ACCESS_TOKEN.getPropertyName()); if (accessToken != null) { @@ -139,63 +139,64 @@ private void retrieveAdvisories(final String advisoriesEndCursor) throws IOExcep jsonBody.put("query", queryTemplate); var stringEntity = new StringEntity(jsonBody.toString()); request.setEntity(stringEntity); - CloseableHttpResponse response = HttpClientPool.getClient().execute(request); + try (CloseableHttpResponse response = HttpClientPool.getClient().execute(request)) { + if (response.getStatusLine().getStatusCode() < HttpStatus.SC_OK || response.getStatusLine().getStatusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) { + LOGGER.error("An error was encountered retrieving advisories with HTTP Status : " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); + LOGGER.debug(queryTemplate); + mirroredWithoutErrors = false; + } else { + var parser = new GitHubSecurityAdvisoryParser(); + String responseString = EntityUtils.toString(response.getEntity()); + var jsonObject = new JSONObject(responseString); + final PageableList pageableList = parser.parse(jsonObject); + updateDatasource(pageableList.getAdvisories()); + if (pageableList.isHasNextPage()) { + retrieveAdvisories(pageableList.getEndCursor()); + } + } - if (response.getStatusLine().getStatusCode() < HttpStatus.SC_OK || response.getStatusLine().getStatusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) { - LOGGER.error("An error was encountered retrieving advisories"); - LOGGER.error("HTTP Status : " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); - LOGGER.debug(queryTemplate); - mirroredWithoutErrors = false; - } else { - var parser = new GitHubSecurityAdvisoryParser(); - String responseString = EntityUtils.toString(response.getEntity()); - var jsonObject = new JSONObject(responseString); - final PageableList pageableList = parser.parse(jsonObject); - updateDatasource(pageableList.getAdvisories()); - if (pageableList.isHasNextPage()) { - retrieveAdvisories(pageableList.getEndCursor()); + if (mirroredWithoutErrors) { + Notification.dispatch(new Notification() + .scope(NotificationScope.SYSTEM) + .group(NotificationGroup.DATASOURCE_MIRRORING) + .title(NotificationConstants.Title.GITHUB_ADVISORY_MIRROR) + .content("Mirroring of GitHub Advisories completed successfully") + .level(NotificationLevel.INFORMATIONAL) + ); + } else { + Notification.dispatch(new Notification() + .scope(NotificationScope.SYSTEM) + .group(NotificationGroup.DATASOURCE_MIRRORING) + .title(NotificationConstants.Title.GITHUB_ADVISORY_MIRROR) + .content("An error occurred mirroring the contents of GitHub Advisories. Check log for details.") + .level(NotificationLevel.ERROR) + ); } } - if (mirroredWithoutErrors) { - Notification.dispatch(new Notification() - .scope(NotificationScope.SYSTEM) - .group(NotificationGroup.DATASOURCE_MIRRORING) - .title(NotificationConstants.Title.GITHUB_ADVISORY_MIRROR) - .content("Mirroring of GitHub Advisories completed successfully") - .level(NotificationLevel.INFORMATIONAL) - ); - } else { - Notification.dispatch(new Notification() - .scope(NotificationScope.SYSTEM) - .group(NotificationGroup.DATASOURCE_MIRRORING) - .title(NotificationConstants.Title.GITHUB_ADVISORY_MIRROR) - .content("An error occurred mirroring the contents of GitHub Advisories. Check log for details.") - .level(NotificationLevel.ERROR) - ); - } } /** * Synchronizes the advisories that were downloaded with the internal Dependency-Track database. + * * @param advisories the results to synchronize */ void updateDatasource(final List advisories) { LOGGER.debug("Updating datasource with GitHub advisories"); try (QueryManager qm = new QueryManager()) { - for (final GitHubSecurityAdvisory advisory: advisories) { + for (final GitHubSecurityAdvisory advisory : advisories) { LOGGER.debug("Synchronizing GitHub advisory: " + advisory.getGhsaId()); final Vulnerability mappedVulnerability = mapAdvisoryToVulnerability(qm, advisory); final List vsListOld = qm.detach(qm.getVulnerableSoftwareByVulnId(mappedVulnerability.getSource(), mappedVulnerability.getVulnId())); final Vulnerability synchronizedVulnerability = qm.synchronizeVulnerability(mappedVulnerability, false); List vsList = new ArrayList<>(); - for (GitHubVulnerability ghvuln: advisory.getVulnerabilities()) { + for (GitHubVulnerability ghvuln : advisory.getVulnerabilities()) { final VulnerableSoftware vs = mapVulnerabilityToVulnerableSoftware(qm, ghvuln, advisory); if (vs != null) { vsList.add(vs); } - for (Pair identifier: advisory.getIdentifiers()) { + for (Pair identifier : advisory.getIdentifiers()) { if (identifier != null && identifier.getLeft() != null - && "CVE".equalsIgnoreCase(identifier.getLeft()) && identifier.getLeft().startsWith("CVE")) { + && "CVE" .equalsIgnoreCase(identifier.getLeft()) && identifier.getLeft().startsWith("CVE")) { LOGGER.debug("Updating vulnerability alias for " + advisory.getGhsaId()); final VulnerabilityAlias alias = new VulnerabilityAlias(); alias.setGhsaId(advisory.getGhsaId()); @@ -217,6 +218,7 @@ void updateDatasource(final List advisories) { /** * Helper method that maps an GitHub SecurityAdvisory object to a Dependency-Track vulnerability object. + * * @param advisory the GitHub SecurityAdvisory to map * @return a Dependency-Track Vulnerability object */ @@ -241,7 +243,7 @@ private Vulnerability mapAdvisoryToVulnerability(final QueryManager qm, final Gi //vuln.setVulnerableVersions(advisory.getVulnerableVersions()); //vuln.setPatchedVersions(advisory.getPatchedVersions()); if (advisory.getCwes() != null) { - for (int i=0; i=")) { versionStartIncluding = part.replace(">=", "").trim(); } else if (part.startsWith(">")) { @@ -325,15 +328,24 @@ private VulnerableSoftware mapVulnerabilityToVulnerableSoftware(final QueryManag private String mapGitHubEcosystemToPurlType(final String ecosystem) { switch (ecosystem.toUpperCase()) { - case "MAVEN": return PackageURL.StandardTypes.MAVEN; - case "RUST": return PackageURL.StandardTypes.CARGO; - case "PIP": return PackageURL.StandardTypes.PYPI; - case "RUBYGEMS": return PackageURL.StandardTypes.GEM; - case "GO": return PackageURL.StandardTypes.GOLANG; - case "NPM": return PackageURL.StandardTypes.NPM; - case "COMPOSER": return PackageURL.StandardTypes.COMPOSER; - case "NUGET": return PackageURL.StandardTypes.NUGET; - default: return null; + case "MAVEN": + return PackageURL.StandardTypes.MAVEN; + case "RUST": + return PackageURL.StandardTypes.CARGO; + case "PIP": + return PackageURL.StandardTypes.PYPI; + case "RUBYGEMS": + return PackageURL.StandardTypes.GEM; + case "GO": + return PackageURL.StandardTypes.GOLANG; + case "NPM": + return PackageURL.StandardTypes.NPM; + case "COMPOSER": + return PackageURL.StandardTypes.COMPOSER; + case "NUGET": + return PackageURL.StandardTypes.NUGET; + default: + return null; } } diff --git a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java index e971e198ad..0e0486eef3 100644 --- a/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java +++ b/src/main/java/org/dependencytrack/tasks/VulnDbSyncTask.java @@ -121,7 +121,7 @@ public void inform(final Event e) { private void updateDatasource(final Results results) { LOGGER.info("Updating datasource with VulnDB vulnerabilities"); try (QueryManager qm = new QueryManager()) { - for (final Object o : results.results()) { + for (final Object o : results.getResults()) { if (o instanceof org.dependencytrack.parser.vulndb.model.Vulnerability) { final org.dependencytrack.parser.vulndb.model.Vulnerability vulnDbVuln = (org.dependencytrack.parser.vulndb.model.Vulnerability) o; final org.dependencytrack.model.Vulnerability vulnerability = ModelConverter.convert(qm, vulnDbVuln); diff --git a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java index cdb35ac1b0..4755cbb36c 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java @@ -49,7 +49,6 @@ public abstract class AbstractMetaAnalyzer implements IMetaAnalyzer { protected String username; protected String password; - private static final Logger LOGGER = Logger.getLogger(AbstractMetaAnalyzer.class); /** * {@inheritDoc} */ @@ -94,6 +93,7 @@ protected void handleRequestException(final Logger logger, final Exception e) { } protected CloseableHttpResponse processHttpRequest(String url) throws IOException { + final Logger logger = Logger.getLogger(AbstractMetaAnalyzer.class); try { URIBuilder uriBuilder = new URIBuilder(url); final HttpUriRequest request = new HttpGet(uriBuilder.build().toString()); @@ -103,7 +103,7 @@ protected CloseableHttpResponse processHttpRequest(String url) throws IOExceptio } return HttpClientPool.getClient().execute(request); }catch (URISyntaxException ex){ - handleRequestException(LOGGER, ex); + handleRequestException(logger, ex); return null; } } diff --git a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java index 6e8216ca04..02b26f1d2a 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java @@ -264,14 +264,15 @@ private List submit(final JSONObject payload) throws IOExceptio if (apiUsername != null && apiToken != null) { request.addHeader("Authorization", HttpUtil.basicAuthHeaderValue(apiUsername, apiToken)); } - final CloseableHttpResponse response = HttpClientPool.getClient().execute(request); - HttpEntity responseEntity = response.getEntity(); - String responseString = EntityUtils.toString(responseEntity); - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { - final OssIndexParser parser = new OssIndexParser(); - return parser.parse(responseString); - } else { - handleUnexpectedHttpResponse(LOGGER, API_BASE_URL, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); + try (final CloseableHttpResponse response = HttpClientPool.getClient().execute(request)) { + HttpEntity responseEntity = response.getEntity(); + String responseString = EntityUtils.toString(responseEntity); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + final OssIndexParser parser = new OssIndexParser(); + return parser.parse(responseString); + } else { + handleUnexpectedHttpResponse(LOGGER, API_BASE_URL, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); + } } return new ArrayList<>(); diff --git a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java index fadbf7521a..d0eae4549b 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java @@ -34,17 +34,15 @@ import io.github.resilience4j.retry.Retry; import io.github.resilience4j.retry.RetryConfig; import io.github.resilience4j.retry.RetryRegistry; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.apache.http.Header; +import org.apache.http.HttpHeaders; import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.utils.URIBuilder; -import org.json.JSONArray; -import org.json.JSONObject; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.concurrent.BasicThreadFactory; -import org.apache.http.HttpHeaders; -import org.apache.http.client.methods.HttpGet; import org.apache.http.util.EntityUtils; import org.dependencytrack.common.ConfigKey; import org.dependencytrack.common.HttpClientPool; @@ -62,6 +60,8 @@ import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.util.NotificationUtil; import org.dependencytrack.util.RoundRobinAccessor; +import org.json.JSONArray; +import org.json.JSONObject; import java.io.IOException; import java.net.URISyntaxException; @@ -117,8 +117,8 @@ public class SnykAnalysisTask extends BaseComponentAnalyzerTask implements Cache .build()); RETRY = retryRegistry.retry("snyk-api"); RETRY.getEventPublisher() - .onRetry(event -> LOGGER.debug("Will execute retry #%d in %s".formatted(event.getNumberOfRetryAttempts(), event.getWaitInterval()))) - .onError(event -> LOGGER.error("Retry failed after %d attempts: %s".formatted(event.getNumberOfRetryAttempts(), event.getLastThrowable()))); + .onRetry(event -> LOGGER.debug("Will execute retry #%d in %s" .formatted(event.getNumberOfRetryAttempts(), event.getWaitInterval()))) + .onError(event -> LOGGER.error("Retry failed after %d attempts: %s" .formatted(event.getNumberOfRetryAttempts(), event.getLastThrowable()))); TaggedRetryMetrics.ofRetryRegistry(retryRegistry) .bindTo(Metrics.getRegistry()); @@ -243,7 +243,7 @@ public void analyze(final List components) { countDownLatch.countDown(); if (exception != null) { - LOGGER.error("An unexpected error occurred while analyzing %s".formatted(component), exception); + LOGGER.error("An unexpected error occurred while analyzing %s" .formatted(component), exception); } }); } @@ -272,7 +272,7 @@ public void analyze(final List components) { .scope(NotificationScope.SYSTEM) .level(NotificationLevel.WARNING) .group(NotificationGroup.ANALYZER) - .title("Snyk API version %s is deprecated".formatted(apiVersion)) + .title("Snyk API version %s is deprecated" .formatted(apiVersion)) .content(message)); } } @@ -299,49 +299,44 @@ public void applyAnalysisFromCache(final Component component) { private void analyzeComponent(final Component component) { final String encodedPurl = URLEncoder.encode(component.getPurl().getCoordinates(), StandardCharsets.UTF_8); - final String requestUrl = "%s/rest/orgs/%s/packages/%s/issues?version=%s".formatted(apiBaseUrl, apiOrgId, encodedPurl, apiVersion); + final String requestUrl = "%s/rest/orgs/%s/packages/%s/issues?version=%s" .formatted(apiBaseUrl, apiOrgId, encodedPurl, apiVersion); try { - URIBuilder uriBuilder = new URIBuilder(requestUrl); - final HttpUriRequest request = new HttpGet(uriBuilder.build().toString()); - request.setHeader(HttpHeaders.USER_AGENT, ManagedHttpClientFactory.getUserAgent()); - request.setHeader(HttpHeaders.AUTHORIZATION, "token " + apiTokenSupplier.get()); - request.setHeader(HttpHeaders.ACCEPT, "application/vnd.api+json"); - final CloseableHttpResponse response = RETRY.executeSupplier(() -> { - try { - return HttpClientPool.getClient().execute(request); - } catch (IOException e) { - handleRequestException(LOGGER, e); - return null; + URIBuilder uriBuilder = new URIBuilder(requestUrl); + final HttpUriRequest request = new HttpGet(uriBuilder.build().toString()); + request.setHeader(HttpHeaders.USER_AGENT, ManagedHttpClientFactory.getUserAgent()); + request.setHeader(HttpHeaders.AUTHORIZATION, "token " + apiTokenSupplier.get()); + request.setHeader(HttpHeaders.ACCEPT, "application/vnd.api+json"); + try (final CloseableHttpResponse response = RETRY.executeCheckedSupplier(() -> HttpClientPool.getClient().execute(request))) { + Header header = response.getFirstHeader("Sunset"); + if (header != null) { + apiVersionSunset = StringUtils.trimToNull(header.getValue()); + } else { + apiVersionSunset = null; } - }); - Header header = response.getFirstHeader("Sunset"); - if(header!=null) { - apiVersionSunset = StringUtils.trimToNull(header.getValue()); - } - else { - apiVersionSunset = null; - } - if (response.getStatusLine().getStatusCode() >= HttpStatus.SC_OK && response.getStatusLine().getStatusCode() < HttpStatus.SC_MULTIPLE_CHOICES) { - String responseString = EntityUtils.toString(response.getEntity()); - JSONObject responseJson = new JSONObject(responseString); - handle(component, responseJson); - } else if (response.getEntity() != null) { - String responseString = EntityUtils.toString(response.getEntity()); - JSONObject responseJson = new JSONObject(responseString); - final List errors = new SnykParser().parseErrors(responseJson); - if (!errors.isEmpty()) { - LOGGER.error("Analysis of component %s failed with HTTP status %d: \n%s" - .formatted(component.getPurl(), response.getStatusLine().getStatusCode(), errors.stream() - .map(error -> " - %s: %s (%s)".formatted(error.title(), error.detail(), error.code())) - .collect(Collectors.joining("\n")))); + if (response.getStatusLine().getStatusCode() >= HttpStatus.SC_OK && response.getStatusLine().getStatusCode() < HttpStatus.SC_MULTIPLE_CHOICES) { + String responseString = EntityUtils.toString(response.getEntity()); + JSONObject responseJson = new JSONObject(responseString); + handle(component, responseJson); + } else if (response.getEntity() != null) { + String responseString = EntityUtils.toString(response.getEntity()); + JSONObject responseJson = new JSONObject(responseString); + final List errors = new SnykParser().parseErrors(responseJson); + if (!errors.isEmpty()) { + LOGGER.error("Analysis of component %s failed with HTTP status %d: \n%s" + .formatted(component.getPurl(), response.getStatusLine().getStatusCode(), errors.stream() + .map(error -> " - %s: %s (%s)" .formatted(error.title(), error.detail(), error.code())) + .collect(Collectors.joining("\n")))); + } else { + handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); + } } else { handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } - } else { - handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } - }catch (IOException | URISyntaxException ex){ + } catch (IOException | URISyntaxException ex) { handleRequestException(LOGGER, ex); + } catch (Throwable ex) { + LOGGER.error("An error occurred while executing scan for coordinates" + component.getPurl().getCoordinates() + " exception: " + ex); } } @@ -398,7 +393,7 @@ private Optional getApiBaseUrl() { private Supplier createTokenSupplier(final String tokenValue) { final String[] tokens = tokenValue.split(";"); if (tokens.length > 1) { - LOGGER.debug("Will use %d tokens in round robin".formatted(tokens.length)); + LOGGER.debug("Will use %d tokens in round robin" .formatted(tokens.length)); final var roundRobinAccessor = new RoundRobinAccessor<>(List.of(tokens)); return roundRobinAccessor::get; } diff --git a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java index 24d3330152..9294eff845 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/VulnDbAnalysisTask.java @@ -33,7 +33,7 @@ import org.dependencytrack.model.VulnerabilityAnalysisLevel; import org.dependencytrack.parser.vulndb.ModelConverter; import org.dependencytrack.parser.vulndb.VulnDbClient; -import org.dependencytrack.parser.vulndb.model.Results1; +import org.dependencytrack.parser.vulndb.model.Results; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.util.NotificationUtil; @@ -146,7 +146,7 @@ public void analyze(final List components) { boolean more = true; while (more) { try { - final Results1 results = api.getVulnerabilitiesByCpe(component.getCpe(), PAGE_SIZE, page); + final Results results = api.getVulnerabilitiesByCpe(component.getCpe(), PAGE_SIZE, page); if (results.isSuccessful()) { more = processResults(results, component); page++; @@ -166,7 +166,7 @@ public void analyze(final List components) { } @SuppressWarnings("unchecked") - private boolean processResults(final Results1 results, final Component component) { + private boolean processResults(final Results results, final Component component) { try (final QueryManager qm = new QueryManager()) { final Component vulnerableComponent = qm.getObjectByUuid(Component.class, component.getUuid()); // Refresh component and attach to current pm. for (org.dependencytrack.parser.vulndb.model.Vulnerability vulnDbVuln : (List) results.getResults()) { From 9cfd5805d285e109ecc575f23b862b589d9ed656 Mon Sep 17 00:00:00 2001 From: mehab Date: Sat, 11 Feb 2023 08:25:45 +0000 Subject: [PATCH 27/31] fixed unit test Signed-off-by: mehab --- .../defectdojo/DefectDojoClientTest.java | 14 +++++++++++++- .../tasks/scanners/VulnDBAnalysisTaskTest.java | 9 ++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java b/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java index de604eb990..439a941a56 100644 --- a/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java +++ b/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java @@ -32,7 +32,12 @@ import org.mockserver.integration.ClientAndServer; import org.mockserver.verify.VerificationTimes; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; import java.net.URL; +import java.nio.charset.Charset; import static org.mockserver.integration.ClientAndServer.startClientAndServer; import static org.mockserver.model.HttpRequest.request; @@ -94,7 +99,14 @@ public void testUploadFindingsPositiveCase() throws Exception { ); DefectDojoUploader uploader = new DefectDojoUploader(); DefectDojoClient client = new DefectDojoClient(uploader, new URL("https://localhost/defectdojo")); - client.uploadDependencyTrackFindings(token, engagementId, new NullInputStream(0)); + String stringInput = "test input"; + InputStream inputStream = new ByteArrayInputStream(stringInput.getBytes((Charset.forName("UTF-8")))); + client.uploadDependencyTrackFindings(token, engagementId, inputStream); + String logMessages = mockServer + .retrieveLogMessages( + request() + ); + testClient.verify( request() .withMethod("POST") diff --git a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java index 93e6620de3..6ba0985abb 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/VulnDBAnalysisTaskTest.java @@ -54,7 +54,6 @@ import static org.dependencytrack.model.ConfigPropertyConstants.SCANNER_VULNDB_ENABLED; import static org.dependencytrack.model.ConfigPropertyConstants.SCANNER_VULNDB_OAUTH1_CONSUMER_KEY; import static org.dependencytrack.model.ConfigPropertyConstants.SCANNER_VULNDB_OAUTH1_CONSUMER_SECRET; - import static org.mockserver.model.HttpRequest.request; import static org.mockserver.model.HttpResponse.response; @@ -126,8 +125,8 @@ public void testAnalyzeWithOneIssue() { .when(request() .withMethod("GET") .withPath("/api/v1/vulnerabilities/find_by_cpe") - .withHeader(new Header("X-User-Agent", "VulnDB Data Mirror (https://github.com/stevespringett/vulndb-data-mirror)")) - .withQueryStringParameter("cpe", "cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*" )) + .withHeader(new Header("X-User-Agent", "Dependency Track (https://github.com/DependencyTrack/dependency-track)")) + .withQueryStringParameter("cpe", "cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*")) .respond(response() .withStatusCode(200) .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") @@ -250,8 +249,8 @@ public void testAnalyzeWithNoIssue() { .when(request() .withMethod("GET") .withPath("/api/v1/vulnerabilities/find_by_cpe") - .withHeader(new Header("X-User-Agent", "VulnDB Data Mirror (https://github.com/stevespringett/vulndb-data-mirror)")) - .withQueryStringParameter("cpe", "cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*" )) + .withHeader(new Header("X-User-Agent", "Dependency Track (https://github.com/DependencyTrack/dependency-track)")) + .withQueryStringParameter("cpe", "cpe:2.3:h:siemens:sppa-t3000_ses3000:-:*:*:*:*:*:*:*")) .respond(response() .withStatusCode(200) .withHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.api+json") From 58d863f38f75572aba8f60b9c3ede8ca41467197 Mon Sep 17 00:00:00 2001 From: mehab Date: Sun, 12 Feb 2023 15:35:49 +0000 Subject: [PATCH 28/31] content type found and updated for defectdojo and fortifyssc Signed-off-by: mehab --- .../integrations/defectdojo/DefectDojoClient.java | 4 ++-- .../integrations/defectdojo/DefectDojoClientTest.java | 8 +------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java index f2be0e27bc..aa11b90e4b 100644 --- a/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java +++ b/src/main/java/org/dependencytrack/integrations/defectdojo/DefectDojoClient.java @@ -58,7 +58,7 @@ public DefectDojoClient(final DefectDojoUploader uploader, final URL baseURL) { public void uploadDependencyTrackFindings(final String token, final String engagementId, final InputStream findingsJson) { LOGGER.debug("Uploading Dependency-Track findings to DefectDojo"); HttpPost request = new HttpPost(baseURL + "/api/v2/import-scan/"); - InputStreamBody inputStreamBody = new InputStreamBody(findingsJson, ContentType.DEFAULT_BINARY, "findings.json"); + InputStreamBody inputStreamBody = new InputStreamBody(findingsJson, ContentType.APPLICATION_OCTET_STREAM, "findings.json"); request.addHeader("accept", "application/json"); request.addHeader("Authorization", "Token " + token); HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE) @@ -168,7 +168,7 @@ public void reimportDependencyTrackFindings(final String token, final String eng HttpPost request = new HttpPost(baseURL + "/api/v2/reimport-scan/"); request.addHeader("accept", "application/json"); request.addHeader("Authorization", "Token " + token); - InputStreamBody inputStreamBody = new InputStreamBody(findingsJson, ContentType.DEFAULT_BINARY, "findings.json"); + InputStreamBody inputStreamBody = new InputStreamBody(findingsJson, ContentType.APPLICATION_OCTET_STREAM, "findings.json"); HttpEntity fileData = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE) .addPart("file", inputStreamBody) .addPart("engagement", new StringBody(engagementId, ContentType.MULTIPART_FORM_DATA)) diff --git a/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java b/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java index 439a941a56..f64f3814e7 100644 --- a/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java +++ b/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java @@ -99,13 +99,7 @@ public void testUploadFindingsPositiveCase() throws Exception { ); DefectDojoUploader uploader = new DefectDojoUploader(); DefectDojoClient client = new DefectDojoClient(uploader, new URL("https://localhost/defectdojo")); - String stringInput = "test input"; - InputStream inputStream = new ByteArrayInputStream(stringInput.getBytes((Charset.forName("UTF-8")))); - client.uploadDependencyTrackFindings(token, engagementId, inputStream); - String logMessages = mockServer - .retrieveLogMessages( - request() - ); + client.uploadDependencyTrackFindings(token, engagementId, new NullInputStream(0)); testClient.verify( request() From e2c6eee33b46837217df765eba2b12c4c9df23f1 Mon Sep 17 00:00:00 2001 From: mehab Date: Sun, 12 Feb 2023 15:47:54 +0000 Subject: [PATCH 29/31] resolved merged error Signed-off-by: mehab --- .../dependencytrack/policy/PolicyEngineTest.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/test/java/org/dependencytrack/policy/PolicyEngineTest.java b/src/test/java/org/dependencytrack/policy/PolicyEngineTest.java index 97d30510c8..d4f4850121 100644 --- a/src/test/java/org/dependencytrack/policy/PolicyEngineTest.java +++ b/src/test/java/org/dependencytrack/policy/PolicyEngineTest.java @@ -19,14 +19,16 @@ package org.dependencytrack.policy; import org.dependencytrack.PersistenceCapableTest; -import org.dependencytrack.model.Tag; +import org.dependencytrack.model.Component; +import org.dependencytrack.model.License; +import org.dependencytrack.model.LicenseGroup; import org.dependencytrack.model.Policy; -import org.dependencytrack.model.Severity; +import org.dependencytrack.model.PolicyCondition; +import org.dependencytrack.model.PolicyViolation; import org.dependencytrack.model.Project; -import org.dependencytrack.model.Component; +import org.dependencytrack.model.Severity; +import org.dependencytrack.model.Tag; import org.dependencytrack.model.Vulnerability; -import org.dependencytrack.model.PolicyViolation; -import org.dependencytrack.model.PolicyCondition; import org.dependencytrack.tasks.scanners.AnalyzerIdentity; import org.junit.Assert; import org.junit.Test; @@ -35,6 +37,7 @@ import java.util.Collections; import java.util.List; import java.util.UUID; + public class PolicyEngineTest extends PersistenceCapableTest { @Test From 1c1b1d322b9fb1a1189112c88f689e425855af17 Mon Sep 17 00:00:00 2001 From: mehab Date: Mon, 13 Feb 2023 13:01:26 +0000 Subject: [PATCH 30/31] added tests with wiremock Signed-off-by: mehab --- pom.xml | 9 + .../fortifyssc/FortifySscClient.java | 2 +- .../publisher/AbstractWebhookPublisher.java | 2 +- .../repositories/AbstractMetaAnalyzer.java | 2 +- .../scanners/BaseComponentAnalyzerTask.java | 2 +- .../tasks/scanners/OssIndexAnalysisTask.java | 2 +- .../tasks/scanners/SnykAnalysisTask.java | 4 +- .../defectdojo/DefectDojoClientTest.java | 171 +++++------------- .../fortifyssc/FortifySscClientTest.java | 149 ++++++--------- 9 files changed, 112 insertions(+), 231 deletions(-) diff --git a/pom.xml b/pom.xml index e636ca62d7..cee76b4cf2 100644 --- a/pom.xml +++ b/pom.xml @@ -349,7 +349,16 @@ mockito-core ${lib.mockito.version} test + + + + com.github.tomakehurst + wiremock-jre8 + 2.35.0 + test + + com.github.stefanbirkner system-rules diff --git a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java index 01b0da0c18..939e8f176e 100644 --- a/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java +++ b/src/main/java/org/dependencytrack/integrations/fortifyssc/FortifySscClient.java @@ -84,7 +84,7 @@ public void uploadDependencyTrackFindings(final String token, final String appli HttpPost request = new HttpPost(builder.build()); request.addHeader("accept", "application/xml"); HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE) - .addBinaryBody("files[]", findingsJson, ContentType.APPLICATION_JSON, "findings.json") + .addBinaryBody("files[]", findingsJson, ContentType.APPLICATION_OCTET_STREAM, "findings.json") .build(); request.setEntity(data); try (CloseableHttpResponse response = HttpClientPool.getClient().execute(request)) { diff --git a/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java b/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java index 878749145d..be80253cd5 100644 --- a/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java +++ b/src/main/java/org/dependencytrack/notification/publisher/AbstractWebhookPublisher.java @@ -35,7 +35,7 @@ public abstract class AbstractWebhookPublisher implements Publisher { public void publish(final String publisherName, final PebbleTemplate template, final Notification notification, final JsonObject config) { - final Logger logger = LoggerFactory.getLogger(AbstractWebhookPublisher.class); + final Logger logger = LoggerFactory.getLogger(getClass()); logger.debug("Preparing to publish " + publisherName + " notification"); if (config == null) { logger.warn("No configuration found. Skipping notification."); diff --git a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java index 4755cbb36c..5e0cee6ec2 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java @@ -93,7 +93,7 @@ protected void handleRequestException(final Logger logger, final Exception e) { } protected CloseableHttpResponse processHttpRequest(String url) throws IOException { - final Logger logger = Logger.getLogger(AbstractMetaAnalyzer.class); + final Logger logger = Logger.getLogger(getClass()); try { URIBuilder uriBuilder = new URIBuilder(url); final HttpUriRequest request = new HttpGet(uriBuilder.build().toString()); diff --git a/src/main/java/org/dependencytrack/tasks/scanners/BaseComponentAnalyzerTask.java b/src/main/java/org/dependencytrack/tasks/scanners/BaseComponentAnalyzerTask.java index 65c9156025..bf8ca516a2 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/BaseComponentAnalyzerTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/BaseComponentAnalyzerTask.java @@ -147,7 +147,7 @@ protected void handleUnexpectedHttpResponse(final Logger logger, String url, fin ); } - protected void handleRequestException(final Logger logger, final Exception e) { + protected void handleRequestException(final Logger logger, final Throwable e) { logger.error("Request failure", e); Notification.dispatch(new Notification() .scope(NotificationScope.SYSTEM) diff --git a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java index 02b26f1d2a..2f10f1dd3e 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/OssIndexAnalysisTask.java @@ -209,7 +209,7 @@ public void analyze(final List components) { final List report = ossIndexRetryer.executeCheckedSupplier(() -> submit(json)); processResults(report, paginatedList); } catch (Throwable ex) { - LOGGER.error("An error occurred while executing scan for coordinates" + json + " exception: " + ex); + handleRequestException(LOGGER, ex); return; } diff --git a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java index d0eae4549b..47a1dc00e0 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java @@ -333,10 +333,8 @@ private void analyzeComponent(final Component component) { handleUnexpectedHttpResponse(LOGGER, request.getURI().toString(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); } } - } catch (IOException | URISyntaxException ex) { + } catch (Throwable ex) { handleRequestException(LOGGER, ex); - } catch (Throwable ex) { - LOGGER.error("An error occurred while executing scan for coordinates" + component.getPurl().getCoordinates() + " exception: " + ex); } } diff --git a/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java b/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java index f64f3814e7..590854e299 100644 --- a/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java +++ b/src/test/java/org/dependencytrack/integrations/defectdojo/DefectDojoClientTest.java @@ -18,122 +18,60 @@ */ package org.dependencytrack.integrations.defectdojo; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import com.github.tomakehurst.wiremock.matching.EqualToPattern; import org.apache.commons.io.input.NullInputStream; import org.apache.http.HttpHeaders; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; +import org.apache.http.entity.ContentType; import org.junit.Rule; import org.junit.Test; -import org.junit.contrib.java.lang.system.EnvironmentVariables; -import org.junit.rules.ExpectedException; -import org.mockserver.client.MockServerClient; -import org.mockserver.integration.ClientAndServer; -import org.mockserver.verify.VerificationTimes; import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; import java.io.InputStream; import java.net.URL; -import java.nio.charset.Charset; - -import static org.mockserver.integration.ClientAndServer.startClientAndServer; -import static org.mockserver.model.HttpRequest.request; -import static org.mockserver.model.HttpResponse.response; public class DefectDojoClientTest { - private static ClientAndServer mockServer; - private static MockServerClient testClient; - - @Rule - public final EnvironmentVariables environmentVariables = new EnvironmentVariables(); - @Rule - public ExpectedException thrown = ExpectedException.none(); + public WireMockRule wireMockRule = new WireMockRule(); - @Before - public void before() { - environmentVariables.set("http_proxy", "http://127.0.0.1:1080"); - testClient = new MockServerClient("localhost", 1080); - } - - @After - public void after() { - testClient.clear( - request() - .withPath("/defectdojo/api/v2/import-scan/") - ); - testClient.clear( - request() - .withPath("/defectdojo/api/v2/reimport-scan/") - ); - } - - @BeforeClass - public static void beforeClass() { - mockServer = startClientAndServer(1080); - } - - @AfterClass - public static void afterClass() { - mockServer.stop(); - } @Test public void testUploadFindingsPositiveCase() throws Exception { + WireMock.stubFor(WireMock.post(WireMock.urlPathEqualTo("/defectdojo/api/v2/import-scan/")) + .withMultipartRequestBody(WireMock.aMultipart().withName("engagement"). + withBody(WireMock.equalTo("12345")))); + InputStream stream = new ByteArrayInputStream("test input" .getBytes()); String token = "db975c97-98b1-4988-8d6a-9c3e044dfff3"; String engagementId = "12345"; - testClient.when( - request() - .withMethod("POST") - .withHeader(HttpHeaders.AUTHORIZATION, "Token " + token) - .withPath("/defectdojo/api/v2/import-scan/") - ) - .respond( - response() - .withStatusCode(201) - .withHeader(HttpHeaders.CONTENT_TYPE, "application/json") - ); DefectDojoUploader uploader = new DefectDojoUploader(); - DefectDojoClient client = new DefectDojoClient(uploader, new URL("https://localhost/defectdojo")); - client.uploadDependencyTrackFindings(token, engagementId, new NullInputStream(0)); - - testClient.verify( - request() - .withMethod("POST") - .withPath("/defectdojo/api/v2/import-scan/"), - VerificationTimes.exactly(1) - ); + DefectDojoClient client = new DefectDojoClient(uploader, new URL(wireMockRule.baseUrl() + "/defectdojo")); + client.uploadDependencyTrackFindings(token, engagementId, stream); + + WireMock.verify(WireMock.postRequestedFor(WireMock.urlPathEqualTo("/defectdojo/api/v2/import-scan/")) + .withAnyRequestBodyPart(WireMock.aMultipart().withName("engagement"). + withBody(WireMock.equalTo("12345") + )).withAnyRequestBodyPart(WireMock.aMultipart().withName("file") + .withBody(WireMock.equalTo("test input")).withHeader("Content-Type", WireMock.equalTo(ContentType.APPLICATION_OCTET_STREAM.getMimeType())))); } + @Test public void testUploadFindingsNegativeCase() throws Exception { String token = "db975c97-98b1-4988-8d6a-9c3e044dfff2"; String engagementId = ""; - testClient.when( - request() - .withMethod("POST") - .withHeader(HttpHeaders.AUTHORIZATION, "Token " + token) - .withPath("/defectdojo/api/v2/import-scan/") - ) - .respond( - response() - .withStatusCode(400) - .withHeader(HttpHeaders.CONTENT_TYPE, "application/json") - ); + WireMock.stubFor(WireMock.post(WireMock.urlPathEqualTo("/defectdojo/api/v2/import-scan/")) + .withHeader(HttpHeaders.AUTHORIZATION, new EqualToPattern("Token " + token)) + .withMultipartRequestBody(WireMock.aMultipart().withName("engagement"). + withBody(WireMock.equalTo(""))).willReturn(WireMock.aResponse().withStatus(400).withHeader(HttpHeaders.CONTENT_TYPE, "application/json"))); DefectDojoUploader uploader = new DefectDojoUploader(); - DefectDojoClient client = new DefectDojoClient(uploader, new URL("https://localhost/defectdojo")); + DefectDojoClient client = new DefectDojoClient(uploader, new URL(wireMockRule.baseUrl() + "/defectdojo")); client.uploadDependencyTrackFindings(token, engagementId, new NullInputStream(16)); - testClient.verify( - request() - .withMethod("POST") - .withHeader(HttpHeaders.AUTHORIZATION, "Token " + token) - .withPath("/defectdojo/api/v2/import-scan/"), - VerificationTimes.exactly(1) - ); + WireMock.verify(WireMock.postRequestedFor(WireMock.urlPathEqualTo("/defectdojo/api/v2/import-scan/")) + .withAnyRequestBodyPart(WireMock.aMultipart().withName("engagement"). + withBody(WireMock.equalTo("") + ))); } @Test @@ -141,26 +79,17 @@ public void testReimportFindingsPositiveCase() throws Exception { String token = "db975c97-98b1-4988-8d6a-9c3e044dfff3"; String testId = "15"; String engagementId = "67890"; - testClient.when( - request() - .withMethod("POST") - .withHeader(HttpHeaders.AUTHORIZATION, "Token " + token) - .withPath("/defectdojo/api/v2/reimport-scan/") - ) - .respond( - response() - .withStatusCode(201) - .withHeader(HttpHeaders.CONTENT_TYPE, "application/json") - ); + WireMock.stubFor(WireMock.post(WireMock.urlPathEqualTo("/defectdojo/api/v2/reimport-scan/")) + .withHeader(HttpHeaders.AUTHORIZATION, new EqualToPattern("Token " + token)) + .withMultipartRequestBody(WireMock.aMultipart().withName("engagement"). + withBody(WireMock.equalTo(engagementId))).willReturn(WireMock.aResponse().withStatus(201).withHeader(HttpHeaders.CONTENT_TYPE, "application/json"))); DefectDojoUploader uploader = new DefectDojoUploader(); - DefectDojoClient client = new DefectDojoClient(uploader, new URL("https://localhost/defectdojo")); + DefectDojoClient client = new DefectDojoClient(uploader, new URL(wireMockRule.baseUrl() + "/defectdojo")); client.reimportDependencyTrackFindings(token, engagementId, new NullInputStream(0), testId); - testClient.verify( - request() - .withMethod("POST") - .withPath("/defectdojo/api/v2/reimport-scan/"), - VerificationTimes.exactly(1) - ); + WireMock.verify(WireMock.postRequestedFor(WireMock.urlPathEqualTo("/defectdojo/api/v2/reimport-scan/")) + .withAnyRequestBodyPart(WireMock.aMultipart().withName("engagement"). + withBody(WireMock.equalTo(engagementId) + ))); } @Test @@ -168,26 +97,16 @@ public void testReimportFindingsNegativeCase() throws Exception { String token = "db975c97-98b1-4988-8d6a-9c3e044dfff2"; String testId = "14"; String engagementId = ""; - testClient.when( - request() - .withMethod("POST") - .withHeader(HttpHeaders.AUTHORIZATION, "Token " + token) - .withPath("/defectdojo/api/v2/reimport-scan/") - ) - .respond( - response() - .withStatusCode(400) - .withHeader(HttpHeaders.CONTENT_TYPE, "application/json") - ); + WireMock.stubFor(WireMock.post(WireMock.urlPathEqualTo("/defectdojo/api/v2/reimport-scan/")) + .withHeader(HttpHeaders.AUTHORIZATION, new EqualToPattern("Token " + token)) + .withMultipartRequestBody(WireMock.aMultipart().withName("engagement"). + withBody(WireMock.equalTo(""))).willReturn(WireMock.aResponse().withStatus(400).withHeader(HttpHeaders.CONTENT_TYPE, "application/json"))); DefectDojoUploader uploader = new DefectDojoUploader(); - DefectDojoClient client = new DefectDojoClient(uploader, new URL("https://localhost/defectdojo")); + DefectDojoClient client = new DefectDojoClient(uploader, new URL(wireMockRule.baseUrl() + "/defectdojo")); client.reimportDependencyTrackFindings(token, engagementId, new NullInputStream(16), testId); - testClient.verify( - request() - .withMethod("POST") - .withHeader(HttpHeaders.AUTHORIZATION, "Token " + token) - .withPath("/defectdojo/api/v2/reimport-scan/"), - VerificationTimes.exactly(1) - ); + WireMock.verify(WireMock.postRequestedFor(WireMock.urlPathEqualTo("/defectdojo/api/v2/reimport-scan/")) + .withAnyRequestBodyPart(WireMock.aMultipart().withName("engagement"). + withBody(WireMock.equalTo(engagementId) + ))); } } diff --git a/src/test/java/org/dependencytrack/integrations/fortifyssc/FortifySscClientTest.java b/src/test/java/org/dependencytrack/integrations/fortifyssc/FortifySscClientTest.java index 53fe710b18..b67f2d71b9 100644 --- a/src/test/java/org/dependencytrack/integrations/fortifyssc/FortifySscClientTest.java +++ b/src/test/java/org/dependencytrack/integrations/fortifyssc/FortifySscClientTest.java @@ -18,90 +18,48 @@ */ package org.dependencytrack.integrations.fortifyssc; -import org.apache.commons.io.input.NullInputStream; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import com.github.tomakehurst.wiremock.matching.EqualToPattern; import org.apache.http.HttpHeaders; -import org.junit.AfterClass; +import org.apache.http.entity.ContentType; import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; -import org.junit.contrib.java.lang.system.EnvironmentVariables; -import org.junit.rules.ExpectedException; -import org.mockserver.client.MockServerClient; -import org.mockserver.integration.ClientAndServer; +import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Base64; -import static org.mockserver.integration.ClientAndServer.startClientAndServer; -import static org.mockserver.model.HttpRequest.request; -import static org.mockserver.model.HttpResponse.response; - public class FortifySscClientTest { - private static ClientAndServer mockServer; - - @Rule - public final EnvironmentVariables environmentVariables = new EnvironmentVariables(); - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Before - public void before() { - environmentVariables.set("http_proxy", "http://127.0.0.1:1080"); - } - - @BeforeClass - public static void beforeClass() { - mockServer = startClientAndServer(1080); - } + public WireMockRule wireMockRule = new WireMockRule(); - @AfterClass - public static void after() { - mockServer.stop(); - } @Test public void testOneTimeTokenPositiveCase() throws Exception { - new MockServerClient("localhost", 1080) - .when( - request() - .withMethod("POST") - .withHeader(HttpHeaders.AUTHORIZATION, "FortifyToken " + Base64.getEncoder().encodeToString("2d5e4a06-945e-405f-a3c2-112bb3053453".getBytes(StandardCharsets.UTF_8))) - .withPath("/ssc/api/v1/fileTokens") - .withBody("{\"fileTokenType\":\"UPLOAD\"}") - ) - .respond( - response() - .withStatusCode(201) - .withHeader(HttpHeaders.CONTENT_TYPE, "application/json") - .withBody("{ \"data\": { \"token\": \"db975c97-98b1-4988-8d6a-9c3e044dfff3\" }}") - ); + WireMock.stubFor(WireMock.post(WireMock.urlPathEqualTo("/ssc/api/v1/fileTokens")) + .withHeader(HttpHeaders.AUTHORIZATION, new EqualToPattern("FortifyToken " + Base64.getEncoder().encodeToString("2d5e4a06-945e-405f-a3c2-112bb3053453" .getBytes(StandardCharsets.UTF_8)))) + .withRequestBody(WireMock.equalToJson("{\"fileTokenType\":\"UPLOAD\"}")) + .willReturn(WireMock.aResponse().withHeader(HttpHeaders.CONTENT_TYPE, "application/json") + .withBody("{ \"data\": { \"token\": \"db975c97-98b1-4988-8d6a-9c3e044dfff3\" }}").withStatus(201))); FortifySscUploader uploader = new FortifySscUploader(); - FortifySscClient client = new FortifySscClient(uploader, new URL("https://localhost/ssc")); + FortifySscClient client = new FortifySscClient(uploader, new URL(wireMockRule.baseUrl() + "/ssc")); String token = client.generateOneTimeUploadToken("2d5e4a06-945e-405f-a3c2-112bb3053453"); Assert.assertEquals("db975c97-98b1-4988-8d6a-9c3e044dfff3", token); } @Test public void testOneTimeTokenInvalidCredentials() throws Exception { - new MockServerClient("localhost", 1080) - .when( - request() - .withMethod("POST") - .withHeader(HttpHeaders.AUTHORIZATION, "FortifyToken " + Base64.getEncoder().encodeToString("wrong".getBytes(StandardCharsets.UTF_8))) - .withPath("/ssc/api/v1/fileTokens") - .withBody("{\"fileTokenType\":\"UPLOAD\"}") - ) - .respond( - response() - .withStatusCode(401) - ); + WireMock.stubFor(WireMock.post(WireMock.urlPathEqualTo("/ssc/api/v1/fileTokens")) + .withHeader(HttpHeaders.AUTHORIZATION, new EqualToPattern("FortifyToken " + Base64.getEncoder().encodeToString("wrong" .getBytes(StandardCharsets.UTF_8)))) + .withRequestBody(WireMock.equalToJson("{\"fileTokenType\":\"UPLOAD\"}")) + .willReturn(WireMock.aResponse().withHeader(HttpHeaders.CONTENT_TYPE, "application/json").withStatus(401))); FortifySscUploader uploader = new FortifySscUploader(); - FortifySscClient client = new FortifySscClient(uploader, new URL("https://localhost/ssc")); + FortifySscClient client = new FortifySscClient(uploader, new URL(wireMockRule.baseUrl() + "/ssc")); String token = client.generateOneTimeUploadToken("wrong"); Assert.assertNull(token); } @@ -110,50 +68,47 @@ public void testOneTimeTokenInvalidCredentials() throws Exception { public void testUploadFindingsPositiveCase() throws Exception { String token = "db975c97-98b1-4988-8d6a-9c3e044dfff3"; String applicationVersion = "12345"; - new MockServerClient("localhost", 1080) - .when( - request() - .withMethod("POST") - .withHeader(HttpHeaders.ACCEPT, "application/xml") - .withPath("/ssc/upload/resultFileUpload.html?mat=" + token + "&engineType=DEPENDENCY_TRACK&entityId=" + applicationVersion) - .withQueryStringParameter("engineType", "DEPENDENCY_TRACK") - .withQueryStringParameter("mat", token) - .withQueryStringParameter("entityId", applicationVersion) - ) - .respond( - response() - .withStatusCode(200) - .withHeader(HttpHeaders.CONTENT_TYPE, "application/xml") - ); + WireMock.stubFor(WireMock.post(WireMock.urlPathEqualTo("/ssc/upload/resultFileUpload.html")) + .withHeader(HttpHeaders.ACCEPT, new EqualToPattern("application/xml")) + .withQueryParam("engineType", new EqualToPattern("DEPENDENCY_TRACK")) + .withQueryParam("mat", new EqualToPattern(token)) + .withQueryParam("entityId", new EqualToPattern(applicationVersion)) + .willReturn(WireMock.aResponse().withHeader(HttpHeaders.CONTENT_TYPE, "application/xml").withStatus(200))); FortifySscUploader uploader = new FortifySscUploader(); - FortifySscClient client = new FortifySscClient(uploader, new URL("https://localhost/ssc")); - client.uploadDependencyTrackFindings(token, applicationVersion, new NullInputStream(0)); + FortifySscClient client = new FortifySscClient(uploader, new URL(wireMockRule.baseUrl() + "/ssc")); + InputStream stream = new ByteArrayInputStream("test input" .getBytes()); + client.uploadDependencyTrackFindings(token, applicationVersion, stream); + + WireMock.verify(WireMock.postRequestedFor(WireMock.urlPathEqualTo("/ssc/upload/resultFileUpload.html")) + .withQueryParam("engineType", new EqualToPattern("DEPENDENCY_TRACK")) + .withQueryParam("mat", new EqualToPattern(token)) + .withQueryParam("entityId", new EqualToPattern(applicationVersion)) + .withAnyRequestBodyPart(WireMock.aMultipart().withName("files[]") + .withBody(WireMock.equalTo("test input")).withHeader("Content-Type", WireMock.equalTo(ContentType.APPLICATION_OCTET_STREAM.getMimeType())))); } @Test public void testUploadFindingsNegativeCase() throws Exception { String token = "db975c97-98b1-4988-8d6a-9c3e044dfff3"; String applicationVersion = ""; - new MockServerClient("localhost", 1080) - .when( - request() - .withMethod("POST") - .withHeader(HttpHeaders.ACCEPT, "application/xml") - .withPath("/ssc/upload/resultFileUpload.html?mat=" + token + "&engineType=DEPENDENCY_TRACK&entityId=" + applicationVersion) - .withQueryStringParameter("engineType", "DEPENDENCY_TRACK") - .withQueryStringParameter("mat", token) - .withQueryStringParameter("entityId", applicationVersion) - ) - .respond( - response() - .withStatusCode(400) - .withHeader(HttpHeaders.CONTENT_TYPE, "application/xml") - ); + + WireMock.stubFor(WireMock.post(WireMock.urlPathEqualTo("/ssc/upload/resultFileUpload.html")) + .withHeader(HttpHeaders.ACCEPT, new EqualToPattern("application/xml")) + .withQueryParam("engineType", new EqualToPattern("DEPENDENCY_TRACK")) + .withQueryParam("mat", new EqualToPattern(token)) + .withQueryParam("entityId", new EqualToPattern(applicationVersion)) + .willReturn(WireMock.aResponse().withHeader(HttpHeaders.CONTENT_TYPE, "application/xml").withStatus(400))); FortifySscUploader uploader = new FortifySscUploader(); - FortifySscClient client = new FortifySscClient(uploader, new URL("https://localhost/ssc")); - client.uploadDependencyTrackFindings(token, applicationVersion, new NullInputStream(16)); + FortifySscClient client = new FortifySscClient(uploader, new URL(wireMockRule.baseUrl() + "/ssc")); + InputStream stream = new ByteArrayInputStream("test input" .getBytes()); + client.uploadDependencyTrackFindings(token, applicationVersion, stream); + + WireMock.verify(WireMock.postRequestedFor(WireMock.urlPathEqualTo("/ssc/upload/resultFileUpload.html")) + .withQueryParam("engineType", new EqualToPattern("DEPENDENCY_TRACK")) + .withQueryParam("mat", new EqualToPattern(token)) + .withQueryParam("entityId", new EqualToPattern(applicationVersion)) + .withAnyRequestBodyPart(WireMock.aMultipart().withName("files[]") + .withBody(WireMock.equalTo("test input")).withHeader("Content-Type", WireMock.equalTo(ContentType.APPLICATION_OCTET_STREAM.getMimeType())))); + } } - -//another test to write: -// request in the current master \ No newline at end of file From 38b3115879defd7247586ff8c332d908db3d6918 Mon Sep 17 00:00:00 2001 From: mehab Date: Mon, 13 Feb 2023 13:04:18 +0000 Subject: [PATCH 31/31] added tests with wiremock Signed-off-by: mehab --- .../org/dependencytrack/tasks/scanners/SnykAnalysisTask.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java index 47a1dc00e0..7ccb7a99d4 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/SnykAnalysisTask.java @@ -63,8 +63,6 @@ import org.json.JSONArray; import org.json.JSONObject; -import java.io.IOException; -import java.net.URISyntaxException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.Duration;