Is your feature request related to a problem? Please describe
A Dependency-Track finding says which package is vulnerable and nothing about where it is used, so triage starts by searching the source by hand. When packages are built in one repository and consumed in another, that search often lands in the wrong repository and the finding gets closed as not applicable by a team that really cannot find the package in their own code.
The Dependency-Track parser creates a location per finding with the purl and nothing else:
finding.unsaved_locations.append(
LocationData.dependency(purl=component_purl),
)
Other SCA parsers already fill file_path on the same factory:
anchore_grype: LocationData.dependency(purl=artifact_purl, file_path=file_path)
dependency_check: LocationData.dependency(purl=component_purl, file_path=dependency_filename)
gitlab_dep_scan: file_path=file_path
govulncheck: file_path=path
jfrog_xray_api_summary_artifact: file_path=impact_path
blackduck_binary_analysis: file_path=file_path
So the Dependency-Track parser is the one that leaves it empty.
Describe the solution you'd like
As someone triaging Dependency-Track findings in DefectDojo, I want the dependency locations to carry the paths Dependency-Track reports for the component, the way the parsers above do, so that I can see where a vulnerable package is used without leaving the finding.
When the report carries the component's occurrences, add one dependency location per occurrence with file_path set from it, instead of one location holding only the purl. unsaved_locations is already a list, so several locations per finding need nothing new.
One finding stays one finding. #14941 folded Dependency-Check's related paths into the description to stop that parser emitting a finding per path, and this is not a step back towards it: the occurrences become locations on the one finding, never findings of their own.
This is parity rather than new surface: no model, no new Finding field, no UI page, no API route, and file_path on a dependency location is already in use by six parsers. I would still like pre-approval before opening a PR, per the contributing guide.
Describe alternatives you've considered
The description. The parser appends analysis.detail as Audit Detail: ..., which is where our paths end up today, and #14941 does something similar with a **Related Filepaths:** block for Dependency-Check. It reads fine. What it does not do is let anyone filter on a path, which LocationFilter gives for locations, and the formatting is whatever the producer happened to write.
Putting the real path in finding.file_path. That breaks deduplication, which depends on the purl being there, per the parser comment and #3647.
Fetching the occurrences from Dependency-Track. The parser is handed the uploaded report through get_findings(self, file, test) and sees nothing else, and a file parser should not be making network calls.
Additional context
The blocker is upstream rather than here. Dependency-Track's Finding Packaging Format carries component.hasOccurrences as a boolean and no occurrences, so the parser has nothing to read. Dependency-Track does hold the data: our js BOMs carry evidence.occurrences, it imports them and shows them in its component view, and only the export drops them. I have asked for the export side there: DependencyTrack/dependency-track#7291.
Filing this separately so the consumer half is written down, and so the shape can be settled before the data turns up.
Is your feature request related to a problem? Please describe
A Dependency-Track finding says which package is vulnerable and nothing about where it is used, so triage starts by searching the source by hand. When packages are built in one repository and consumed in another, that search often lands in the wrong repository and the finding gets closed as not applicable by a team that really cannot find the package in their own code.
The Dependency-Track parser creates a location per finding with the purl and nothing else:
Other SCA parsers already fill
file_pathon the same factory:anchore_grype:LocationData.dependency(purl=artifact_purl, file_path=file_path)dependency_check:LocationData.dependency(purl=component_purl, file_path=dependency_filename)gitlab_dep_scan:file_path=file_pathgovulncheck:file_path=pathjfrog_xray_api_summary_artifact:file_path=impact_pathblackduck_binary_analysis:file_path=file_pathSo the Dependency-Track parser is the one that leaves it empty.
Describe the solution you'd like
As someone triaging Dependency-Track findings in DefectDojo, I want the dependency locations to carry the paths Dependency-Track reports for the component, the way the parsers above do, so that I can see where a vulnerable package is used without leaving the finding.
When the report carries the component's occurrences, add one dependency location per occurrence with
file_pathset from it, instead of one location holding only the purl.unsaved_locationsis already a list, so several locations per finding need nothing new.One finding stays one finding. #14941 folded Dependency-Check's related paths into the description to stop that parser emitting a finding per path, and this is not a step back towards it: the occurrences become locations on the one finding, never findings of their own.
This is parity rather than new surface: no model, no new Finding field, no UI page, no API route, and
file_pathon a dependency location is already in use by six parsers. I would still like pre-approval before opening a PR, per the contributing guide.Describe alternatives you've considered
The description. The parser appends
analysis.detailasAudit Detail: ..., which is where our paths end up today, and #14941 does something similar with a**Related Filepaths:**block for Dependency-Check. It reads fine. What it does not do is let anyone filter on a path, whichLocationFiltergives for locations, and the formatting is whatever the producer happened to write.Putting the real path in
finding.file_path. That breaks deduplication, which depends on the purl being there, per the parser comment and #3647.Fetching the occurrences from Dependency-Track. The parser is handed the uploaded report through
get_findings(self, file, test)and sees nothing else, and a file parser should not be making network calls.Additional context
The blocker is upstream rather than here. Dependency-Track's Finding Packaging Format carries
component.hasOccurrencesas a boolean and no occurrences, so the parser has nothing to read. Dependency-Track does hold the data: our js BOMs carryevidence.occurrences, it imports them and shows them in its component view, and only the export drops them. I have asked for the export side there: DependencyTrack/dependency-track#7291.Filing this separately so the consumer half is written down, and so the shape can be settled before the data turns up.