Skip to content

fix: improve handling of triage data #4160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
63 changes: 55 additions & 8 deletions cve_bin_tool/cve_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from cve_bin_tool.input_engine import TriageData
from cve_bin_tool.log import LOGGER
from cve_bin_tool.theme import cve_theme
from cve_bin_tool.util import CVE, CVEData, ProductInfo, VersionInfo
from cve_bin_tool.util import CVE, CVEData, ProductInfo, Remarks, VersionInfo
from cve_bin_tool.version_compare import Version


Expand Down Expand Up @@ -180,8 +180,13 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
end_excluding=version_end_excluding,
)

# Go through and get all the severities
product_info_data: CVEData | None = self.all_cve_data.get(product_info)
prev_cves: List[CVE] = (
product_info_data.get("cves", []) if product_info_data is not None else [] # type: ignore
)
cves: List[CVE] = []

# Go through and get all the severities
if cve_list:
finished = False
max_cves = 500
Expand Down Expand Up @@ -223,15 +228,26 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
if duplicate_found:
continue

# Check if we already found this CVE with a previous scan.
# In that case we need to check where to get our triage info
# from.
# TODO: turn the list of CVEs into a set to avoid needing
# the linear-time lookup.
prev_cve = next(
(
cve
for cve in prev_cves
if cve.cve_number == row["cve_number"]
),
None,
)

triage = triage_data.get(row["cve_number"]) or triage_data.get(
"default"
)
# Only scan cves if triage is not None.
# Triage will only be None if triage_data don't have default attribute.
# NOTE: Triage can be empty dictionary so checking `if triage:` won't suffice.
if triage is not None:
if prev_cve is None:
row_dict = dict(row)
row_dict.update(triage)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@terriko the plotly.js is coming from the:

"ref": "urn:cbt:1/plotly#plotly.js-2.13.2"

triage.json being used in test_requirement.py as triage-input since the code mentioned tries to scan for the cves even if the triage data is present, apologies for not interpreting the changes in greater depth , cve_scanner is a little complex to read but this particular line is what i suspect is causing error hope it helps!


# print(row_dict)
row_dict["severity"] = row_dict["severity"] or row["severity"]
# Checking for exploits
Expand Down Expand Up @@ -274,7 +290,38 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
f'metrics found in CVE {row_dict["cve_number"]} is {row_dict["metric"]}'
)
cve = CVE(**row_dict)
cves.append(cve)
else:
cve = prev_cve

# We assume that only one source has the triage info.
# We try to figure out here which one.
# If we have useful info in the triage data we received,
# then we use it.
if triage is not None and (
# Either the new cve does not have triage data,
# or it is trivial (newly found cve)
not cve.remarks or cve.remarks == Remarks.NewFound
):
for key in [
"remarks",
"comments",
"response",
"justification",
"severity",
]:
data = triage.get(key)
if data:
if (
key == "severity"
and self.check_exploits
and row_dict["cve_number"] in self.exploits_list
):
data += "-EXPLOIT"

self.logger.debug(f"Setting field {key} to: {data}")
cve = cve._replace(**{key: data})

cves.append(cve)

if cves:
self.products_with_cve += 1
Expand Down
21 changes: 20 additions & 1 deletion cve_bin_tool/util.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Copyright (C) 2021 Intel Corporation
# SPDX-License-Identifier: GPL-3.0-or-later

""" Utility classes for the CVE Binary Tool """
"""Utility classes for the CVE Binary Tool"""

from __future__ import annotations

import fnmatch
Expand Down Expand Up @@ -165,6 +166,24 @@ class ProductInfo(NamedTuple):
location: str
purl: str | None = None

def __identity_members(self):
"""The members that will be used for eq and hash implementations.
We do not include location here since it can take on different values
depending on where the product info is coming from and we want to be
able to properly identify products that are actually the same.
"""
# TODO: what is the meaning of the location field exactly?
return (self.vendor, self.product, self.version)

def __eq__(self, other):
if type(other) is type(self):
return self.__identity_members() == other.__identity_members()
else:
return False

def __hash__(self):
return hash(self.__identity_members())


class ScanInfo(NamedTuple):
"""
Expand Down
Loading