Skip to content

Commit 6fbe2e0

Browse files
authored
Handle unknown severity and null severity as untriaged / Add source column to the markdown table (#77)
Co-authored-by: Kenji Sugimura <kensugim@amazon.co.jp>
1 parent 32f23a4 commit 6fbe2e0

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

entrypoint/entrypoint/pkg_vuln.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@
1515
from typing import List
1616

1717

18+
class CvssSourceProvider:
19+
NVD = 'NVD'
20+
MITRE = 'MITRE'
21+
AMAZON_INSPECTOR = 'AMAZON_INSPECTOR'
22+
23+
DEFAULT_PROVIDER = NVD
24+
25+
26+
class CvssSeverity:
27+
UNTRIAGED = "untriaged"
28+
UNKNOWN = "unknown"
29+
30+
1831
class Vulnerability:
1932
"""
2033
Vulnerability is an object for marshalling
@@ -26,6 +39,7 @@ class Vulnerability:
2639
def __init__(self):
2740
self.vuln_id = "null"
2841
self.severity = "null"
42+
self.severity_provider = "null"
2943
self.cvss_score = "null"
3044
self.published = "null"
3145
self.modified = "null"
@@ -41,7 +55,8 @@ def __init__(self):
4155

4256
@dataclass
4357
class CvssRating:
44-
severity: str = "null"
58+
severity: str = CvssSeverity.UNTRIAGED
59+
provider: str = CvssSourceProvider.DEFAULT_PROVIDER
4560
cvss_score: str = "null"
4661

4762

@@ -209,6 +224,7 @@ def add_ratings(ratings, vulnerability):
209224

210225
rating = get_cvss_rating(ratings, vulnerability)
211226
vulnerability.severity = rating.severity
227+
vulnerability.severity_provider = rating.provider
212228
vulnerability.cvss_score = rating.cvss_score
213229

214230
epss_score = get_epss_score(ratings)
@@ -227,10 +243,10 @@ def get_cvss_rating(ratings, vulnerability) -> CvssRating:
227243
if rating['source']['name'] != provider:
228244
continue
229245

230-
severity = rating["severity"]
246+
severity = CvssSeverity.UNTRIAGED if rating["severity"] == CvssSeverity.UNKNOWN else rating["severity"]
231247
cvss_score = rating["score"] if rating['method'] == 'CVSSv31' else "null"
232248
if severity and cvss_score:
233-
return CvssRating(severity=severity, cvss_score=cvss_score)
249+
return CvssRating(severity=severity, provider=provider, cvss_score=cvss_score)
234250

235251
logging.info(f"No CVSS rating is provided for {vulnerability.vuln_id}")
236252
return CvssRating()
@@ -279,7 +295,7 @@ def to_csv(vulns,
279295
csv_writer.writerow(vuln_summary)
280296

281297
# write the header into the CSV
282-
header = ["ID", "Severity", "CVSS",
298+
header = ["ID", "Severity", "Source", "CVSS",
283299
"Installed Package", "Fixed Package",
284300
"Path", "EPSS", "Exploit Available",
285301
"Exploit Last Seen", "CWEs"]
@@ -289,7 +305,7 @@ def to_csv(vulns,
289305
if vulns:
290306
for v in vulns:
291307
# if package vuln
292-
row = [v.vuln_id, v.severity, v.cvss_score,
308+
row = [v.vuln_id, v.severity, v.severity_provider, v.cvss_score,
293309
v.installed_ver, v.fixed_ver,
294310
v.pkg_path, v.epss_score, v.exploit_available,
295311
v.exploit_last_seen, v.cwes
@@ -345,15 +361,15 @@ def to_markdown(vulns,
345361

346362
# create vulnerability details table
347363
markdown += "## Vulnerability Findings\n\n"
348-
markdown += "| ID | Severity | [CVSS](https://www.first.org/cvss/) | Installed Package ([PURL](https://github.com/package-url/purl-spec/tree/master?tab=readme-ov-file#purl)) | Fixed Package | Path | [EPSS](https://www.first.org/epss/) | Exploit Available | Exploit Last Seen | CWEs |\n"
349-
markdown += "|----------|-------|-------|-------|-------|-------|-------|-------|-------|-------|\n"
364+
markdown += "| ID | Severity | Source | [CVSS](https://www.first.org/cvss/) | Installed Package ([PURL](https://github.com/package-url/purl-spec/tree/master?tab=readme-ov-file#purl)) | Fixed Package | Path | [EPSS](https://www.first.org/epss/) | Exploit Available | Exploit Last Seen | CWEs |\n"
365+
markdown += "| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n"
350366

351367
# sort vulns by CVSS score
352368
vulns = sort_vulns(vulns)
353369

354370
# append each row to the vulnerability details table
355371
for v in vulns:
356-
markdown += f"|{v.vuln_id}| {clean_null(v.severity)} | {clean_null(v.cvss_score)} | {merge_cell(v.installed_ver)} | {merge_cell(v.fixed_ver)} | {merge_cell(clean_null(v.pkg_path))} | {clean_null(v.epss_score)} | {clean_null(v.exploit_available)} | {clean_null(v.exploit_last_seen)} | {(merge_cell(clean_null(v.cwes)))} | \n"
372+
markdown += f"| {v.vuln_id} | {clean_null(v.severity)} | {clean_null(v.severity_provider)} | {clean_null(v.cvss_score)} | {merge_cell(v.installed_ver)} | {merge_cell(v.fixed_ver)} | {merge_cell(clean_null(v.pkg_path))} | {clean_null(v.epss_score)} | {clean_null(v.exploit_available)} | {clean_null(v.exploit_last_seen)} | {(merge_cell(clean_null(v.cwes)))} | \n"
357373

358374
markdown += "\n\n"
359375
return markdown

entrypoint/tests/test_pkg_vuln.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,14 @@ def test_get_rating(self):
8888
"source": {"name": "EPSS"},
8989
},
9090
],
91-
"expected": pkg_vuln.CvssRating("medium", 5.3),
91+
"expected": pkg_vuln.CvssRating("medium", "NVD", 5.3),
9292
},
9393
{
94-
"name": 'score should be "null" when method is "other"',
94+
"name": 'score should be "null" and severity should be "untriaged" when method is "other" and severity is "unknown"',
9595
"ratings": [
9696
{
9797
"method": "other",
98-
"severity": "medium",
98+
"severity": "unknown",
9999
"source": {"name": "AMAZON_INSPECTOR"},
100100
},
101101
{
@@ -105,10 +105,10 @@ def test_get_rating(self):
105105
"source": {"name": "EPSS"},
106106
},
107107
],
108-
"expected": pkg_vuln.CvssRating("medium"),
108+
"expected": pkg_vuln.CvssRating("untriaged", "AMAZON_INSPECTOR", "null"),
109109
},
110110
{
111-
"name": 'rating should be "null" when neither NVD, MITRE, nor AMAZON_INSPECTOR provides a rating',
111+
"name": 'rating should be "null" and severity is not provided when no CVSS rating is provided',
112112
"ratings": [
113113
{
114114
"method": "other",
@@ -117,7 +117,7 @@ def test_get_rating(self):
117117
"source": {"name": "EPSS"},
118118
},
119119
],
120-
"expected": pkg_vuln.CvssRating(),
120+
"expected": pkg_vuln.CvssRating("untriaged", "NVD", "null"),
121121
},
122122
]
123123
for test in tests:

0 commit comments

Comments
 (0)