Skip to content

Commit

Permalink
Including score in the CVE Report (#1077)
Browse files Browse the repository at this point in the history
* Including score in the CVE Report

Signed-off-by: Jerin J Titus <[email protected]>

* Updating tests

Signed-off-by: Jerin J Titus <[email protected]>

* Truncating test reports

Signed-off-by: Jerin J Titus <[email protected]>

* shortened mock CVE number

Signed-off-by: Jerin J Titus <[email protected]>

* setting a specificed console width for tests

Signed-off-by: Jerin J Titus <[email protected]>

* Updated tests

Signed-off-by: Jerin J Titus <[email protected]>

* Changed the output report format

Signed-off-by: Jerin J Titus <[email protected]>
  • Loading branch information
jerinjtitus authored May 26, 2021
1 parent dace084 commit 66e1df3
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 20 deletions.
7 changes: 6 additions & 1 deletion cve_bin_tool/cve_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
# Go through and get all the severities
if cve_list:
query = f"""
SELECT CVE_number, severity, description
SELECT CVE_number, severity, description, score, cvss_version
FROM cve_severity
WHERE CVE_number IN ({",".join(["?"] * len(cve_list))}) AND score >= ?
ORDER BY CVE_number
Expand All @@ -176,7 +176,12 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
if triage is not None:
row_dict = dict(row)
row_dict.update(triage)
# print(row_dict)
row_dict["severity"] = row_dict["severity"] or row["severity"]
row_dict["score"] = row_dict["score"] or row["score"]
row_dict["cvss_version"] = (
row_dict["cvss_version"] or row["cvss_version"]
)
cve = CVE(**row_dict)
cves.append(cve)

Expand Down
2 changes: 2 additions & 0 deletions cve_bin_tool/output_engine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ def output_csv(all_cve_data: Dict[ProductInfo, CVEData], outfile):
"version",
"cve_number",
"severity",
"score",
"cvss_version",
"paths",
"remarks",
"comments",
Expand Down
12 changes: 12 additions & 0 deletions cve_bin_tool/output_engine/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def output_console(
):
""" Output list of CVEs in a tabular format with color support """

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

console.print(
Expand Down Expand Up @@ -56,6 +57,8 @@ def output_console(
"version": product_info.version,
"cve_number": cve.cve_number,
"severity": cve.severity,
"score": cve.score,
"cvss_version": cve.cvss_version,
}
)

Expand All @@ -71,6 +74,8 @@ def output_console(
table.add_column("Version")
table.add_column("CVE Number")
table.add_column("Severity")
table.add_column("Score (CVSS Version)")
# table.add_column("CVSS Version")

for cve_data in cve_by_remarks[remarks]:
color = cve_data["severity"].lower()
Expand All @@ -80,6 +85,13 @@ def output_console(
Text.styled(cve_data["version"], color),
linkify_cve(Text.styled(cve_data["cve_number"], color)),
Text.styled(cve_data["severity"], color),
Text.styled(
str(cve_data["score"])
+ " (v"
+ str(cve_data["cvss_version"])
+ ")",
color,
),
)
# Print the table to the console
console.print(table)
9 changes: 8 additions & 1 deletion cve_bin_tool/output_engine/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ def format_output(all_cve_data: Dict[ProductInfo, CVEData]) -> List[Dict[str, st
"product": "curl",
"version": "1.2.1",
"cve_number": "CVE-1234-1234",
"severity": "LOW"
"severity": "LOW",
"score": "1.2",
"cvss_version": "2",
"paths": "",
"remarks": "NewFound",
"comments": "",
},
...
]
Expand All @@ -58,6 +63,8 @@ def format_output(all_cve_data: Dict[ProductInfo, CVEData]) -> List[Dict[str, st
"version": product_info.version,
"cve_number": cve.cve_number,
"severity": cve.severity,
"score": str(cve.score),
"cvss_version": str(cve.cvss_version),
"paths": ", ".join(cve_data["paths"]),
"remarks": cve.remarks.name,
"comments": cve.comments,
Expand Down
2 changes: 2 additions & 0 deletions cve_bin_tool/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class CVE(NamedTuple):
remarks: Remarks = Remarks.NewFound
description: str = ""
comments: str = ""
score: float = 0
cvss_version: int = 0


class ProductInfo(NamedTuple):
Expand Down
47 changes: 29 additions & 18 deletions test/test_output_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,55 +23,66 @@ class TestOutputEngine(unittest.TestCase):
""" Test the OutputEngine class functions """

MOCK_OUTPUT = {
ProductInfo("vendorname0", "productname0", "1.0"): CVEData(
cves=[CVE("CVE-1234-1234", "MEDIUM"), CVE("CVE-1234-9876", "LOW")],
ProductInfo("vendor0", "product0", "1.0"): CVEData(
cves=[
CVE("CVE-1234-1234", "MEDIUM", score=4.2, cvss_version=2),
CVE("CVE-1234-1234", "LOW", score=1.2, cvss_version=2),
],
paths={""},
),
ProductInfo("vendorname0", "productname0", "2.8.6"): CVEData(
cves=[CVE("CVE-1234-1111", "LOW")], paths={""}
ProductInfo("vendor0", "product0", "2.8.6"): CVEData(
cves=[CVE("CVE-1234-1234", "LOW", score=2.5, cvss_version=3)], paths={""}
),
ProductInfo("vendorname1", "productname1", "3.2.1.0"): CVEData(
cves=[CVE("CVE-1234-5678", "HIGH")], paths={""}
ProductInfo("vendor1", "product1", "3.2.1.0"): CVEData(
cves=[CVE("CVE-1234-1234", "HIGH", score=7.5, cvss_version=2)], paths={""}
),
}

FORMATTED_OUTPUT = [
{
"vendor": "vendorname0",
"product": "productname0",
"vendor": "vendor0",
"product": "product0",
"version": "1.0",
"cve_number": "CVE-1234-1234",
"severity": "MEDIUM",
"score": "4.2",
"cvss_version": "2",
"paths": "",
"remarks": "NewFound",
"comments": "",
},
{
"vendor": "vendorname0",
"product": "productname0",
"vendor": "vendor0",
"product": "product0",
"version": "1.0",
"cve_number": "CVE-1234-9876",
"cve_number": "CVE-1234-1234",
"severity": "LOW",
"score": "1.2",
"cvss_version": "2",
"paths": "",
"remarks": "NewFound",
"comments": "",
},
{
"vendor": "vendorname0",
"product": "productname0",
"vendor": "vendor0",
"product": "product0",
"version": "2.8.6",
"cve_number": "CVE-1234-1111",
"cve_number": "CVE-1234-1234",
"severity": "LOW",
"score": "2.5",
"cvss_version": "3",
"paths": "",
"remarks": "NewFound",
"comments": "",
},
{
"vendor": "vendorname1",
"product": "productname1",
"vendor": "vendor1",
"product": "product1",
"version": "3.2.1.0",
"cve_number": "CVE-1234-5678",
"cve_number": "CVE-1234-1234",
"severity": "HIGH",
"score": "7.5",
"cvss_version": "2",
"paths": "",
"remarks": "NewFound",
"comments": "",
Expand Down Expand Up @@ -111,7 +122,7 @@ def test_output_console(self):
console = Console(file=self.mock_file)
output_console(self.MOCK_OUTPUT, console=console)

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"
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"
self.mock_file.seek(0) # reset file position
result = self.mock_file.read()
self.assertIn(expected_output, result)
Expand Down

0 comments on commit 66e1df3

Please sign in to comment.