Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 8 additions & 117 deletions dojo/tools/dependency_track/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,106 +13,6 @@

class DependencyTrackParser:

r"""
A class that can be used to parse the JSON Finding Packaging Format (FPF) export from OWASP Dependency Track.

See here for more info on this JSON format: https://docs.dependencytrack.org/integrations/file-formats/

A typical Finding Packaging Format (FPF) export looks like the following:

{
"version": "1.3",
"meta" : {
"application": "Dependency-Track",
"version": "4.5.0",
"timestamp": "2022-02-18T23:31:42Z",
"baseUrl": "http://dtrack.example.org"
},
"project" : {
"uuid": "ca4f2da9-0fad-4a13-92d7-f627f3168a56",
"name": "Acme Example",
"version": "1.0",
"description": "A sample application"
},
"findings" : [
{
"component": {
"uuid": "b815b581-fec1-4374-a871-68862a8f8d52",
"name": "timespan",
"version": "2.3.0",
"purl": "pkg:npm/timespan@2.3.0",
"latestVersion": "3.2.0"
},
"vulnerability": {
"uuid": "115b80bb-46c4-41d1-9f10-8a175d4abb46",
"source": "NPM",
"vulnId": "533",
"title": "Regular Expression Denial of Service",
"subtitle": "timespan",
"severity": "LOW",
"severityRank": 3,
"cvssV2Vector": "CVSS:2.0/AV:N/AC:L/Au:N/C:P/I:P/A:P",
"cvssV3Vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"cvssV4Vector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N",
"references": "* [https://example.com](https://example.com)\n* [https://example.org](https://example.org)",
"published": "2025-07-11 03:16:03.563",
"cweId": 400,
"cweName": "Uncontrolled Resource Consumption ('Resource Exhaustion')",
"cwes": [
{
"cweId": 400,
"name": "Uncontrolled Resource Consumption ('Resource Exhaustion')"
}
],
"description": "Affected versions of `timespan`...",
"recommendation": "No direct patch is available..."
},
"analysis": {
"state": "NOT_SET",
"isSuppressed": false
},
"matrix": "ca4f2da9-0fad-4a13-92d7-f627f3168a56:b815b581-fec1-4374-a871-68862a8f8d52:115b80bb-46c4-41d1-9f10-8a175d4abb46"
},
{
"component": {
"uuid": "979f87f5-eaf5-4095-9d38-cde17bf9228e",
"name": "uglify-js",
"version": "2.4.24",
"purl": "pkg:npm/uglify-js@2.4.24"
},
"vulnerability": {
"uuid": "701a3953-666b-4b7a-96ca-e1e6a3e1def3",
"source": "NPM",
"vulnId": "48",
"aliases": [
{
"cveId": "CVE-2022-2053",
"ghsaId": "GHSA-95rf-557x-44g5"
}
],
"title": "Regular Expression Denial of Service",
"subtitle": "uglify-js",
"severity": "LOW",
"severityRank": 3,
"cweId": 400,
"cweName": "Uncontrolled Resource Consumption ('Resource Exhaustion')",
"cwes": [
{
"cweId": 400,
"name": "Uncontrolled Resource Consumption ('Resource Exhaustion')"
}
],
"description": "Versions of `uglify-js` prior to...",
"recommendation": "Update to version 2.6.0 or later."
},
"analysis": {
"isSuppressed": false
},
"matrix": "ca4f2da9-0fad-4a13-92d7-f627f3168a56:979f87f5-eaf5-4095-9d38-cde17bf9228e:701a3953-666b-4b7a-96ca-e1e6a3e1def3"
}]
}
"""

def _convert_dependency_track_severity_to_dojo_severity(self, dependency_track_severity):
"""
Converts a Dependency Track severity to a DefectDojo severity.
Expand Down Expand Up @@ -171,23 +71,14 @@ def _convert_dependency_track_finding_to_dojo_finding(self, dependency_track_fin

title = f"{component_name}:{version_description} affected by: {vuln_id} ({source})"

# We should collect all the vulnerability ids, the FPF format can add additional IDs as aliases
# we add these aliases in the vulnerability_id list making sure duplicate findings get correctly deduplicated
# older version of Dependency-track might not include these field therefore lets check first
if dependency_track_finding["vulnerability"].get("aliases"):
# There can be multiple alias entries
set_of_ids = set()
set_of_sources = {"cveId", "sonatypeId", "ghsaId", "osvId", "snykId", "gsdId", "vulnDbId"}
for alias in dependency_track_finding["vulnerability"]["aliases"]:
for source in set_of_sources:
if source in alias:
set_of_ids.add(alias[source])
vulnerability_id = list(set_of_ids)
else:
# The vulnId is not always a CVE (e.g. if the vulnerability is not from the NVD source)
# So here we set the cve for the DefectDojo finding to null unless the source of the
# Dependency Track vulnerability is NVD
vulnerability_id = [vuln_id] if source is not None and source.upper() == "NVD" else None
# Collect all vulnerability IDs: vulnId itself plus any aliases
set_of_ids = {vuln_id}
set_of_alias_sources = {"cveId", "sonatypeId", "ghsaId", "osvId", "snykId", "gsdId", "vulnDbId"}
for alias in dependency_track_finding["vulnerability"].get("aliases") or []:
for alias_source in set_of_alias_sources:
if alias_source in alias:
set_of_ids.add(alias[alias_source])
vulnerability_id = list(set_of_ids)

# Default CWE to CWE-1035 Using Components with Known Vulnerabilities if there is no CWE
if "cweId" in dependency_track_finding["vulnerability"] and dependency_track_finding["vulnerability"]["cweId"] is not None:
Expand Down
Loading
Loading