Skip to content

Commit 66e1df3

Browse files
authored
Including score in the CVE Report (#1077)
* Including score in the CVE Report Signed-off-by: Jerin J Titus <72017981+jerinjtitus@users.noreply.github.com> * Updating tests Signed-off-by: Jerin J Titus <72017981+jerinjtitus@users.noreply.github.com> * Truncating test reports Signed-off-by: Jerin J Titus <72017981+jerinjtitus@users.noreply.github.com> * shortened mock CVE number Signed-off-by: Jerin J Titus <72017981+jerinjtitus@users.noreply.github.com> * setting a specificed console width for tests Signed-off-by: Jerin J Titus <72017981+jerinjtitus@users.noreply.github.com> * Updated tests Signed-off-by: Jerin J Titus <72017981+jerinjtitus@users.noreply.github.com> * Changed the output report format Signed-off-by: Jerin J Titus <72017981+jerinjtitus@users.noreply.github.com>
1 parent dace084 commit 66e1df3

File tree

6 files changed

+59
-20
lines changed

6 files changed

+59
-20
lines changed

cve_bin_tool/cve_scanner.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
155155
# Go through and get all the severities
156156
if cve_list:
157157
query = f"""
158-
SELECT CVE_number, severity, description
158+
SELECT CVE_number, severity, description, score, cvss_version
159159
FROM cve_severity
160160
WHERE CVE_number IN ({",".join(["?"] * len(cve_list))}) AND score >= ?
161161
ORDER BY CVE_number
@@ -176,7 +176,12 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
176176
if triage is not None:
177177
row_dict = dict(row)
178178
row_dict.update(triage)
179+
# print(row_dict)
179180
row_dict["severity"] = row_dict["severity"] or row["severity"]
181+
row_dict["score"] = row_dict["score"] or row["score"]
182+
row_dict["cvss_version"] = (
183+
row_dict["cvss_version"] or row["cvss_version"]
184+
)
180185
cve = CVE(**row_dict)
181186
cves.append(cve)
182187

cve_bin_tool/output_engine/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ def output_csv(all_cve_data: Dict[ProductInfo, CVEData], outfile):
3737
"version",
3838
"cve_number",
3939
"severity",
40+
"score",
41+
"cvss_version",
4042
"paths",
4143
"remarks",
4244
"comments",

cve_bin_tool/output_engine/console.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def output_console(
2424
):
2525
""" Output list of CVEs in a tabular format with color support """
2626

27+
console._width = 120
2728
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
2829

2930
console.print(
@@ -56,6 +57,8 @@ def output_console(
5657
"version": product_info.version,
5758
"cve_number": cve.cve_number,
5859
"severity": cve.severity,
60+
"score": cve.score,
61+
"cvss_version": cve.cvss_version,
5962
}
6063
)
6164

@@ -71,6 +74,8 @@ def output_console(
7174
table.add_column("Version")
7275
table.add_column("CVE Number")
7376
table.add_column("Severity")
77+
table.add_column("Score (CVSS Version)")
78+
# table.add_column("CVSS Version")
7479

7580
for cve_data in cve_by_remarks[remarks]:
7681
color = cve_data["severity"].lower()
@@ -80,6 +85,13 @@ def output_console(
8085
Text.styled(cve_data["version"], color),
8186
linkify_cve(Text.styled(cve_data["cve_number"], color)),
8287
Text.styled(cve_data["severity"], color),
88+
Text.styled(
89+
str(cve_data["score"])
90+
+ " (v"
91+
+ str(cve_data["cvss_version"])
92+
+ ")",
93+
color,
94+
),
8395
)
8496
# Print the table to the console
8597
console.print(table)

cve_bin_tool/output_engine/util.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ def format_output(all_cve_data: Dict[ProductInfo, CVEData]) -> List[Dict[str, st
4343
"product": "curl",
4444
"version": "1.2.1",
4545
"cve_number": "CVE-1234-1234",
46-
"severity": "LOW"
46+
"severity": "LOW",
47+
"score": "1.2",
48+
"cvss_version": "2",
49+
"paths": "",
50+
"remarks": "NewFound",
51+
"comments": "",
4752
},
4853
...
4954
]
@@ -58,6 +63,8 @@ def format_output(all_cve_data: Dict[ProductInfo, CVEData]) -> List[Dict[str, st
5863
"version": product_info.version,
5964
"cve_number": cve.cve_number,
6065
"severity": cve.severity,
66+
"score": str(cve.score),
67+
"cvss_version": str(cve.cvss_version),
6168
"paths": ", ".join(cve_data["paths"]),
6269
"remarks": cve.remarks.name,
6370
"comments": cve.comments,

cve_bin_tool/util.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class CVE(NamedTuple):
5454
remarks: Remarks = Remarks.NewFound
5555
description: str = ""
5656
comments: str = ""
57+
score: float = 0
58+
cvss_version: int = 0
5759

5860

5961
class ProductInfo(NamedTuple):

test/test_output_engine.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,55 +23,66 @@ class TestOutputEngine(unittest.TestCase):
2323
""" Test the OutputEngine class functions """
2424

2525
MOCK_OUTPUT = {
26-
ProductInfo("vendorname0", "productname0", "1.0"): CVEData(
27-
cves=[CVE("CVE-1234-1234", "MEDIUM"), CVE("CVE-1234-9876", "LOW")],
26+
ProductInfo("vendor0", "product0", "1.0"): CVEData(
27+
cves=[
28+
CVE("CVE-1234-1234", "MEDIUM", score=4.2, cvss_version=2),
29+
CVE("CVE-1234-1234", "LOW", score=1.2, cvss_version=2),
30+
],
2831
paths={""},
2932
),
30-
ProductInfo("vendorname0", "productname0", "2.8.6"): CVEData(
31-
cves=[CVE("CVE-1234-1111", "LOW")], paths={""}
33+
ProductInfo("vendor0", "product0", "2.8.6"): CVEData(
34+
cves=[CVE("CVE-1234-1234", "LOW", score=2.5, cvss_version=3)], paths={""}
3235
),
33-
ProductInfo("vendorname1", "productname1", "3.2.1.0"): CVEData(
34-
cves=[CVE("CVE-1234-5678", "HIGH")], paths={""}
36+
ProductInfo("vendor1", "product1", "3.2.1.0"): CVEData(
37+
cves=[CVE("CVE-1234-1234", "HIGH", score=7.5, cvss_version=2)], paths={""}
3538
),
3639
}
3740

3841
FORMATTED_OUTPUT = [
3942
{
40-
"vendor": "vendorname0",
41-
"product": "productname0",
43+
"vendor": "vendor0",
44+
"product": "product0",
4245
"version": "1.0",
4346
"cve_number": "CVE-1234-1234",
4447
"severity": "MEDIUM",
48+
"score": "4.2",
49+
"cvss_version": "2",
4550
"paths": "",
4651
"remarks": "NewFound",
4752
"comments": "",
4853
},
4954
{
50-
"vendor": "vendorname0",
51-
"product": "productname0",
55+
"vendor": "vendor0",
56+
"product": "product0",
5257
"version": "1.0",
53-
"cve_number": "CVE-1234-9876",
58+
"cve_number": "CVE-1234-1234",
5459
"severity": "LOW",
60+
"score": "1.2",
61+
"cvss_version": "2",
5562
"paths": "",
5663
"remarks": "NewFound",
5764
"comments": "",
5865
},
5966
{
60-
"vendor": "vendorname0",
61-
"product": "productname0",
67+
"vendor": "vendor0",
68+
"product": "product0",
6269
"version": "2.8.6",
63-
"cve_number": "CVE-1234-1111",
70+
"cve_number": "CVE-1234-1234",
6471
"severity": "LOW",
72+
"score": "2.5",
73+
"cvss_version": "3",
6574
"paths": "",
6675
"remarks": "NewFound",
6776
"comments": "",
6877
},
6978
{
70-
"vendor": "vendorname1",
71-
"product": "productname1",
79+
"vendor": "vendor1",
80+
"product": "product1",
7281
"version": "3.2.1.0",
73-
"cve_number": "CVE-1234-5678",
82+
"cve_number": "CVE-1234-1234",
7483
"severity": "HIGH",
84+
"score": "7.5",
85+
"cvss_version": "2",
7586
"paths": "",
7687
"remarks": "NewFound",
7788
"comments": "",
@@ -111,7 +122,7 @@ def test_output_console(self):
111122
console = Console(file=self.mock_file)
112123
output_console(self.MOCK_OUTPUT, console=console)
113124

114-
expected_output = "│ vendorname0productname0 │ 1.0 │ CVE-1234-1234 │ MEDIUM │\nvendorname0productname0 │ 1.0 │ CVE-1234-9876 │ LOW │\nvendorname0productname0 │ 2.8.6 │ CVE-1234-1111 │ LOW │\nvendorname1productname1 │ 3.2.1.0 │ CVE-1234-5678 │ HIGH │\n└───────────────────────────┴──────────────────────────────────┘\n"
125+
expected_output = "│ vendor0product0 │ 1.0 │ CVE-1234-1234 │ MEDIUM │ 4.2 (v2) │\nvendor0product0 │ 1.0 │ CVE-1234-1234 │ LOW │ 1.2 (v2) │\nvendor0product0 │ 2.8.6 │ CVE-1234-1234 │ LOW │ 2.5 (v3) │\nvendor1product1 │ 3.2.1.0 │ CVE-1234-1234 │ HIGH │ 7.5 (v2) │\n└───────────────────────────┴─────────────────────────┴──────────────────────┘\n"
115126
self.mock_file.seek(0) # reset file position
116127
result = self.mock_file.read()
117128
self.assertIn(expected_output, result)

0 commit comments

Comments
 (0)