From 140a01e53a7b0e178c550cf5f8a5dfe5f7d59217 Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Mon, 6 Jul 2026 12:32:04 +0200 Subject: [PATCH 01/10] fix(trustify): merge remediation data across purl_statuses with advisory attribution (TC-5019) Fix first-wins deduplication bug in TrustifyResponseHandler.toIssues() that dropped remediation data when multiple purl_statuses existed for the same CVE. When the same source:cveId key is encountered again, mergeIssueData() now accumulates fixedIn versions (deduped), adds RemediationInfo entries, and retains the highest CVSS score. Populate the new AdvisoryInfo field on each RemediationInfo using advisory data from Trustify v3 (document_id, title, identifier URL). Set RemediationCategory to VENDOR_FIX when fixed versions exist. Bump trustify-da-api-model to 2.0.11-SNAPSHOT which includes AdvisoryInfo, updated RemediationInfo with advisory field, and RemediationCategory. Co-Authored-By: Claude Opus 4.6 --- pom.xml | 2 +- .../trustify/TrustifyResponseHandler.java | 169 ++++++++++ .../trustify/TrustifyResponseHandlerTest.java | 290 ++++++++++++++++++ 3 files changed, 460 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 35b0c524..d1705f6d 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 3.1.1 - 2.0.10 + 2.0.11 11.0.1 7.8.0 2.0.2 diff --git a/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java b/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java index 4067474d..22f4d812 100644 --- a/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java +++ b/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java @@ -18,6 +18,7 @@ package io.github.guacsec.trustifyda.integration.providers.trustify; import java.io.IOException; +import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -34,6 +35,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import io.github.guacsec.trustifyda.api.PackageRef; +import io.github.guacsec.trustifyda.api.v5.AdvisoryInfo; import io.github.guacsec.trustifyda.api.v5.Issue; import io.github.guacsec.trustifyda.api.v5.Remediation; import io.github.guacsec.trustifyda.api.v5.RemediationCategory; @@ -131,6 +133,7 @@ private List toIssues(JsonNode response) { } var key = String.format("%s:%s", source, id); if (issuesByCveSource.containsKey(key)) { + mergeIssueData(issuesByCveSource.get(key), vuln, purlStatus); return; } var issue = new Issue().id(id).title(iTitle).source(source).cves(List.of(id)); @@ -230,6 +233,7 @@ private void setCvssData(Issue issue, JsonNode vuln, JsonNode purlStatus) { } var remediations = (ArrayNode) purlStatus.get("remediations"); + var advisoryInfo = buildAdvisoryInfo(purlStatus); if (remediations != null && !remediations.isEmpty()) { remediations.forEach( rem -> { @@ -250,9 +254,20 @@ private void setCvssData(Issue issue, JsonNode vuln, JsonNode purlStatus) { if (url != null) { info.url(url); } + if (advisoryInfo != null) { + info.advisory(advisoryInfo); + } r.addRemediationsItem(info); }); hasRemediation = true; + } else { + var info = + buildRemediationInfo( + purlStatus, r.getFixedIn() != null && !r.getFixedIn().isEmpty()); + if (info != null) { + r.addRemediationsItem(info); + hasRemediation = true; + } } if (hasRemediation) { @@ -260,6 +275,160 @@ private void setCvssData(Issue issue, JsonNode vuln, JsonNode purlStatus) { } } + private void mergeIssueData(Issue existing, JsonNode vuln, JsonNode purlStatus) { + Float score = null; + String severity = null; + + var baseScore = vuln.get("base_score"); + if (baseScore != null && !baseScore.isNull()) { + score = baseScore.has("score") ? (float) baseScore.get("score").asDouble() : null; + severity = JsonUtils.getTextValue(baseScore, "severity"); + } + + if (score == null) { + var scores = purlStatus.get("scores"); + if (scores != null && scores.isArray() && !scores.isEmpty()) { + for (var entry : scores) { + var entryValue = entry.has("value") ? (float) entry.get("value").asDouble() : null; + if (entryValue != null && (score == null || entryValue > score)) { + score = entryValue; + severity = JsonUtils.getTextValue(entry, "severity"); + } + } + } + } + + if (score != null + && (existing.getCvssScore() == null || score > existing.getCvssScore())) { + existing.cvssScore(score); + if (severity != null) { + try { + existing.setSeverity(SeverityUtils.fromValue(severity.toUpperCase())); + } catch (IllegalArgumentException e) { + existing.setSeverity(SeverityUtils.fromScore(score)); + } + } else { + existing.setSeverity(SeverityUtils.fromScore(score)); + } + } + + var r = ensureRemediation(existing); + + var versionRange = purlStatus.get("version_range"); + if (versionRange != null && !versionRange.isNull()) { + var vr = new VersionRange(); + var schemeId = JsonUtils.getTextValue(versionRange, "version_scheme_id"); + if (schemeId != null) { + vr.versionSchemeId(schemeId); + } + var lowVersion = JsonUtils.getTextValue(versionRange, "low_version"); + if (lowVersion != null) { + vr.lowVersion(lowVersion); + } + var lowInclusive = JsonUtils.getBooleanValue(versionRange, "low_inclusive"); + if (lowInclusive != null) { + vr.lowInclusive(lowInclusive); + } + var highVersion = JsonUtils.getTextValue(versionRange, "high_version"); + var highInclusive = JsonUtils.getBooleanValue(versionRange, "high_inclusive"); + if (highVersion != null) { + vr.highVersion(highVersion); + if (highInclusive == null || !highInclusive) { + var fixedIn = r.getFixedIn(); + if (fixedIn == null || !fixedIn.contains(highVersion)) { + r.addFixedInItem(highVersion); + } + } + } + if (highInclusive != null) { + vr.highInclusive(highInclusive); + } + r.addVersionRangesItem(vr); + } + + var remediations = (ArrayNode) purlStatus.get("remediations"); + var advisoryInfo = buildAdvisoryInfo(purlStatus); + if (remediations != null && !remediations.isEmpty()) { + remediations.forEach( + rem -> { + var info = new RemediationInfo(); + var category = JsonUtils.getTextValue(rem, "category"); + if (category != null) { + try { + info.category(RemediationCategory.fromValue(category.toUpperCase())); + } catch (IllegalArgumentException e) { + LOGGER.infof("Unknown remediation category: %s", category); + } + } + var details = JsonUtils.getTextValue(rem, "details"); + if (details != null) { + info.details(details); + } + var url = JsonUtils.getTextValue(rem, "url"); + if (url != null) { + info.url(url); + } + if (advisoryInfo != null) { + info.advisory(advisoryInfo); + } + r.addRemediationsItem(info); + }); + } else { + var info = + buildRemediationInfo( + purlStatus, r.getFixedIn() != null && !r.getFixedIn().isEmpty()); + if (info != null) { + r.addRemediationsItem(info); + } + } + } + + private Remediation ensureRemediation(Issue issue) { + var r = issue.getRemediation(); + if (r == null) { + r = new Remediation(); + issue.setRemediation(r); + } + return r; + } + + private AdvisoryInfo buildAdvisoryInfo(JsonNode purlStatus) { + var advisory = purlStatus.get("advisory"); + if (advisory == null) { + return null; + } + var documentId = JsonUtils.getTextValue(advisory, "document_id"); + if (documentId == null) { + return null; + } + var info = new AdvisoryInfo().id(documentId); + var title = JsonUtils.getTextValue(advisory, "title"); + if (title != null) { + info.title(title); + } + var identifier = JsonUtils.getTextValue(advisory, "identifier"); + if (identifier != null) { + try { + info.url(URI.create(identifier)); + } catch (IllegalArgumentException e) { + LOGGER.infof("Invalid advisory URL: %s", identifier); + } + } + return info; + } + + private RemediationInfo buildRemediationInfo(JsonNode purlStatus, boolean hasFixedVersions) { + var advisoryInfo = buildAdvisoryInfo(purlStatus); + if (advisoryInfo == null) { + return null; + } + var info = new RemediationInfo().advisory(advisoryInfo); + if (hasFixedVersions) { + info.category(RemediationCategory.VENDOR_FIX); + } + return info; + } + private String getSource(JsonNode purlStatus) { var advisory = purlStatus.get("advisory"); if (advisory == null) { diff --git a/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java b/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java index 161adb2f..bf0a9be3 100644 --- a/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java +++ b/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java @@ -49,6 +49,7 @@ import io.github.guacsec.trustifyda.api.PackageRef; import io.github.guacsec.trustifyda.api.v5.Issue; import io.github.guacsec.trustifyda.api.v5.RemediationCategory; +import io.github.guacsec.trustifyda.api.v5.RemediationInfo; import io.github.guacsec.trustifyda.api.v5.Severity; import io.github.guacsec.trustifyda.integration.Constants; import io.github.guacsec.trustifyda.integration.providers.trustify.ubi.UBIRecommendation; @@ -1807,4 +1808,293 @@ void testResponseToIssuesSameCveDifferentSources() throws IOException { assertTrue(issues.stream().anyMatch(i -> "Red Hat Product Security".equals(i.getSource()))); assertTrue(issues.stream().anyMatch(i -> "GitHub".equals(i.getSource()))); } + + @Test + void testResponseToIssuesMergesRemediationsAcrossAffected() throws IOException { + String jsonResponse = + """ + { + "pkg:maven/org.postgresql/postgresql@42.5.0": { + "details": [ + { + "identifier": "CVE-2024-1597", + "title": "SQL Injection in PostgreSQL JDBC", + "description": "SQL injection vulnerability", + "base_score": { + "score": 9.8, + "severity": "CRITICAL" + }, + "purl_statuses": [ + { + "advisory": { + "id": "adv-1", + "document_id": "RHSA-2024:1234", + "title": "Red Hat Security Advisory", + "identifier": "https://access.redhat.com/errata/RHSA-2024:1234", + "issuer": { + "id": "issuer-1", + "name": "redhat-csaf" + } + }, + "status": "affected", + "version_range": { + "version_scheme_id": "semver", + "low_version": "0", + "low_inclusive": true, + "high_version": "42.5.5", + "high_inclusive": false + }, + "remediations": [], + "scores": [ + { + "source": "cve", + "value": 9.8, + "severity": "critical" + } + ] + }, + { + "advisory": { + "id": "adv-2", + "document_id": "RHSA-2024:5678", + "title": "Red Hat Security Advisory 2", + "identifier": "https://access.redhat.com/errata/RHSA-2024:5678", + "issuer": { + "id": "issuer-1", + "name": "redhat-csaf" + } + }, + "status": "affected", + "version_range": { + "version_scheme_id": "semver", + "low_version": "0", + "low_inclusive": true, + "high_version": "42.6.1", + "high_inclusive": false + }, + "remediations": [], + "scores": [ + { + "source": "cve", + "value": 9.8, + "severity": "critical" + } + ] + } + ] + } + ], + "warnings": [] + } + } + """; + + byte[] responseBytes = jsonResponse.getBytes(); + ProviderResponse result = + handler.responseToIssues(buildExchange(responseBytes, dependencyTree)); + + PackageItem packageItem = result.pkgItems().get("pkg:maven/org.postgresql/postgresql@42.5.0"); + assertNotNull(packageItem); + List issues = packageItem.issues(); + assertEquals(1, issues.size(), "Same CVE+source should merge into one issue"); + + Issue issue = issues.get(0); + assertEquals("CVE-2024-1597", issue.getId()); + assertEquals(9.8f, issue.getCvssScore()); + assertNotNull(issue.getRemediation()); + assertEquals( + 2, issue.getRemediation().getFixedIn().size(), "Should accumulate fixedIn from both"); + assertTrue(issue.getRemediation().getFixedIn().contains("42.5.5")); + assertTrue(issue.getRemediation().getFixedIn().contains("42.6.1")); + + List remInfos = issue.getRemediation().getRemediations(); + assertNotNull(remInfos); + assertEquals(2, remInfos.size(), "Should have two advisory-linked remediations"); + } + + @Test + void testResponseToIssuesWithAdvisoryInfoAttribution() throws IOException { + String jsonResponse = + """ + { + "pkg:maven/org.postgresql/postgresql@42.5.0": { + "details": [ + { + "identifier": "CVE-2024-1597", + "title": "SQL Injection in PostgreSQL JDBC", + "description": "SQL injection vulnerability", + "base_score": { + "score": 9.8, + "severity": "CRITICAL" + }, + "purl_statuses": [ + { + "advisory": { + "id": "adv-1", + "document_id": "RHSA-2024:1234", + "title": "Red Hat Security Advisory", + "identifier": "https://access.redhat.com/errata/RHSA-2024:1234", + "issuer": { + "id": "issuer-1", + "name": "redhat-csaf" + } + }, + "status": "affected", + "version_range": { + "version_scheme_id": "semver", + "low_version": "0", + "low_inclusive": true, + "high_version": "42.5.5", + "high_inclusive": false + }, + "remediations": [], + "scores": [ + { + "source": "cve", + "value": 9.8, + "severity": "critical" + } + ] + }, + { + "advisory": { + "id": "adv-2", + "document_id": "GHSA-2024-5678", + "title": "GitHub Security Advisory", + "identifier": "GHSA-xxxx-yyyy-zzzz", + "issuer": { + "id": "issuer-2", + "name": "redhat-csaf" + } + }, + "status": "affected", + "version_range": null, + "remediations": [], + "scores": [ + { + "source": "cve", + "value": 9.8, + "severity": "critical" + } + ] + } + ] + } + ], + "warnings": [] + } + } + """; + + byte[] responseBytes = jsonResponse.getBytes(); + ProviderResponse result = + handler.responseToIssues(buildExchange(responseBytes, dependencyTree)); + + PackageItem packageItem = result.pkgItems().get("pkg:maven/org.postgresql/postgresql@42.5.0"); + assertNotNull(packageItem); + List issues = packageItem.issues(); + assertEquals(1, issues.size()); + + Issue issue = issues.get(0); + assertNotNull(issue.getRemediation()); + + List remInfos = issue.getRemediation().getRemediations(); + assertNotNull(remInfos); + assertEquals(2, remInfos.size(), "Should have two advisory-linked remediations"); + + RemediationInfo first = remInfos.get(0); + assertNotNull(first.getAdvisory()); + assertEquals("RHSA-2024:1234", first.getAdvisory().getId()); + assertEquals("Red Hat Security Advisory", first.getAdvisory().getTitle()); + assertNotNull(first.getAdvisory().getUrl()); + assertEquals( + "https://access.redhat.com/errata/RHSA-2024:1234", + first.getAdvisory().getUrl().toString()); + assertEquals(RemediationCategory.VENDOR_FIX, first.getCategory()); + + RemediationInfo second = remInfos.get(1); + assertNotNull(second.getAdvisory()); + assertEquals("GHSA-2024-5678", second.getAdvisory().getId()); + assertEquals("GitHub Security Advisory", second.getAdvisory().getTitle()); + assertNull(second.getAdvisory().getUrl(), "Non-URL identifier should result in null url"); + } + + @Test + void testResponseToIssuesMergeKeepsHigherCvss() throws IOException { + String jsonResponse = + """ + { + "pkg:maven/org.postgresql/postgresql@42.5.0": { + "details": [ + { + "identifier": "CVE-2024-1597", + "title": "SQL Injection in PostgreSQL JDBC", + "description": "SQL injection vulnerability", + "base_score": null, + "purl_statuses": [ + { + "advisory": { + "id": "adv-high", + "document_id": "ADV-HIGH", + "title": "High Score Advisory", + "identifier": "https://example.com/adv-high", + "issuer": { + "id": "issuer-1", + "name": "redhat-csaf" + } + }, + "status": "affected", + "version_range": null, + "remediations": [], + "scores": [ + { + "source": "cve", + "value": 9.8, + "severity": "critical" + } + ] + }, + { + "advisory": { + "id": "adv-low", + "document_id": "ADV-LOW", + "title": "Low Score Advisory", + "identifier": "https://example.com/adv-low", + "issuer": { + "id": "issuer-1", + "name": "redhat-csaf" + } + }, + "status": "affected", + "version_range": null, + "remediations": [], + "scores": [ + { + "source": "cve", + "value": 5.0, + "severity": "medium" + } + ] + } + ] + } + ], + "warnings": [] + } + } + """; + + byte[] responseBytes = jsonResponse.getBytes(); + ProviderResponse result = + handler.responseToIssues(buildExchange(responseBytes, dependencyTree)); + + PackageItem packageItem = result.pkgItems().get("pkg:maven/org.postgresql/postgresql@42.5.0"); + assertNotNull(packageItem); + List issues = packageItem.issues(); + assertEquals(1, issues.size()); + + Issue issue = issues.get(0); + assertEquals(9.8f, issue.getCvssScore(), "Should keep the higher CVSS score"); + assertEquals(Severity.CRITICAL, issue.getSeverity()); + } } From 6cfe99a7831d5abae9da21ab0082a38563b60063 Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Tue, 7 Jul 2026 11:19:38 +0200 Subject: [PATCH 02/10] fix(trustify): adapt remediation/advisory URLs to URI type in API model 2.0.11 RemediationInfo.url() and AdvisoryInfo.url() now accept URI instead of String. Wrap URI.create() calls in try-catch for malformed URLs and guard non-URL advisory identifiers (e.g., GHSA IDs) from being stored as URLs. Co-Authored-By: Claude Opus 4.6 --- .../trustify/TrustifyResponseHandler.java | 23 +++++++++++-------- .../trustify/TrustifyResponseHandlerTest.java | 6 ++--- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java b/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java index 22f4d812..8d101a77 100644 --- a/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java +++ b/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java @@ -252,7 +252,11 @@ private void setCvssData(Issue issue, JsonNode vuln, JsonNode purlStatus) { } var url = JsonUtils.getTextValue(rem, "url"); if (url != null) { - info.url(url); + try { + info.url(URI.create(url)); + } catch (IllegalArgumentException e) { + LOGGER.infof("Invalid remediation URL: %s", url); + } } if (advisoryInfo != null) { info.advisory(advisoryInfo); @@ -262,8 +266,7 @@ private void setCvssData(Issue issue, JsonNode vuln, JsonNode purlStatus) { hasRemediation = true; } else { var info = - buildRemediationInfo( - purlStatus, r.getFixedIn() != null && !r.getFixedIn().isEmpty()); + buildRemediationInfo(purlStatus, r.getFixedIn() != null && !r.getFixedIn().isEmpty()); if (info != null) { r.addRemediationsItem(info); hasRemediation = true; @@ -298,8 +301,7 @@ private void mergeIssueData(Issue existing, JsonNode vuln, JsonNode purlStatus) } } - if (score != null - && (existing.getCvssScore() == null || score > existing.getCvssScore())) { + if (score != null && (existing.getCvssScore() == null || score > existing.getCvssScore())) { existing.cvssScore(score); if (severity != null) { try { @@ -366,7 +368,11 @@ private void mergeIssueData(Issue existing, JsonNode vuln, JsonNode purlStatus) } var url = JsonUtils.getTextValue(rem, "url"); if (url != null) { - info.url(url); + try { + info.url(URI.create(url)); + } catch (IllegalArgumentException e) { + LOGGER.infof("Invalid remediation URL: %s", url); + } } if (advisoryInfo != null) { info.advisory(advisoryInfo); @@ -375,8 +381,7 @@ private void mergeIssueData(Issue existing, JsonNode vuln, JsonNode purlStatus) }); } else { var info = - buildRemediationInfo( - purlStatus, r.getFixedIn() != null && !r.getFixedIn().isEmpty()); + buildRemediationInfo(purlStatus, r.getFixedIn() != null && !r.getFixedIn().isEmpty()); if (info != null) { r.addRemediationsItem(info); } @@ -407,7 +412,7 @@ private AdvisoryInfo buildAdvisoryInfo(JsonNode purlStatus) { info.title(title); } var identifier = JsonUtils.getTextValue(advisory, "identifier"); - if (identifier != null) { + if (identifier != null && identifier.startsWith("http")) { try { info.url(URI.create(identifier)); } catch (IllegalArgumentException e) { diff --git a/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java b/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java index bf0a9be3..5aaa629e 100644 --- a/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java +++ b/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.when; import java.io.IOException; +import java.net.URI; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -1476,7 +1477,7 @@ void testResponseToIssuesWithRemediationUrl() throws IOException { var rem = issue.getRemediation().getRemediations().get(0); assertEquals(RemediationCategory.VENDOR_FIX, rem.getCategory()); assertEquals("Update to latest version", rem.getDetails()); - assertEquals("https://example.com/fix", rem.getUrl()); + assertEquals(URI.create("https://example.com/fix"), rem.getUrl()); } @Test @@ -2008,8 +2009,7 @@ void testResponseToIssuesWithAdvisoryInfoAttribution() throws IOException { assertEquals("Red Hat Security Advisory", first.getAdvisory().getTitle()); assertNotNull(first.getAdvisory().getUrl()); assertEquals( - "https://access.redhat.com/errata/RHSA-2024:1234", - first.getAdvisory().getUrl().toString()); + "https://access.redhat.com/errata/RHSA-2024:1234", first.getAdvisory().getUrl().toString()); assertEquals(RemediationCategory.VENDOR_FIX, first.getCategory()); RemediationInfo second = remInfos.get(1); From b8996816b35d60b4b27d0dd4d9ee7b8be5fa5b40 Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Tue, 7 Jul 2026 18:46:25 +0200 Subject: [PATCH 03/10] test(trustify): update WireMock fixtures for advisory-based remediations Add advisory RemediationInfo objects to all test fixture issues to match the new buildRemediationInfo fallback behavior in TrustifyResponseHandler. Update remediations summary counts accordingly. Co-Authored-By: Claude Opus 4.6 --- .../__files/reports/batch_report.json | 420 +++++++++++++++++- .../__files/reports/pypi_report.json | 248 ++++++----- .../resources/__files/reports/report.json | 420 +++++++++++++++++- 3 files changed, 936 insertions(+), 152 deletions(-) diff --git a/src/test/resources/__files/reports/batch_report.json b/src/test/resources/__files/reports/batch_report.json index c3adfd1b..2080af1c 100644 --- a/src/test/resources/__files/reports/batch_report.json +++ b/src/test/resources/__files/reports/batch_report.json @@ -30,7 +30,7 @@ "medium": 2, "low": 0, "unknown": 0, - "remediations": 2, + "remediations": 7, "recommendations": 0, "unscanned": 0 }, @@ -50,7 +50,17 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } + } + ] + } }, { "id": "CVE-2022-41946", @@ -61,7 +71,17 @@ "cves": [ "CVE-2022-41946" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-562r-vg33-8x8h", + "title": "TemporaryFolder on unix-like systems does not limit access to created files" + } + } + ] + } } ], "highestVulnerability": { @@ -73,7 +93,17 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } + } + ] + } } } ], @@ -86,7 +116,17 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } + } + ] + } } }, { @@ -106,6 +146,14 @@ ], "unique": false, "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-57j2-w4cx-62h2", + "title": "Deeply nested json in jackson-databind" + } + } + ], "trustedContent": { "ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.1.2-redhat-00001?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar", "status": "NotAffected", @@ -122,7 +170,17 @@ "cves": [ "CVE-2022-42003" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-jjjh-jjxp-wpff", + "title": "Uncontrolled Resource Consumption in Jackson-databind" + } + } + ] + } }, { "id": "CVE-2022-42004", @@ -133,7 +191,17 @@ "cves": [ "CVE-2022-42004" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-rgv9-q543-rqg4", + "title": "Uncontrolled Resource Consumption in FasterXML jackson-databind" + } + } + ] + } } ], "highestVulnerability": { @@ -147,6 +215,14 @@ ], "unique": false, "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-57j2-w4cx-62h2", + "title": "Deeply nested json in jackson-databind" + } + } + ], "trustedContent": { "ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.1.2-redhat-00001?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar", "status": "NotAffected", @@ -167,7 +243,17 @@ "cves": [ "CVE-2024-2700" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-f8h5-v2vg-46rr", + "title": "quarkus-core leaks local environment variables from Quarkus namespace during application's build" + } + } + ] + } }, { "id": "CVE-2023-2974", @@ -180,6 +266,14 @@ ], "unique": false, "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-3fhx-3vvg-2j84", + "title": "quarkus-core vulnerable to client driven TLS cipher downgrading" + } + } + ], "trustedContent": { "ref": "pkg:maven/io.quarkus/quarkus-core@2.13.5.Final-redhat-00004?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar", "status": "NotAffected", @@ -197,7 +291,17 @@ "cves": [ "CVE-2024-2700" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-f8h5-v2vg-46rr", + "title": "quarkus-core leaks local environment variables from Quarkus namespace during application's build" + } + } + ] + } } } ], @@ -212,6 +316,14 @@ ], "unique": false, "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-57j2-w4cx-62h2", + "title": "Deeply nested json in jackson-databind" + } + } + ], "trustedContent": { "ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.1.2-redhat-00001?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar", "status": "NotAffected", @@ -233,7 +345,7 @@ "medium": 0, "low": 0, "unknown": 0, - "remediations": 0, + "remediations": 2, "recommendations": 0, "unscanned": 0 }, @@ -253,7 +365,67 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + } + ] + } } ], "highestVulnerability": { @@ -265,7 +437,67 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + } + ] + } } } ], @@ -278,7 +510,67 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + } + ] + } } }, { @@ -296,7 +588,39 @@ "cves": [ "CVE-2024-2700" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "RHSA-2024:2705", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.12 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_2705" + } + }, + { + "advisory": { + "id": "RHSA-2024:2106", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.8.4 release", + "url": "https://www.redhat.com/#RHSA-2024_2106" + } + } + ] + } } ], "highestVulnerability": { @@ -308,7 +632,39 @@ "cves": [ "CVE-2024-2700" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "RHSA-2024:2705", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.12 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_2705" + } + }, + { + "advisory": { + "id": "RHSA-2024:2106", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.8.4 release", + "url": "https://www.redhat.com/#RHSA-2024_2106" + } + } + ] + } } } ], @@ -321,7 +677,39 @@ "cves": [ "CVE-2024-2700" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "RHSA-2024:2705", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.12 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_2705" + } + }, + { + "advisory": { + "id": "RHSA-2024:2106", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.8.4 release", + "url": "https://www.redhat.com/#RHSA-2024_2106" + } + } + ] + } } } ] diff --git a/src/test/resources/__files/reports/pypi_report.json b/src/test/resources/__files/reports/pypi_report.json index 07b328f8..15fb3f6b 100644 --- a/src/test/resources/__files/reports/pypi_report.json +++ b/src/test/resources/__files/reports/pypi_report.json @@ -1,129 +1,137 @@ { - "scanned": { - "total": 2, - "direct": 2, - "transitive": 0 - }, - "providers": { - "trustify": { - "status": { - "ok": true, - "name": "trustify", - "code": 200, - "message": "OK", - "warnings": { - - } - }, - "sources": { - "osv-github": { - "summary": { - "direct": 1, - "transitive": 0, - "total": 1, - "dependencies": 1, - "critical": 0, - "high": 0, - "medium": 1, - "low": 0, - "unknown": 0, - "remediations": 0, - "recommendations": 2, - "unscanned": 0 - }, - "dependencies": [ - { - "ref": "pkg:pypi/requests@2.31.0", - "issues": [ - { - "id": "CVE-2024-35195", - "title": "Requests Session object does not verify requests after making first request with verify=False", - "source": "osv-github", - "cvssScore": 5.6, - "severity": "MEDIUM", - "cves": [ - "CVE-2024-35195" - ], - "unique": false, - "remediation": { - "trustedContent": { - "ref": "pkg:pypi/requests@2.31.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" - } - } - } - ], - "transitive": [ - - ], - "recommendation": "pkg:pypi/requests@2.31.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython", - "highestVulnerability": { - "id": "CVE-2024-35195", - "title": "Requests Session object does not verify requests after making first request with verify=False", - "source": "osv-github", - "cvssScore": 5.6, - "severity": "MEDIUM", - "cves": [ - "CVE-2024-35195" - ], - "unique": false, - "remediation": { - "trustedContent": { - "ref": "pkg:pypi/requests@2.31.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" - } - } - } - }, - { - "ref": "pkg:pypi/flask@3.0.0", - "recommendation": "pkg:pypi/flask@3.0.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" + "scanned": { + "total": 2, + "direct": 2, + "transitive": 0 + }, + "providers": { + "trustify": { + "status": { + "ok": true, + "name": "trustify", + "code": 200, + "message": "OK", + "warnings": {} + }, + "sources": { + "osv-github": { + "summary": { + "direct": 1, + "transitive": 0, + "total": 1, + "dependencies": 1, + "critical": 0, + "high": 0, + "medium": 1, + "low": 0, + "unknown": 0, + "remediations": 1, + "recommendations": 2, + "unscanned": 0 + }, + "dependencies": [ + { + "ref": "pkg:pypi/requests@2.31.0", + "issues": [ + { + "id": "CVE-2024-35195", + "title": "Requests Session object does not verify requests after making first request with verify=False", + "source": "osv-github", + "cvssScore": 5.6, + "severity": "MEDIUM", + "cves": [ + "CVE-2024-35195" + ], + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-9wx4-h78v-vm56", + "title": "Requests Session object does not verify requests after making first request with verify=False" } - ] + } + ], + "trustedContent": { + "ref": "pkg:pypi/requests@2.31.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" + } + } } - }, - "recommendations": { - "trusted-libraries": { - "summary": { - "total": 2 - }, - "dependencies": [ - { - "ref": "pkg:pypi/requests@2.31.0", - "recommendation": "pkg:pypi/requests@2.31.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" - }, - { - "ref": "pkg:pypi/flask@3.0.0", - "recommendation": "pkg:pypi/flask@3.0.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" - } - ] + ], + "transitive": [], + "recommendation": "pkg:pypi/requests@2.31.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython", + "highestVulnerability": { + "id": "CVE-2024-35195", + "title": "Requests Session object does not verify requests after making first request with verify=False", + "source": "osv-github", + "cvssScore": 5.6, + "severity": "MEDIUM", + "cves": [ + "CVE-2024-35195" + ], + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-9wx4-h78v-vm56", + "title": "Requests Session object does not verify requests after making first request with verify=False" + } + } + ], + "trustedContent": { + "ref": "pkg:pypi/requests@2.31.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" + } } + } + }, + { + "ref": "pkg:pypi/flask@3.0.0", + "recommendation": "pkg:pypi/flask@3.0.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" } + ] } - }, - "licenses": [ - { - "status": { - "ok": false, - "name": "deps.dev", - "code": 504, - "message": "Request timed out", - "warnings": { - - } - }, - "summary": { - "total": 0, - "concluded": 0, - "permissive": 0, - "weakCopyleft": 0, - "strongCopyleft": 0, - "unknown": 0, - "deprecated": 0, - "osiApproved": 0, - "fsfLibre": 0 + }, + "recommendations": { + "trusted-libraries": { + "summary": { + "total": 2 + }, + "dependencies": [ + { + "ref": "pkg:pypi/requests@2.31.0", + "recommendation": "pkg:pypi/requests@2.31.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" }, - "packages": { - + { + "ref": "pkg:pypi/flask@3.0.0", + "recommendation": "pkg:pypi/flask@3.0.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" } + ] } - ] -} \ No newline at end of file + } + } + }, + "licenses": [ + { + "status": { + "ok": false, + "name": "deps.dev", + "code": 504, + "message": "Request timed out", + "warnings": {} + }, + "summary": { + "total": 0, + "concluded": 0, + "permissive": 0, + "weakCopyleft": 0, + "strongCopyleft": 0, + "unknown": 0, + "deprecated": 0, + "osiApproved": 0, + "fsfLibre": 0 + }, + "packages": {} + } + ] +} diff --git a/src/test/resources/__files/reports/report.json b/src/test/resources/__files/reports/report.json index 60c754f1..67e89caa 100644 --- a/src/test/resources/__files/reports/report.json +++ b/src/test/resources/__files/reports/report.json @@ -29,7 +29,7 @@ "medium": 2, "low": 0, "unknown": 0, - "remediations": 2, + "remediations": 7, "recommendations": 0, "unscanned": 0 }, @@ -49,7 +49,17 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } + } + ] + } }, { "id": "CVE-2022-41946", @@ -60,7 +70,17 @@ "cves": [ "CVE-2022-41946" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-562r-vg33-8x8h", + "title": "TemporaryFolder on unix-like systems does not limit access to created files" + } + } + ] + } } ], "highestVulnerability": { @@ -72,7 +92,17 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } + } + ] + } } } ], @@ -85,7 +115,17 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } + } + ] + } } }, { @@ -105,6 +145,14 @@ ], "unique": false, "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-57j2-w4cx-62h2", + "title": "Deeply nested json in jackson-databind" + } + } + ], "trustedContent": { "ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.1.2-redhat-00001?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar", "status": "NotAffected", @@ -121,7 +169,17 @@ "cves": [ "CVE-2022-42003" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-jjjh-jjxp-wpff", + "title": "Uncontrolled Resource Consumption in Jackson-databind" + } + } + ] + } }, { "id": "CVE-2022-42004", @@ -132,7 +190,17 @@ "cves": [ "CVE-2022-42004" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-rgv9-q543-rqg4", + "title": "Uncontrolled Resource Consumption in FasterXML jackson-databind" + } + } + ] + } } ], "highestVulnerability": { @@ -146,6 +214,14 @@ ], "unique": false, "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-57j2-w4cx-62h2", + "title": "Deeply nested json in jackson-databind" + } + } + ], "trustedContent": { "ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.1.2-redhat-00001?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar", "status": "NotAffected", @@ -166,7 +242,17 @@ "cves": [ "CVE-2024-2700" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-f8h5-v2vg-46rr", + "title": "quarkus-core leaks local environment variables from Quarkus namespace during application's build" + } + } + ] + } }, { "id": "CVE-2023-2974", @@ -179,6 +265,14 @@ ], "unique": false, "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-3fhx-3vvg-2j84", + "title": "quarkus-core vulnerable to client driven TLS cipher downgrading" + } + } + ], "trustedContent": { "ref": "pkg:maven/io.quarkus/quarkus-core@2.13.5.Final-redhat-00004?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar", "status": "NotAffected", @@ -196,7 +290,17 @@ "cves": [ "CVE-2024-2700" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-f8h5-v2vg-46rr", + "title": "quarkus-core leaks local environment variables from Quarkus namespace during application's build" + } + } + ] + } } } ], @@ -211,6 +315,14 @@ ], "unique": false, "remediation": { + "remediations": [ + { + "advisory": { + "id": "GHSA-57j2-w4cx-62h2", + "title": "Deeply nested json in jackson-databind" + } + } + ], "trustedContent": { "ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.1.2-redhat-00001?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar", "status": "NotAffected", @@ -232,7 +344,7 @@ "medium": 0, "low": 0, "unknown": 0, - "remediations": 0, + "remediations": 2, "recommendations": 0, "unscanned": 0 }, @@ -252,7 +364,67 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + } + ] + } } ], "highestVulnerability": { @@ -264,7 +436,67 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + } + ] + } } } ], @@ -277,7 +509,67 @@ "cves": [ "CVE-2024-1597" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + }, + { + "advisory": { + "id": "CVE-2024-1597", + "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", + "url": "https://www.redhat.com/#CVE-2024-1597" + } + }, + { + "advisory": { + "id": "RHSA-2024:1797", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1797" + } + }, + { + "advisory": { + "id": "RHSA-2024:1662", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_1662" + } + } + ] + } } }, { @@ -295,7 +587,39 @@ "cves": [ "CVE-2024-2700" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "RHSA-2024:2705", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.12 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_2705" + } + }, + { + "advisory": { + "id": "RHSA-2024:2106", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.8.4 release", + "url": "https://www.redhat.com/#RHSA-2024_2106" + } + } + ] + } } ], "highestVulnerability": { @@ -307,7 +631,39 @@ "cves": [ "CVE-2024-2700" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "RHSA-2024:2705", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.12 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_2705" + } + }, + { + "advisory": { + "id": "RHSA-2024:2106", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.8.4 release", + "url": "https://www.redhat.com/#RHSA-2024_2106" + } + } + ] + } } } ], @@ -320,7 +676,39 @@ "cves": [ "CVE-2024-2700" ], - "unique": false + "unique": false, + "remediation": { + "remediations": [ + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "CVE-2024-2700", + "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", + "url": "https://www.redhat.com/#CVE-2024-2700" + } + }, + { + "advisory": { + "id": "RHSA-2024:2705", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.12 release and security update", + "url": "https://www.redhat.com/#RHSA-2024_2705" + } + }, + { + "advisory": { + "id": "RHSA-2024:2106", + "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.8.4 release", + "url": "https://www.redhat.com/#RHSA-2024_2106" + } + } + ] + } } } ] From 4ddeb516e3fc8546f52a99761d7b3d1a8cbd8269 Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Tue, 7 Jul 2026 23:41:02 +0200 Subject: [PATCH 04/10] test(trustify): add non-empty remediations to mock data for coverage Add vendor_fix and workaround remediation entries to WireMock mock data so the non-empty remediations processing paths in TrustifyResponseHandler (setCvssData lines 237-266, mergeIssueData lines 351-381) are exercised by integration tests. Co-Authored-By: Claude Opus 4.6 --- .../__files/reports/batch_report.json | 50 ++++++++++++------- .../__files/reports/pypi_report.json | 18 ++++--- .../resources/__files/reports/report.json | 38 +++++++++----- .../__files/trustify/maven_report.json | 16 +++++- .../__files/trustify/pypi_report.json | 8 ++- 5 files changed, 89 insertions(+), 41 deletions(-) diff --git a/src/test/resources/__files/reports/batch_report.json b/src/test/resources/__files/reports/batch_report.json index 2080af1c..48c5d66c 100644 --- a/src/test/resources/__files/reports/batch_report.json +++ b/src/test/resources/__files/reports/batch_report.json @@ -53,13 +53,16 @@ "unique": false, "remediation": { "remediations": [ - { - "advisory": { - "id": "GHSA-24rp-q3w6-vc56", - "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" - } + { + "category": "VENDOR_FIX", + "details": "Upgrade to version 42.7.2 or later", + "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" } - ] + } + ] } }, { @@ -97,6 +100,9 @@ "remediation": { "remediations": [ { + "category": "VENDOR_FIX", + "details": "Upgrade to version 42.7.2 or later", + "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", "advisory": { "id": "GHSA-24rp-q3w6-vc56", "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" @@ -119,13 +125,16 @@ "unique": false, "remediation": { "remediations": [ - { - "advisory": { - "id": "GHSA-24rp-q3w6-vc56", - "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" - } - } - ] + { + "category": "VENDOR_FIX", + "details": "Upgrade to version 42.7.2 or later", + "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } + } + ] } } }, @@ -173,13 +182,16 @@ "unique": false, "remediation": { "remediations": [ - { - "advisory": { - "id": "GHSA-jjjh-jjxp-wpff", - "title": "Uncontrolled Resource Consumption in Jackson-databind" - } + { + "category": "WORKAROUND", + "details": "Disable UNWRAP_SINGLE_VALUE_ARRAYS feature or upgrade to 2.13.4.1 or later", + "url": "https://github.com/FasterXML/jackson-databind/issues/3590", + "advisory": { + "id": "GHSA-jjjh-jjxp-wpff", + "title": "Uncontrolled Resource Consumption in Jackson-databind" } - ] + } + ] } }, { diff --git a/src/test/resources/__files/reports/pypi_report.json b/src/test/resources/__files/reports/pypi_report.json index 15fb3f6b..0f0c8543 100644 --- a/src/test/resources/__files/reports/pypi_report.json +++ b/src/test/resources/__files/reports/pypi_report.json @@ -46,6 +46,9 @@ "remediation": { "remediations": [ { + "category": "VENDOR_FIX", + "details": "Upgrade to 2.32.0 or later", + "url": "https://github.com/psf/requests/security/advisories/GHSA-9wx4-h78v-vm56", "advisory": { "id": "GHSA-9wx4-h78v-vm56", "title": "Requests Session object does not verify requests after making first request with verify=False" @@ -72,13 +75,16 @@ "unique": false, "remediation": { "remediations": [ - { - "advisory": { - "id": "GHSA-9wx4-h78v-vm56", - "title": "Requests Session object does not verify requests after making first request with verify=False" + { + "category": "VENDOR_FIX", + "details": "Upgrade to 2.32.0 or later", + "url": "https://github.com/psf/requests/security/advisories/GHSA-9wx4-h78v-vm56", + "advisory": { + "id": "GHSA-9wx4-h78v-vm56", + "title": "Requests Session object does not verify requests after making first request with verify=False" + } } - } - ], + ], "trustedContent": { "ref": "pkg:pypi/requests@2.31.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" } diff --git a/src/test/resources/__files/reports/report.json b/src/test/resources/__files/reports/report.json index 67e89caa..d5c47c57 100644 --- a/src/test/resources/__files/reports/report.json +++ b/src/test/resources/__files/reports/report.json @@ -53,6 +53,9 @@ "remediation": { "remediations": [ { + "category": "VENDOR_FIX", + "details": "Upgrade to version 42.7.2 or later", + "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", "advisory": { "id": "GHSA-24rp-q3w6-vc56", "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" @@ -95,13 +98,16 @@ "unique": false, "remediation": { "remediations": [ - { - "advisory": { - "id": "GHSA-24rp-q3w6-vc56", - "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + { + "category": "VENDOR_FIX", + "details": "Upgrade to version 42.7.2 or later", + "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } } - } - ] + ] } } } @@ -118,13 +124,16 @@ "unique": false, "remediation": { "remediations": [ - { - "advisory": { - "id": "GHSA-24rp-q3w6-vc56", - "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" - } - } - ] + { + "category": "VENDOR_FIX", + "details": "Upgrade to version 42.7.2 or later", + "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } + } + ] } } }, @@ -173,6 +182,9 @@ "remediation": { "remediations": [ { + "category": "WORKAROUND", + "details": "Disable UNWRAP_SINGLE_VALUE_ARRAYS feature or upgrade to 2.13.4.1 or later", + "url": "https://github.com/FasterXML/jackson-databind/issues/3590", "advisory": { "id": "GHSA-jjjh-jjxp-wpff", "title": "Uncontrolled Resource Consumption in Jackson-databind" diff --git a/src/test/resources/__files/trustify/maven_report.json b/src/test/resources/__files/trustify/maven_report.json index ac4b9a55..dcad1eb2 100644 --- a/src/test/resources/__files/trustify/maven_report.json +++ b/src/test/resources/__files/trustify/maven_report.json @@ -65,7 +65,13 @@ }, "status": "affected", "version_range": null, - "remediations": [] + "remediations": [ + { + "category": "workaround", + "details": "Disable UNWRAP_SINGLE_VALUE_ARRAYS feature or upgrade to 2.13.4.1 or later", + "url": "https://github.com/FasterXML/jackson-databind/issues/3590" + } + ] } ] }, @@ -441,7 +447,13 @@ }, "status": "affected", "version_range": null, - "remediations": [] + "remediations": [ + { + "category": "vendor_fix", + "details": "Upgrade to version 42.7.2 or later", + "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56" + } + ] }, { "advisory": { diff --git a/src/test/resources/__files/trustify/pypi_report.json b/src/test/resources/__files/trustify/pypi_report.json index ea49333c..c8eab44d 100644 --- a/src/test/resources/__files/trustify/pypi_report.json +++ b/src/test/resources/__files/trustify/pypi_report.json @@ -33,7 +33,13 @@ }, "status": "affected", "version_range": null, - "remediations": [] + "remediations": [ + { + "category": "vendor_fix", + "details": "Upgrade to 2.32.0 or later", + "url": "https://github.com/psf/requests/security/advisories/GHSA-9wx4-h78v-vm56" + } + ] } ] } From 725480a3515a680351cf7ca53f799e2f1e14f450 Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Wed, 8 Jul 2026 09:03:47 +0200 Subject: [PATCH 05/10] refactor(trustify): extract shared helpers from setCvssData/mergeIssueData Extract three duplicated blocks into private helpers: - extractScoreData: CVSS score/severity extraction from JSON - processVersionRange: version range parsing with dedup flag - processRemediations: remediation array processing with fallback Also add method length convention to CONVENTIONS.md. Co-Authored-By: Claude Opus 4.6 --- CONVENTIONS.md | 1 + .../trustify/TrustifyResponseHandler.java | 211 ++++++------------ 2 files changed, 74 insertions(+), 138 deletions(-) diff --git a/CONVENTIONS.md b/CONVENTIONS.md index bcbbe8ab..65631f29 100644 --- a/CONVENTIONS.md +++ b/CONVENTIONS.md @@ -26,6 +26,7 @@ - **Formatter toggle**: `// fmt:off` / `// fmt:on` to disable formatting (used in Camel DSL code) - **Encoding**: UTF-8 - **Line endings**: LF, trim trailing whitespace, final newline +- **Method length**: Methods should not exceed ~40 lines of logic. When a method grows beyond this, extract cohesive blocks into well-named private helpers. Duplicated blocks across methods must always be extracted. ## Naming Conventions diff --git a/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java b/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java index 8d101a77..d4e3b761 100644 --- a/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java +++ b/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java @@ -161,124 +161,59 @@ private List getWarnings(JsonNode entryValue) { } private void setCvssData(Issue issue, JsonNode vuln, JsonNode purlStatus) { - Float score = null; - String severity = null; + var sd = extractScoreData(vuln, purlStatus); - var baseScore = vuln.get("base_score"); - if (baseScore != null && !baseScore.isNull()) { - score = baseScore.has("score") ? (float) baseScore.get("score").asDouble() : null; - severity = JsonUtils.getTextValue(baseScore, "severity"); + if (sd.score != null) { + issue.cvssScore(sd.score); } - - if (score == null) { - var scores = purlStatus.get("scores"); - if (scores != null && scores.isArray() && !scores.isEmpty()) { - for (var entry : scores) { - var entryValue = entry.has("value") ? (float) entry.get("value").asDouble() : null; - if (entryValue != null && (score == null || entryValue > score)) { - score = entryValue; - severity = JsonUtils.getTextValue(entry, "severity"); - } - } - } - } - - if (score != null) { - issue.cvssScore(score); - } - if (severity != null) { + if (sd.severity != null) { try { - issue.setSeverity(SeverityUtils.fromValue(severity.toUpperCase())); + issue.setSeverity(SeverityUtils.fromValue(sd.severity.toUpperCase())); } catch (IllegalArgumentException e) { - LOGGER.infof("Unknown severity value: %s, falling back to score-based severity", severity); - if (score != null) { - issue.setSeverity(SeverityUtils.fromScore(score)); + LOGGER.infof( + "Unknown severity value: %s, falling back to score-based severity", sd.severity); + if (sd.score != null) { + issue.setSeverity(SeverityUtils.fromScore(sd.score)); } } - } else if (score != null) { - issue.setSeverity(SeverityUtils.fromScore(score)); + } else if (sd.score != null) { + issue.setSeverity(SeverityUtils.fromScore(sd.score)); } var r = new Remediation(); - boolean hasRemediation = false; + boolean hasRemediation = processVersionRange(purlStatus, r, false); + hasRemediation |= processRemediations(purlStatus, r); - var versionRange = purlStatus.get("version_range"); - if (versionRange != null && !versionRange.isNull()) { - var vr = new VersionRange(); - var schemeId = JsonUtils.getTextValue(versionRange, "version_scheme_id"); - if (schemeId != null) { - vr.versionSchemeId(schemeId); - } - var lowVersion = JsonUtils.getTextValue(versionRange, "low_version"); - if (lowVersion != null) { - vr.lowVersion(lowVersion); - } - var lowInclusive = JsonUtils.getBooleanValue(versionRange, "low_inclusive"); - if (lowInclusive != null) { - vr.lowInclusive(lowInclusive); - } - var highVersion = JsonUtils.getTextValue(versionRange, "high_version"); - var highInclusive = JsonUtils.getBooleanValue(versionRange, "high_inclusive"); - if (highVersion != null) { - vr.highVersion(highVersion); - if (highInclusive == null || !highInclusive) { - r.addFixedInItem(highVersion); - } - } - if (highInclusive != null) { - vr.highInclusive(highInclusive); - } - r.addVersionRangesItem(vr); - hasRemediation = true; + if (hasRemediation) { + issue.setRemediation(r); } + } - var remediations = (ArrayNode) purlStatus.get("remediations"); - var advisoryInfo = buildAdvisoryInfo(purlStatus); - if (remediations != null && !remediations.isEmpty()) { - remediations.forEach( - rem -> { - var info = new RemediationInfo(); - var category = JsonUtils.getTextValue(rem, "category"); - if (category != null) { - try { - info.category(RemediationCategory.fromValue(category.toUpperCase())); - } catch (IllegalArgumentException e) { - LOGGER.infof("Unknown remediation category: %s", category); - } - } - var details = JsonUtils.getTextValue(rem, "details"); - if (details != null) { - info.details(details); - } - var url = JsonUtils.getTextValue(rem, "url"); - if (url != null) { - try { - info.url(URI.create(url)); - } catch (IllegalArgumentException e) { - LOGGER.infof("Invalid remediation URL: %s", url); - } - } - if (advisoryInfo != null) { - info.advisory(advisoryInfo); - } - r.addRemediationsItem(info); - }); - hasRemediation = true; - } else { - var info = - buildRemediationInfo(purlStatus, r.getFixedIn() != null && !r.getFixedIn().isEmpty()); - if (info != null) { - r.addRemediationsItem(info); - hasRemediation = true; + private void mergeIssueData(Issue existing, JsonNode vuln, JsonNode purlStatus) { + var sd = extractScoreData(vuln, purlStatus); + + if (sd.score != null + && (existing.getCvssScore() == null || sd.score > existing.getCvssScore())) { + existing.cvssScore(sd.score); + if (sd.severity != null) { + try { + existing.setSeverity(SeverityUtils.fromValue(sd.severity.toUpperCase())); + } catch (IllegalArgumentException e) { + existing.setSeverity(SeverityUtils.fromScore(sd.score)); + } + } else { + existing.setSeverity(SeverityUtils.fromScore(sd.score)); } } - if (hasRemediation) { - issue.setRemediation(r); - } + var r = ensureRemediation(existing); + processVersionRange(purlStatus, r, true); + processRemediations(purlStatus, r); } - private void mergeIssueData(Issue existing, JsonNode vuln, JsonNode purlStatus) { + private record ScoreData(Float score, String severity) {} + + private ScoreData extractScoreData(JsonNode vuln, JsonNode purlStatus) { Float score = null; String severity = null; @@ -301,53 +236,50 @@ private void mergeIssueData(Issue existing, JsonNode vuln, JsonNode purlStatus) } } - if (score != null && (existing.getCvssScore() == null || score > existing.getCvssScore())) { - existing.cvssScore(score); - if (severity != null) { - try { - existing.setSeverity(SeverityUtils.fromValue(severity.toUpperCase())); - } catch (IllegalArgumentException e) { - existing.setSeverity(SeverityUtils.fromScore(score)); - } - } else { - existing.setSeverity(SeverityUtils.fromScore(score)); - } - } - - var r = ensureRemediation(existing); + return new ScoreData(score, severity); + } + private boolean processVersionRange(JsonNode purlStatus, Remediation r, boolean dedup) { var versionRange = purlStatus.get("version_range"); - if (versionRange != null && !versionRange.isNull()) { - var vr = new VersionRange(); - var schemeId = JsonUtils.getTextValue(versionRange, "version_scheme_id"); - if (schemeId != null) { - vr.versionSchemeId(schemeId); - } - var lowVersion = JsonUtils.getTextValue(versionRange, "low_version"); - if (lowVersion != null) { - vr.lowVersion(lowVersion); - } - var lowInclusive = JsonUtils.getBooleanValue(versionRange, "low_inclusive"); - if (lowInclusive != null) { - vr.lowInclusive(lowInclusive); - } - var highVersion = JsonUtils.getTextValue(versionRange, "high_version"); - var highInclusive = JsonUtils.getBooleanValue(versionRange, "high_inclusive"); - if (highVersion != null) { - vr.highVersion(highVersion); - if (highInclusive == null || !highInclusive) { + if (versionRange == null || versionRange.isNull()) { + return false; + } + var vr = new VersionRange(); + var schemeId = JsonUtils.getTextValue(versionRange, "version_scheme_id"); + if (schemeId != null) { + vr.versionSchemeId(schemeId); + } + var lowVersion = JsonUtils.getTextValue(versionRange, "low_version"); + if (lowVersion != null) { + vr.lowVersion(lowVersion); + } + var lowInclusive = JsonUtils.getBooleanValue(versionRange, "low_inclusive"); + if (lowInclusive != null) { + vr.lowInclusive(lowInclusive); + } + var highVersion = JsonUtils.getTextValue(versionRange, "high_version"); + var highInclusive = JsonUtils.getBooleanValue(versionRange, "high_inclusive"); + if (highVersion != null) { + vr.highVersion(highVersion); + if (highInclusive == null || !highInclusive) { + if (dedup) { var fixedIn = r.getFixedIn(); if (fixedIn == null || !fixedIn.contains(highVersion)) { r.addFixedInItem(highVersion); } + } else { + r.addFixedInItem(highVersion); } } - if (highInclusive != null) { - vr.highInclusive(highInclusive); - } - r.addVersionRangesItem(vr); } + if (highInclusive != null) { + vr.highInclusive(highInclusive); + } + r.addVersionRangesItem(vr); + return true; + } + private boolean processRemediations(JsonNode purlStatus, Remediation r) { var remediations = (ArrayNode) purlStatus.get("remediations"); var advisoryInfo = buildAdvisoryInfo(purlStatus); if (remediations != null && !remediations.isEmpty()) { @@ -379,13 +311,16 @@ private void mergeIssueData(Issue existing, JsonNode vuln, JsonNode purlStatus) } r.addRemediationsItem(info); }); + return true; } else { var info = buildRemediationInfo(purlStatus, r.getFixedIn() != null && !r.getFixedIn().isEmpty()); if (info != null) { r.addRemediationsItem(info); + return true; } } + return false; } private Remediation ensureRemediation(Issue issue) { From 79c7b261433b80636abaa7421a541016464aaf45 Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Wed, 8 Jul 2026 09:13:43 +0200 Subject: [PATCH 06/10] =?UTF-8?q?fix(test):=20revert=20pypi=20mock=20remed?= =?UTF-8?q?iations=20=E2=80=94=20Vulnerability=20model=20lacks=20field?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pypi recommendations endpoint deserializes into Vulnerability which only has status/id/justification fields, not remediations. Co-Authored-By: Claude Opus 4.6 --- .../resources/__files/reports/pypi_report.json | 18 ++++++------------ .../__files/trustify/pypi_report.json | 8 +------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/test/resources/__files/reports/pypi_report.json b/src/test/resources/__files/reports/pypi_report.json index 0f0c8543..15fb3f6b 100644 --- a/src/test/resources/__files/reports/pypi_report.json +++ b/src/test/resources/__files/reports/pypi_report.json @@ -46,9 +46,6 @@ "remediation": { "remediations": [ { - "category": "VENDOR_FIX", - "details": "Upgrade to 2.32.0 or later", - "url": "https://github.com/psf/requests/security/advisories/GHSA-9wx4-h78v-vm56", "advisory": { "id": "GHSA-9wx4-h78v-vm56", "title": "Requests Session object does not verify requests after making first request with verify=False" @@ -75,16 +72,13 @@ "unique": false, "remediation": { "remediations": [ - { - "category": "VENDOR_FIX", - "details": "Upgrade to 2.32.0 or later", - "url": "https://github.com/psf/requests/security/advisories/GHSA-9wx4-h78v-vm56", - "advisory": { - "id": "GHSA-9wx4-h78v-vm56", - "title": "Requests Session object does not verify requests after making first request with verify=False" - } + { + "advisory": { + "id": "GHSA-9wx4-h78v-vm56", + "title": "Requests Session object does not verify requests after making first request with verify=False" } - ], + } + ], "trustedContent": { "ref": "pkg:pypi/requests@2.31.0?repository_url=https%3A%2F%2Fpackages.redhat.com%2Ftrusted-libraries%2Fpython" } diff --git a/src/test/resources/__files/trustify/pypi_report.json b/src/test/resources/__files/trustify/pypi_report.json index c8eab44d..ea49333c 100644 --- a/src/test/resources/__files/trustify/pypi_report.json +++ b/src/test/resources/__files/trustify/pypi_report.json @@ -33,13 +33,7 @@ }, "status": "affected", "version_range": null, - "remediations": [ - { - "category": "vendor_fix", - "details": "Upgrade to 2.32.0 or later", - "url": "https://github.com/psf/requests/security/advisories/GHSA-9wx4-h78v-vm56" - } - ] + "remediations": [] } ] } From 914e55f4d8614d15a23cc81efde78e1db8120dcb Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Wed, 8 Jul 2026 09:27:16 +0200 Subject: [PATCH 07/10] fix(trustify): ignore unknown fields in Vulnerability model The Trustify server now returns a remediations field on the recommendations Vulnerability object. Add @JsonIgnoreProperties to tolerate new fields without breaking deserialization. Co-Authored-By: Claude Opus 4.6 --- .../github/guacsec/trustifyda/model/trustify/Vulnerability.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/io/github/guacsec/trustifyda/model/trustify/Vulnerability.java b/src/main/java/io/github/guacsec/trustifyda/model/trustify/Vulnerability.java index 36b93ba2..ec8d29aa 100644 --- a/src/main/java/io/github/guacsec/trustifyda/model/trustify/Vulnerability.java +++ b/src/main/java/io/github/guacsec/trustifyda/model/trustify/Vulnerability.java @@ -19,6 +19,7 @@ import java.io.IOException; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; @@ -28,6 +29,7 @@ import io.quarkus.runtime.annotations.RegisterForReflection; @RegisterForReflection +@JsonIgnoreProperties(ignoreUnknown = true) public class Vulnerability { private String id; From 8e3c8c9279adadf34a4ce0d5b574d85727c51a6d Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Wed, 8 Jul 2026 11:24:19 +0200 Subject: [PATCH 08/10] fix(trustify): deduplicate remediations when merging purl_statuses When multiple purl_statuses for the same CVE+source are merged, remediations were blindly appended without checking for duplicates. This produced repeated entries in the output (e.g., the same NO_FIX_PLANNED advisory appearing multiple times). Add isDuplicateRemediation guard using a composite key of (category, details, advisory.id) before adding any remediation item. Co-Authored-By: Claude Opus 4.6 --- .../trustify/TrustifyResponseHandler.java | 22 ++++++++++++-- .../__files/reports/batch_report.json | 30 ++----------------- .../resources/__files/reports/report.json | 30 ++----------------- .../__files/trustify/maven_report.json | 16 ++++++++-- 4 files changed, 38 insertions(+), 60 deletions(-) diff --git a/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java b/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java index d4e3b761..7ca10caa 100644 --- a/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java +++ b/src/main/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandler.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import org.apache.camel.Exchange; @@ -309,13 +310,15 @@ private boolean processRemediations(JsonNode purlStatus, Remediation r) { if (advisoryInfo != null) { info.advisory(advisoryInfo); } - r.addRemediationsItem(info); + if (!isDuplicateRemediation(r, info)) { + r.addRemediationsItem(info); + } }); return true; } else { var info = buildRemediationInfo(purlStatus, r.getFixedIn() != null && !r.getFixedIn().isEmpty()); - if (info != null) { + if (info != null && !isDuplicateRemediation(r, info)) { r.addRemediationsItem(info); return true; } @@ -323,6 +326,21 @@ private boolean processRemediations(JsonNode purlStatus, Remediation r) { return false; } + private boolean isDuplicateRemediation(Remediation r, RemediationInfo info) { + var existing = r.getRemediations(); + if (existing == null) { + return false; + } + return existing.stream() + .anyMatch( + e -> + Objects.equals(e.getCategory(), info.getCategory()) + && Objects.equals(e.getDetails(), info.getDetails()) + && Objects.equals( + e.getAdvisory() != null ? e.getAdvisory().getId() : null, + info.getAdvisory() != null ? info.getAdvisory().getId() : null)); + } + private Remediation ensureRemediation(Issue issue) { var r = issue.getRemediation(); if (r == null) { diff --git a/src/test/resources/__files/reports/batch_report.json b/src/test/resources/__files/reports/batch_report.json index 48c5d66c..52010fe4 100644 --- a/src/test/resources/__files/reports/batch_report.json +++ b/src/test/resources/__files/reports/batch_report.json @@ -388,6 +388,8 @@ } }, { + "category": "NO_FIX_PLANNED", + "details": "Out of support scope", "advisory": { "id": "CVE-2024-1597", "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", @@ -401,34 +403,6 @@ "url": "https://www.redhat.com/#CVE-2024-1597" } }, - { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { - "advisory": { - "id": "RHSA-2024:1662", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1662" - } - }, - { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { - "advisory": { - "id": "RHSA-2024:1797", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1797" - } - }, { "advisory": { "id": "RHSA-2024:1662", diff --git a/src/test/resources/__files/reports/report.json b/src/test/resources/__files/reports/report.json index d5c47c57..9e5b325d 100644 --- a/src/test/resources/__files/reports/report.json +++ b/src/test/resources/__files/reports/report.json @@ -387,6 +387,8 @@ } }, { + "category": "NO_FIX_PLANNED", + "details": "Out of support scope", "advisory": { "id": "CVE-2024-1597", "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", @@ -400,34 +402,6 @@ "url": "https://www.redhat.com/#CVE-2024-1597" } }, - { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { - "advisory": { - "id": "RHSA-2024:1662", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1662" - } - }, - { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { - "advisory": { - "id": "RHSA-2024:1797", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1797" - } - }, { "advisory": { "id": "RHSA-2024:1662", diff --git a/src/test/resources/__files/trustify/maven_report.json b/src/test/resources/__files/trustify/maven_report.json index dcad1eb2..fd417e6e 100644 --- a/src/test/resources/__files/trustify/maven_report.json +++ b/src/test/resources/__files/trustify/maven_report.json @@ -348,7 +348,13 @@ }, "status": "affected", "version_range": null, - "remediations": [] + "remediations": [ + { + "category": "no_fix_planned", + "details": "Out of support scope", + "url": null + } + ] }, { "advisory": { @@ -365,7 +371,13 @@ }, "status": "affected", "version_range": null, - "remediations": [] + "remediations": [ + { + "category": "no_fix_planned", + "details": "Out of support scope", + "url": null + } + ] }, { "advisory": { From 453e951df6c12c0558036bc721c13c821678123b Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Wed, 8 Jul 2026 12:15:46 +0200 Subject: [PATCH 09/10] test(trustify): add regression test for remediation dedup across purl_statuses Reproduces the exact scenario where two purl_statuses within the same vulnerability have identical remediations (WORKAROUND + NO_FIX_PLANNED) with the same advisory document_id, verifying only 2 unique RemediationInfo items appear in the output instead of 4. Co-Authored-By: Claude Opus 4.6 --- .../trustify/TrustifyResponseHandlerTest.java | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java b/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java index 5aaa629e..5fdaabbe 100644 --- a/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java +++ b/src/test/java/io/github/guacsec/trustifyda/integration/providers/trustify/TrustifyResponseHandlerTest.java @@ -2097,4 +2097,140 @@ void testResponseToIssuesMergeKeepsHigherCvss() throws IOException { assertEquals(9.8f, issue.getCvssScore(), "Should keep the higher CVSS score"); assertEquals(Severity.CRITICAL, issue.getSeverity()); } + + @Test + void testResponseToIssuesDeduplicatesIdenticalRemediationsAcrossPurlStatuses() + throws IOException { + String jsonResponse = + """ + { + "pkg:maven/org.postgresql/postgresql@42.5.0": { + "details": [ + { + "identifier": "CVE-2023-2454", + "title": "postgresql: schema_element defeats protective search_path changes", + "description": "A schema_element vulnerability", + "base_score": { + "score": 7.2, + "severity": "HIGH" + }, + "purl_statuses": [ + { + "advisory": { + "id": "adv-a", + "document_id": "CVE-2023-2454", + "title": "postgresql: schema_element defeats protective search_path changes", + "identifier": "https://www.redhat.com/#CVE-2023-2454", + "issuer": { + "id": "issuer-1", + "name": "redhat-csaf" + } + }, + "status": "affected", + "version_range": { + "version_scheme_id": "semver", + "low_version": "0", + "low_inclusive": true, + "high_version": "42.5.5", + "high_inclusive": false + }, + "remediations": [ + { + "category": "WORKAROUND", + "details": "Use a workaround" + }, + { + "category": "NO_FIX_PLANNED", + "details": "No fix is planned" + } + ], + "scores": [ + { + "source": "cve", + "value": 7.2, + "severity": "high" + } + ] + }, + { + "advisory": { + "id": "adv-b", + "document_id": "CVE-2023-2454", + "title": "postgresql: schema_element defeats protective search_path changes", + "identifier": "https://www.redhat.com/#CVE-2023-2454", + "issuer": { + "id": "issuer-1", + "name": "redhat-csaf" + } + }, + "status": "affected", + "version_range": { + "version_scheme_id": "semver", + "low_version": "0", + "low_inclusive": true, + "high_version": "42.6.1", + "high_inclusive": false + }, + "remediations": [ + { + "category": "WORKAROUND", + "details": "Use a workaround" + }, + { + "category": "NO_FIX_PLANNED", + "details": "No fix is planned" + } + ], + "scores": [ + { + "source": "cve", + "value": 7.2, + "severity": "high" + } + ] + } + ] + } + ], + "warnings": [] + } + } + """; + + byte[] responseBytes = jsonResponse.getBytes(); + ProviderResponse result = + handler.responseToIssues(buildExchange(responseBytes, dependencyTree)); + + PackageItem packageItem = result.pkgItems().get("pkg:maven/org.postgresql/postgresql@42.5.0"); + assertNotNull(packageItem); + List issues = packageItem.issues(); + assertEquals(1, issues.size(), "Same CVE+source should merge into one issue"); + + Issue issue = issues.get(0); + assertEquals("CVE-2023-2454", issue.getId()); + assertNotNull(issue.getRemediation()); + + List remInfos = issue.getRemediation().getRemediations(); + assertNotNull(remInfos); + assertEquals( + 2, + remInfos.size(), + "Should have exactly 2 unique remediations (WORKAROUND + NO_FIX_PLANNED), not 4"); + + long workaroundCount = + remInfos.stream() + .filter(r -> RemediationCategory.WORKAROUND.equals(r.getCategory())) + .count(); + long noFixCount = + remInfos.stream() + .filter(r -> RemediationCategory.NO_FIX_PLANNED.equals(r.getCategory())) + .count(); + assertEquals(1, workaroundCount, "WORKAROUND should appear exactly once"); + assertEquals(1, noFixCount, "NO_FIX_PLANNED should appear exactly once"); + + assertEquals( + 2, issue.getRemediation().getFixedIn().size(), "Should accumulate fixedIn from both"); + assertTrue(issue.getRemediation().getFixedIn().contains("42.5.5")); + assertTrue(issue.getRemediation().getFixedIn().contains("42.6.1")); + } } From 3ccbe071f0208448d9a0a400257869fe28162bec Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Wed, 8 Jul 2026 14:01:48 +0200 Subject: [PATCH 10/10] fix(test): update integration test fixtures for advisory attribution and dedup The report.json and batch_report.json fixtures now reflect the actual handler output after advisory attribution and remediation deduplication were added. Co-Authored-By: Claude Opus 4.6 --- .../__files/reports/batch_report.json | 137 ++++------------- .../resources/__files/reports/report.json | 139 +++++------------- 2 files changed, 65 insertions(+), 211 deletions(-) diff --git a/src/test/resources/__files/reports/batch_report.json b/src/test/resources/__files/reports/batch_report.json index 52010fe4..05701020 100644 --- a/src/test/resources/__files/reports/batch_report.json +++ b/src/test/resources/__files/reports/batch_report.json @@ -53,16 +53,16 @@ "unique": false, "remediation": { "remediations": [ - { - "category": "VENDOR_FIX", - "details": "Upgrade to version 42.7.2 or later", - "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", - "advisory": { - "id": "GHSA-24rp-q3w6-vc56", - "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + { + "category": "VENDOR_FIX", + "details": "Upgrade to version 42.7.2 or later", + "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } } - } - ] + ] } }, { @@ -125,16 +125,16 @@ "unique": false, "remediation": { "remediations": [ - { - "category": "VENDOR_FIX", - "details": "Upgrade to version 42.7.2 or later", - "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", - "advisory": { - "id": "GHSA-24rp-q3w6-vc56", - "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" - } - } - ] + { + "category": "VENDOR_FIX", + "details": "Upgrade to version 42.7.2 or later", + "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } + } + ] } } }, @@ -182,16 +182,16 @@ "unique": false, "remediation": { "remediations": [ - { - "category": "WORKAROUND", - "details": "Disable UNWRAP_SINGLE_VALUE_ARRAYS feature or upgrade to 2.13.4.1 or later", - "url": "https://github.com/FasterXML/jackson-databind/issues/3590", - "advisory": { - "id": "GHSA-jjjh-jjxp-wpff", - "title": "Uncontrolled Resource Consumption in Jackson-databind" + { + "category": "WORKAROUND", + "details": "Disable UNWRAP_SINGLE_VALUE_ARRAYS feature or upgrade to 2.13.4.1 or later", + "url": "https://github.com/FasterXML/jackson-databind/issues/3590", + "advisory": { + "id": "GHSA-jjjh-jjxp-wpff", + "title": "Uncontrolled Resource Consumption in Jackson-databind" + } } - } - ] + ] } }, { @@ -434,13 +434,8 @@ } }, { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { + "category": "NO_FIX_PLANNED", + "details": "Out of support scope", "advisory": { "id": "CVE-2024-1597", "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", @@ -454,27 +449,6 @@ "url": "https://www.redhat.com/#CVE-2024-1597" } }, - { - "advisory": { - "id": "RHSA-2024:1662", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1662" - } - }, - { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { - "advisory": { - "id": "RHSA-2024:1797", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1797" - } - }, { "advisory": { "id": "RHSA-2024:1662", @@ -507,6 +481,8 @@ } }, { + "category": "NO_FIX_PLANNED", + "details": "Out of support scope", "advisory": { "id": "CVE-2024-1597", "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", @@ -520,34 +496,6 @@ "url": "https://www.redhat.com/#CVE-2024-1597" } }, - { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { - "advisory": { - "id": "RHSA-2024:1662", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1662" - } - }, - { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { - "advisory": { - "id": "RHSA-2024:1797", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1797" - } - }, { "advisory": { "id": "RHSA-2024:1662", @@ -584,13 +532,6 @@ "url": "https://www.redhat.com/#CVE-2024-2700" } }, - { - "advisory": { - "id": "CVE-2024-2700", - "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", - "url": "https://www.redhat.com/#CVE-2024-2700" - } - }, { "advisory": { "id": "RHSA-2024:2705", @@ -628,13 +569,6 @@ "url": "https://www.redhat.com/#CVE-2024-2700" } }, - { - "advisory": { - "id": "CVE-2024-2700", - "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", - "url": "https://www.redhat.com/#CVE-2024-2700" - } - }, { "advisory": { "id": "RHSA-2024:2705", @@ -673,13 +607,6 @@ "url": "https://www.redhat.com/#CVE-2024-2700" } }, - { - "advisory": { - "id": "CVE-2024-2700", - "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", - "url": "https://www.redhat.com/#CVE-2024-2700" - } - }, { "advisory": { "id": "RHSA-2024:2705", diff --git a/src/test/resources/__files/reports/report.json b/src/test/resources/__files/reports/report.json index 9e5b325d..7b1b8a95 100644 --- a/src/test/resources/__files/reports/report.json +++ b/src/test/resources/__files/reports/report.json @@ -98,16 +98,16 @@ "unique": false, "remediation": { "remediations": [ - { - "category": "VENDOR_FIX", - "details": "Upgrade to version 42.7.2 or later", - "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", - "advisory": { - "id": "GHSA-24rp-q3w6-vc56", - "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" - } + { + "category": "VENDOR_FIX", + "details": "Upgrade to version 42.7.2 or later", + "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" } - ] + } + ] } } } @@ -124,16 +124,16 @@ "unique": false, "remediation": { "remediations": [ - { - "category": "VENDOR_FIX", - "details": "Upgrade to version 42.7.2 or later", - "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", - "advisory": { - "id": "GHSA-24rp-q3w6-vc56", - "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" - } - } - ] + { + "category": "VENDOR_FIX", + "details": "Upgrade to version 42.7.2 or later", + "url": "https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-24rp-q3w6-vc56", + "advisory": { + "id": "GHSA-24rp-q3w6-vc56", + "title": "org.postgresql:postgresql vulnerable to SQL Injection via line comment generation" + } + } + ] } } }, @@ -433,13 +433,8 @@ } }, { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { + "category": "NO_FIX_PLANNED", + "details": "Out of support scope", "advisory": { "id": "CVE-2024-1597", "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", @@ -453,27 +448,6 @@ "url": "https://www.redhat.com/#CVE-2024-1597" } }, - { - "advisory": { - "id": "RHSA-2024:1662", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1662" - } - }, - { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { - "advisory": { - "id": "RHSA-2024:1797", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1797" - } - }, { "advisory": { "id": "RHSA-2024:1662", @@ -506,13 +480,8 @@ } }, { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { + "category": "NO_FIX_PLANNED", + "details": "Out of support scope", "advisory": { "id": "CVE-2024-1597", "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", @@ -526,27 +495,6 @@ "url": "https://www.redhat.com/#CVE-2024-1597" } }, - { - "advisory": { - "id": "RHSA-2024:1662", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 3.2.11 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1662" - } - }, - { - "advisory": { - "id": "CVE-2024-1597", - "title": "pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL if using PreferQueryMode=SIMPLE", - "url": "https://www.redhat.com/#CVE-2024-1597" - } - }, - { - "advisory": { - "id": "RHSA-2024:1797", - "title": "Red Hat Security Advisory: Red Hat build of Quarkus 2.13.9.SP2 release and security update", - "url": "https://www.redhat.com/#RHSA-2024_1797" - } - }, { "advisory": { "id": "RHSA-2024:1662", @@ -583,13 +531,6 @@ "url": "https://www.redhat.com/#CVE-2024-2700" } }, - { - "advisory": { - "id": "CVE-2024-2700", - "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", - "url": "https://www.redhat.com/#CVE-2024-2700" - } - }, { "advisory": { "id": "RHSA-2024:2705", @@ -627,13 +568,6 @@ "url": "https://www.redhat.com/#CVE-2024-2700" } }, - { - "advisory": { - "id": "CVE-2024-2700", - "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", - "url": "https://www.redhat.com/#CVE-2024-2700" - } - }, { "advisory": { "id": "RHSA-2024:2705", @@ -672,13 +606,6 @@ "url": "https://www.redhat.com/#CVE-2024-2700" } }, - { - "advisory": { - "id": "CVE-2024-2700", - "title": "quarkus-core: Leak of local configuration properties into Quarkus applications", - "url": "https://www.redhat.com/#CVE-2024-2700" - } - }, { "advisory": { "id": "RHSA-2024:2705", @@ -707,20 +634,24 @@ }, "dependencies": [ { - "ref": "pkg:maven/io.quarkus/quarkus-jdbc-postgresql@2.13.5.Final?type=jar", - "recommendation": "pkg:maven/io.quarkus/quarkus-jdbc-postgresql@2.13.5.Final-redhat-00004?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar" + "ref": "pkg:maven/jakarta.el/jakarta.el-api@3.0.3?type=jar", + "recommendation": "pkg:maven/jakarta.el/jakarta.el-api@3.0.3.redhat-00002?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar" + }, + { + "ref": "pkg:maven/jakarta.enterprise/jakarta.enterprise.cdi-api@2.0.2?type=jar", + "recommendation": "pkg:maven/jakarta.enterprise/jakarta.enterprise.cdi-api@2.0.2.redhat-00004?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar" }, { "ref": "pkg:maven/io.quarkus/quarkus-hibernate-orm@2.13.5.Final?type=jar", "recommendation": "pkg:maven/io.quarkus/quarkus-hibernate-orm@2.13.5.Final-redhat-00004?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar" }, { - "ref": "pkg:maven/jakarta.el/jakarta.el-api@3.0.3?type=jar", - "recommendation": "pkg:maven/jakarta.el/jakarta.el-api@3.0.3.redhat-00002?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar" + "ref": "pkg:maven/io.quarkus/quarkus-jdbc-postgresql@2.13.5.Final?type=jar", + "recommendation": "pkg:maven/io.quarkus/quarkus-jdbc-postgresql@2.13.5.Final-redhat-00004?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar" }, { - "ref": "pkg:maven/jakarta.enterprise/jakarta.enterprise.cdi-api@2.0.2?type=jar", - "recommendation": "pkg:maven/jakarta.enterprise/jakarta.enterprise.cdi-api@2.0.2.redhat-00004?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar" + "ref": "pkg:maven/org.postgresql/postgresql@42.5.0?type=jar", + "recommendation": "pkg:maven/org.postgresql/postgresql@42.5.0.redhat-00001?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar" }, { "ref": "pkg:maven/io.quarkus/quarkus-narayana-jta@2.13.5.Final?type=jar", @@ -734,10 +665,6 @@ "ref": "pkg:maven/jakarta.interceptor/jakarta.interceptor-api@1.2.5?type=jar", "recommendation": "pkg:maven/jakarta.interceptor/jakarta.interceptor-api@1.2.5.redhat-00003?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar" }, - { - "ref": "pkg:maven/org.postgresql/postgresql@42.5.0?type=jar", - "recommendation": "pkg:maven/org.postgresql/postgresql@42.5.0.redhat-00001?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar" - }, { "ref": "pkg:maven/io.quarkus/quarkus-core@2.13.5.Final?type=jar", "recommendation": "pkg:maven/io.quarkus/quarkus-core@2.13.5.Final-redhat-00004?repository_url=https%3A%2F%2Fmaven.repository.redhat.com%2Fga%2F&type=jar"