Skip to content
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

Support for cvss v4 #365

Merged
merged 1 commit into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
52 changes: 28 additions & 24 deletions depscan/lib/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from rich.tree import Tree
from vdb.lib import CPE_FULL_REGEX
from vdb.lib.config import placeholder_exclude_version, placeholder_fix_version
from vdb.lib.utils import parse_cpe, parse_purl
from vdb.lib.utils import get_cvss3_from_vector, get_cvss4_from_vector, parse_cpe, parse_purl

from depscan.lib import config
from depscan.lib.logger import LOG, console
Expand Down Expand Up @@ -336,6 +336,11 @@ def prepare_vdr(options: PrepareVdrOptions):
justify = "right"
table.add_column(header=h, justify=justify, vertical="top")
for vuln_occ_dict in options.results:
# If CVSS v4 data is available, override the severity and cvss_score
if vuln_occ_dict.get("cvss4_vector_string"):
cvss4_obj = get_cvss4_from_vector(vuln_occ_dict.get("cvss4_vector_string"))
vuln_occ_dict["cvss_score"] = cvss4_obj.get("baseScore")
vuln_occ_dict["severity"] = cvss4_obj.get("baseSeverity").upper()
vid = vuln_occ_dict.get("id")
problem_type = vuln_occ_dict.get("problem_type")
cwes = []
Expand Down Expand Up @@ -1026,34 +1031,33 @@ def cvss_to_vdr_rating(vuln_occ_dict):

:return: A list containing a dictionary with CVSS score information.
"""
cvss_score = vuln_occ_dict.get("cvss_score", 2.0)
with contextlib.suppress(ValueError, TypeError):
cvss_score = float(cvss_score)
if (pkg_severity := vuln_occ_dict.get("severity", "").lower()) not in (
"critical",
"high",
"medium",
"low",
"info",
"none",
):
pkg_severity = "unknown"
ratings = [
{
"score": cvss_score,
"severity": pkg_severity,
}
]
method = "31"
ratings = []
# Support for cvss v4
if vuln_occ_dict.get("cvss4_vector_string") and (vector_string := vuln_occ_dict.get("cvss4_vector_string")):
cvss4_obj = get_cvss4_from_vector(vector_string)
ratings.append(
{
"method": "CVSSv4",
"score": cvss4_obj.get("baseScore"),
"severity": cvss4_obj.get("baseSeverity").lower(),
"vector": vector_string
}
)
if vuln_occ_dict.get("cvss_v3") and (
vector_string := vuln_occ_dict["cvss_v3"].get("vector_string")
):
ratings[0]["vector"] = vector_string
with contextlib.suppress(CVSSError):
method = cvss.CVSS3(vector_string).as_json().get("version")
cvss3_obj = get_cvss3_from_vector(vector_string)
method = cvss3_obj.get("version")
method = method.replace(".", "").replace("0", "")
ratings[0]["method"] = f"CVSSv{method}"

ratings.append(
{
"method": f"CVSSv{method}",
"score": cvss3_obj.get("baseScore"),
"severity": cvss3_obj.get("baseSeverity").lower(),
"vector": vector_string
}
)
return ratings


Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[project]
name = "owasp-depscan"
version = "5.4.8"
version = "5.5.0"
description = "Fully open-source security audit for project dependencies based on known vulnerabilities and advisories."
authors = [
{name = "Team AppThreat", email = "cloud@appthreat.com"},
]
dependencies = [
"appthreat-vulnerability-db==5.7.8",
"appthreat-vulnerability-db==5.8.1",
"defusedxml",
"oras~=0.1.26",
"PyYAML",
Expand Down
21 changes: 19 additions & 2 deletions test/test_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -708,8 +708,7 @@ def test_cvss_to_vdr_rating():
"severity": "HIGH",
}
# Test missing score and vector string
assert cvss_to_vdr_rating(res) == [
{'method': 'CVSSv31', 'score': 2.0, 'severity': 'high'}]
assert cvss_to_vdr_rating(res) == []
# Test parsing
res["cvss_v3"]["vector_string"] = ("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I"
":N/A:H")
Expand All @@ -729,6 +728,24 @@ def test_cvss_to_vdr_rating():
'severity': 'high',
'vector': 'CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H'
}]
assert cvss_to_vdr_rating({
"cvss_v3": {
"vector_string": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:H/A:H"
},
"cvss4_vector_string": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:H/SA:H"
}) == [{
'method': 'CVSSv4',
'score': 7.9,
'severity': 'high',
'vector': 'CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:H/SA:H'
},
{
'method': 'CVSSv31',
'score': 10.0,
'severity': 'critical',
'vector': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:H/A:H'
}
]


def test_get_version_range():
Expand Down
Loading