Skip to content

Commit 27779e4

Browse files
committed
Import EPSS data from Anchore Grype scans
Grype added EPSS metrics in v0.92.0, see: https://github.com/anchore/grype/releases/tag/v0.92.0 Adds EPSS support with a test based on the same busybox image used in anchore_grype/no_vuln.json. Also removes the hardcoded CWE value as Grype does not support CWE data.
1 parent 7cf5b09 commit 27779e4

File tree

4 files changed

+2033
-11
lines changed

4 files changed

+2033
-11
lines changed

docs/content/en/connecting_your_tools/parsers/file/anchore_grype.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ toc_hide: true
55
### File Types
66
DefectDojo parser accepts a .json file.
77

8-
Anchore Grype JSON files are created using the Grype CLI, using the '-o json' option. See: https://github.com/anchore/grype
8+
Anchore Grype JSON files are created using the Grype CLI, using the '--output=json' option. See: https://github.com/anchore/grype
99

1010
**Example:**
1111
{{< highlight bash >}}
12-
grype yourApp/example-page -o json > example_vulns.json
12+
grype yourApp/example-page --output=json=example_vulns.json
1313
{{< /highlight >}}
1414

1515
### Acceptable JSON Format

dojo/tools/anchore_grype/parser.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ def get_label_for_scan_types(self, scan_type):
2222

2323
def get_description_for_scan_types(self, scan_type):
2424
return (
25-
"A vulnerability scanner for container images and filesystems. JSON report generated with '-o json' "
26-
"format"
25+
"A vulnerability scanner for container images, filesystems, and SBOMs. "
26+
"JSON report generated with '--output=json' format."
2727
)
2828

2929
def get_findings(self, file, test):
@@ -41,11 +41,13 @@ def get_findings(self, file, test):
4141
if "fix" in vulnerability:
4242
vuln_fix_versions = vulnerability["fix"].get("versions")
4343
vuln_cvss = vulnerability.get("cvss")
44+
vuln_epss = vulnerability.get("epss")
4445

4546
rel_datasource = None
4647
rel_urls = None
4748
rel_description = None
4849
rel_cvss = None
50+
rel_epss = None
4951
vulnerability_ids = None
5052
related_vulnerabilities = item.get("relatedVulnerabilities")
5153
if related_vulnerabilities:
@@ -54,6 +56,7 @@ def get_findings(self, file, test):
5456
rel_urls = related_vulnerability.get("urls")
5557
rel_description = related_vulnerability.get("description")
5658
rel_cvss = related_vulnerability.get("cvss")
59+
rel_epss = related_vulnerability.get("epss")
5760
vulnerability_ids = self.get_vulnerability_ids(
5861
vuln_id, related_vulnerabilities,
5962
)
@@ -160,6 +163,10 @@ def get_findings(self, file, test):
160163
if not finding_cvss3 and rel_cvss:
161164
finding_cvss3 = self.get_cvss(rel_cvss)
162165

166+
finding_epss_score, finding_epss_percentile = self.get_epss_values(vuln_id, vuln_epss)
167+
if finding_epss_score is None and rel_epss:
168+
finding_epss_score, finding_epss_percentile = self.get_epss_values(vuln_id, rel_epss)
169+
163170
dupe_key = finding_title
164171
if dupe_key in dupes:
165172
finding = dupes[dupe_key]
@@ -168,8 +175,9 @@ def get_findings(self, file, test):
168175
dupes[dupe_key] = Finding(
169176
title=finding_title.replace("\x00", ""),
170177
description=finding_description.replace("\x00", ""),
171-
cwe=1352,
172178
cvssv3=finding_cvss3,
179+
epss_score=finding_epss_score,
180+
epss_percentile=finding_epss_percentile,
173181
severity=vuln_severity,
174182
mitigation=finding_mitigation,
175183
references=finding_references,
@@ -202,6 +210,20 @@ def get_cvss(self, cvss):
202210
return vector
203211
return None
204212

213+
def get_epss_values(self, vuln_id, epss_list):
214+
if isinstance(epss_list, list):
215+
for epss_data in epss_list:
216+
if epss_data.get("cve") != vuln_id:
217+
continue
218+
try:
219+
epss_score = float(epss_data.get("epss"))
220+
epss_percentile = float(epss_data.get("percentile"))
221+
except (TypeError, ValueError):
222+
pass
223+
else:
224+
return epss_score, epss_percentile
225+
return None, None
226+
205227
def get_vulnerability_ids(self, vuln_id, related_vulnerabilities):
206228
vulnerability_ids = []
207229
if vuln_id:

0 commit comments

Comments
 (0)