From 27987b03f703775f741fc3106b49945101c9e756 Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Thu, 28 May 2026 20:49:07 +0200 Subject: [PATCH 1/6] test(model): add failing tests for analysis.detail in Finding Signed-off-by: webdevred <148627186+webdevred@users.noreply.github.com> --- .../integrations/FindingPackagingFormatTest.java | 6 ++++-- src/test/java/org/dependencytrack/model/FindingTest.java | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/dependencytrack/integrations/FindingPackagingFormatTest.java b/src/test/java/org/dependencytrack/integrations/FindingPackagingFormatTest.java index d610ae6487..595f200f38 100644 --- a/src/test/java/org/dependencytrack/integrations/FindingPackagingFormatTest.java +++ b/src/test/java/org/dependencytrack/integrations/FindingPackagingFormatTest.java @@ -92,7 +92,8 @@ void testFindingsVulnerabilityAndAliases() { null, // 32 null, // 33 AnalysisState.NOT_AFFECTED, // 34 - true // 35 + true, // 35 + null // 36 ); Finding findingWithAlias = new Finding(project.getUuid(), "component-uuid-2", "component-name-2", "component-group", @@ -119,7 +120,8 @@ void testFindingsVulnerabilityAndAliases() { null, // 32 null, // 33 AnalysisState.NOT_AFFECTED, // 34 - true // 35 + true, // 35 + null // 36 ); var alias = new VulnerabilityAlias(); diff --git a/src/test/java/org/dependencytrack/model/FindingTest.java b/src/test/java/org/dependencytrack/model/FindingTest.java index 3c7f09f652..7d1a6fbac4 100644 --- a/src/test/java/org/dependencytrack/model/FindingTest.java +++ b/src/test/java/org/dependencytrack/model/FindingTest.java @@ -58,7 +58,8 @@ class FindingTest extends PersistenceCapableTest { null, // 32 null, // 33 AnalysisState.NOT_AFFECTED, // 34 - true // 35 + true, // 35 + "analysis-detail" // 36 ); @Test @@ -102,6 +103,7 @@ void testAnalysis() { Map map = finding.getAnalysis(); Assertions.assertEquals(AnalysisState.NOT_AFFECTED, map.get("state")); Assertions.assertEquals(true, map.get("isSuppressed")); + Assertions.assertEquals("analysis-detail", map.get("detail")); } @Test From 590bb29e2122ef761938d0ee76636e26edc1d102 Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Thu, 28 May 2026 20:49:12 +0200 Subject: [PATCH 2/6] feat(model): include analysis.detail in Finding query and constructor Signed-off-by: webdevred <148627186+webdevred@users.noreply.github.com> --- .../java/org/dependencytrack/model/Finding.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/dependencytrack/model/Finding.java b/src/main/java/org/dependencytrack/model/Finding.java index 400c615dc5..a49f7f21dc 100644 --- a/src/main/java/org/dependencytrack/model/Finding.java +++ b/src/main/java/org/dependencytrack/model/Finding.java @@ -96,6 +96,7 @@ public class Finding implements Serializable { , "FINDINGATTRIBUTION"."REFERENCE_URL" , "ANALYSIS"."STATE" , "ANALYSIS"."SUPPRESSED" + , "ANALYSIS"."DETAILS" FROM "COMPONENT" INNER JOIN "COMPONENTS_VULNERABILITIES" ON "COMPONENT"."ID" = "COMPONENTS_VULNERABILITIES"."COMPONENT_ID" @@ -151,6 +152,7 @@ public class Finding implements Serializable { , "FINDINGATTRIBUTION"."REFERENCE_URL" , "ANALYSIS"."STATE" , "ANALYSIS"."SUPPRESSED" + , "ANALYSIS"."DETAILS" , "PROJECT"."UUID" , "PROJECT"."NAME" , "PROJECT"."VERSION" @@ -245,10 +247,15 @@ public Finding(UUID project, Object... o) { optValue(analysis, "state", o[34]); optValue(analysis, "isSuppressed", o[35], false); + if (o[36] instanceof final Clob clob) { + optValue(analysis, "detail", toString(clob)); + } else { + optValue(analysis, "detail", o[36]); + } - if (o.length > 36) { - optValue(component, "projectName", o[37]); - optValue(component, "projectVersion", o[38]); + if (o.length > 37) { + optValue(component, "projectName", o[38]); + optValue(component, "projectVersion", o[39]); } } From 18d08bcfc6a6e85990db9687285114705b8bd70a Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Thu, 28 May 2026 21:05:09 +0200 Subject: [PATCH 3/6] fix(model): update QUERY_ALL_FINDINGS project UUID index after DETAILS column shift Signed-off-by: webdevred <148627186+webdevred@users.noreply.github.com> --- .../dependencytrack/persistence/FindingsSearchQueryManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/dependencytrack/persistence/FindingsSearchQueryManager.java b/src/main/java/org/dependencytrack/persistence/FindingsSearchQueryManager.java index a91de4dbaa..9406bbf10a 100644 --- a/src/main/java/org/dependencytrack/persistence/FindingsSearchQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/FindingsSearchQueryManager.java @@ -137,7 +137,7 @@ public PaginatedResult getAllFindings(final Map filters, final b final List list = totalList.subList(this.pagination.getOffset(), Math.min(this.pagination.getOffset() + this.pagination.getLimit(), totalList.size())); final List findings = new ArrayList<>(); for (final Object[] o : list) { - final Finding finding = new Finding(UUID.fromString((String) o[36]), o); + final Finding finding = new Finding(UUID.fromString((String) o[37]), o); final Component component = getObjectByUuid(Component.class, (String) finding.getComponent().get("uuid")); final Vulnerability vulnerability = getObjectByUuid(Vulnerability.class, (String) finding.getVulnerability().get("uuid")); final Analysis analysis = getAnalysis(component, vulnerability); From 0b9ba5f6a9464b1763fa573d03176c71645ff6c4 Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Thu, 28 May 2026 21:11:01 +0200 Subject: [PATCH 4/6] test(integrations): verify analysis.detail propagates through QUERY_ALL_FINDINGS Signed-off-by: webdevred <148627186+webdevred@users.noreply.github.com> --- .../resources/v1/FindingResourceTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/org/dependencytrack/resources/v1/FindingResourceTest.java b/src/test/java/org/dependencytrack/resources/v1/FindingResourceTest.java index f6f58a9b16..1ce28e73d6 100644 --- a/src/test/java/org/dependencytrack/resources/v1/FindingResourceTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/FindingResourceTest.java @@ -31,6 +31,7 @@ import jakarta.ws.rs.core.Response; import org.dependencytrack.JerseyTestExtension; import org.dependencytrack.ResourceTest; +import org.dependencytrack.model.AnalysisState; import org.dependencytrack.model.Component; import org.dependencytrack.model.ConfigPropertyConstants; import org.dependencytrack.model.Project; @@ -419,6 +420,24 @@ void getAllFindings() { Assertions.assertEquals(p2.getUuid().toString(), json.getJsonObject(4).getJsonObject("component").getString("project")); } + @Test + void getAllFindingsIncludesAnalysisDetail() { + Project project = qm.createProject("Acme Example", null, "1.0", null, null, null, true, false); + Component component = createComponent(project, "Component A", "1.0"); + Vulnerability vuln = createVulnerability("Vuln-1", Severity.HIGH); + qm.addVulnerability(vuln, component, AnalyzerIdentity.NONE); + qm.makeAnalysis(component, vuln, AnalysisState.NOT_AFFECTED, null, null, "audit detail text", false); + + Response response = jersey.target(V1_FINDING).request() + .header(X_API_KEY, apiKey) + .get(Response.class); + + Assertions.assertEquals(200, response.getStatus()); + JsonArray json = parseJsonArray(response); + Assertions.assertEquals(1, json.size()); + Assertions.assertEquals("audit detail text", json.getJsonObject(0).getJsonObject("analysis").getString("detail")); + } + @Test void getAllFindingsWithAclEnabled() { Project p1 = qm.createProject("Acme Example", null, "1.0", null, null, null, true, false); From ebb2d0364c446f2d6705142e4bd843e9d244ecc5 Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Thu, 28 May 2026 22:49:19 +0200 Subject: [PATCH 5/6] docs(integrations): document forwarded analysis fields for DefectDojo Signed-off-by: webdevred <148627186+webdevred@users.noreply.github.com> --- docs/_docs/integrations/defectdojo.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/_docs/integrations/defectdojo.md b/docs/_docs/integrations/defectdojo.md index ce8a130a01..46386e518f 100644 --- a/docs/_docs/integrations/defectdojo.md +++ b/docs/_docs/integrations/defectdojo.md @@ -14,6 +14,16 @@ Dependency-Track accomplishes this in the following ways: * Dependency-Track pushes findings to DefectDojo on a periodic basis (configurable) * DefectDojo parses Dependency-Track findings +### Forwarded analysis data + +Each finding pushed to DefectDojo includes the following fields from the audit trail in Dependency-Track: + +| Field | Description | +| ---------------------- | ----------- | +| `analysis.state` | The triage state (e.g. `IN_TRIAGE`, `FALSE_POSITIVE`). A state of `FALSE_POSITIVE` marks the finding as a false positive in DefectDojo. | +| `analysis.isSuppressed`| Whether the finding is suppressed in Dependency-Track. | +| `analysis.detail` | Free-text analyst notes entered in Dependency-Track. Requires Dependency-Track v4.14.0 or higher and a compatible version of the DefectDojo Dependency Track parser. | + Requirements: * Dependency-Track v4.1.0 or higher * DefectDojo 1.13.1 or higher From 70c21703d8dea860e0ed14d0d05f44175b76c452 Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Thu, 28 May 2026 22:51:44 +0200 Subject: [PATCH 6/6] docs(integrations): clarify how analysis.state is handled by DefectDojo Signed-off-by: webdevred <148627186+webdevred@users.noreply.github.com> --- docs/_docs/integrations/defectdojo.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/_docs/integrations/defectdojo.md b/docs/_docs/integrations/defectdojo.md index 46386e518f..f611c5fdb6 100644 --- a/docs/_docs/integrations/defectdojo.md +++ b/docs/_docs/integrations/defectdojo.md @@ -16,13 +16,13 @@ Dependency-Track accomplishes this in the following ways: ### Forwarded analysis data -Each finding pushed to DefectDojo includes the following fields from the audit trail in Dependency-Track: +Each finding pushed to DefectDojo includes audit data from Dependency-Track. The following fields influence how DefectDojo represents the finding: | Field | Description | | ---------------------- | ----------- | -| `analysis.state` | The triage state (e.g. `IN_TRIAGE`, `FALSE_POSITIVE`). A state of `FALSE_POSITIVE` marks the finding as a false positive in DefectDojo. | +| `analysis.state` | A state of `FALSE_POSITIVE` marks the finding as a false positive in DefectDojo. Other states are included in the payload but are not acted on by the DefectDojo parser. | | `analysis.isSuppressed`| Whether the finding is suppressed in Dependency-Track. | -| `analysis.detail` | Free-text analyst notes entered in Dependency-Track. Requires Dependency-Track v4.14.0 or higher and a compatible version of the DefectDojo Dependency Track parser. | +| `analysis.detail` | Free-text analyst notes entered in Dependency-Track. Appended to the finding description in DefectDojo. Requires Dependency-Track v4.14.0 or higher and a compatible version of the DefectDojo Dependency Track parser. | Requirements: * Dependency-Track v4.1.0 or higher