@@ -205,11 +205,18 @@ func GetEngagementFindings(ddService defectdojo.DefectDojoService, projectName s
205205// findings just created by the sync import). All local findings are returned —
206206// nothing is filtered out.
207207//
208- // Two complementary hash strategies are used to match a local finding to its DD
208+ // Three complementary hash strategies are used to match a local finding to its DD
209209// counterpart:
210210//
211- // 1. hash(severity|filePath|line|mitigation) — primary path for Grype and KICS.
212- // 2. UniqueIdFromTool — covers OpenGrep (hash injected into extra.fingerprint
211+ // 1. hash(severity|filePath|line|mitigation) — primary path for KICS, whose
212+ // Recommendation is a raw field (expected_value) that DD's parser passes
213+ // through verbatim into Mitigation.
214+ // 2. hash(severity|filePath|line|vulnerability_id) — primary path for Grype.
215+ // DefectDojo's Anchore Grype parser synthesizes its own Mitigation wording
216+ // (e.g. "Upgrade to version: X" instead of ScopeGuardian's "Upgrade to X"),
217+ // so matching on that text is unreliable. The CVE/GHSA id, however, is
218+ // copied through verbatim and returned in vulnerability_ids.
219+ // 3. UniqueIdFromTool — covers OpenGrep (hash injected into extra.fingerprint
213220// before upload; DD's Semgrep parser stores it as unique_id_from_tool).
214221func MarkFindingsByDDFindings (local []models.Finding , ddFindings []defectdojo.Finding ) []models.Finding {
215222 type ddStatus struct {
@@ -228,9 +235,13 @@ func MarkFindingsByDDFindings(local []models.Finding, ddFindings []defectdojo.Fi
228235 riskAccepted : f .RiskAccepted ,
229236 falseP : f .FalseP ,
230237 }
231- // Strategy 1: hash from API fields — covers Grype and KICS.
238+ // Strategy 1: hash from API fields — covers KICS.
232239 ddMap [models .ComputeFindingHash (f .Severity , f .FilePath , f .Line , f .Mitigation )] = s
233- // Strategy 2: UniqueIdFromTool — covers OpenGrep.
240+ // Strategy 2: hash from vulnerability id — covers Grype.
241+ for _ , v := range f .VulnerabilityIds {
242+ ddMap [models .ComputeFindingHash (f .Severity , f .FilePath , f .Line , v .VulnerabilityId )] = s
243+ }
244+ // Strategy 3: UniqueIdFromTool — covers OpenGrep.
234245 if f .UniqueIdFromTool != "" {
235246 ddMap [f .UniqueIdFromTool ] = s
236247 }
0 commit comments