Skip to content

Commit 59fbd9c

Browse files
authored
Support for cvss v4 (#365)
Signed-off-by: Prabhu Subramanian <[email protected]>
1 parent 806cf71 commit 59fbd9c

File tree

3 files changed

+49
-28
lines changed

3 files changed

+49
-28
lines changed

depscan/lib/analysis.py

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from rich.tree import Tree
2020
from vdb.lib import CPE_FULL_REGEX
2121
from vdb.lib.config import placeholder_exclude_version, placeholder_fix_version
22-
from vdb.lib.utils import parse_cpe, parse_purl
22+
from vdb.lib.utils import get_cvss3_from_vector, get_cvss4_from_vector, parse_cpe, parse_purl
2323

2424
from depscan.lib import config
2525
from depscan.lib.logger import LOG, console
@@ -336,6 +336,11 @@ def prepare_vdr(options: PrepareVdrOptions):
336336
justify = "right"
337337
table.add_column(header=h, justify=justify, vertical="top")
338338
for vuln_occ_dict in options.results:
339+
# If CVSS v4 data is available, override the severity and cvss_score
340+
if vuln_occ_dict.get("cvss4_vector_string"):
341+
cvss4_obj = get_cvss4_from_vector(vuln_occ_dict.get("cvss4_vector_string"))
342+
vuln_occ_dict["cvss_score"] = cvss4_obj.get("baseScore")
343+
vuln_occ_dict["severity"] = cvss4_obj.get("baseSeverity").upper()
339344
vid = vuln_occ_dict.get("id")
340345
problem_type = vuln_occ_dict.get("problem_type")
341346
cwes = []
@@ -1026,34 +1031,33 @@ def cvss_to_vdr_rating(vuln_occ_dict):
10261031
10271032
:return: A list containing a dictionary with CVSS score information.
10281033
"""
1029-
cvss_score = vuln_occ_dict.get("cvss_score", 2.0)
1030-
with contextlib.suppress(ValueError, TypeError):
1031-
cvss_score = float(cvss_score)
1032-
if (pkg_severity := vuln_occ_dict.get("severity", "").lower()) not in (
1033-
"critical",
1034-
"high",
1035-
"medium",
1036-
"low",
1037-
"info",
1038-
"none",
1039-
):
1040-
pkg_severity = "unknown"
1041-
ratings = [
1042-
{
1043-
"score": cvss_score,
1044-
"severity": pkg_severity,
1045-
}
1046-
]
1047-
method = "31"
1034+
ratings = []
1035+
# Support for cvss v4
1036+
if vuln_occ_dict.get("cvss4_vector_string") and (vector_string := vuln_occ_dict.get("cvss4_vector_string")):
1037+
cvss4_obj = get_cvss4_from_vector(vector_string)
1038+
ratings.append(
1039+
{
1040+
"method": "CVSSv4",
1041+
"score": cvss4_obj.get("baseScore"),
1042+
"severity": cvss4_obj.get("baseSeverity").lower(),
1043+
"vector": vector_string
1044+
}
1045+
)
10481046
if vuln_occ_dict.get("cvss_v3") and (
10491047
vector_string := vuln_occ_dict["cvss_v3"].get("vector_string")
10501048
):
1051-
ratings[0]["vector"] = vector_string
10521049
with contextlib.suppress(CVSSError):
1053-
method = cvss.CVSS3(vector_string).as_json().get("version")
1050+
cvss3_obj = get_cvss3_from_vector(vector_string)
1051+
method = cvss3_obj.get("version")
10541052
method = method.replace(".", "").replace("0", "")
1055-
ratings[0]["method"] = f"CVSSv{method}"
1056-
1053+
ratings.append(
1054+
{
1055+
"method": f"CVSSv{method}",
1056+
"score": cvss3_obj.get("baseScore"),
1057+
"severity": cvss3_obj.get("baseSeverity").lower(),
1058+
"vector": vector_string
1059+
}
1060+
)
10571061
return ratings
10581062

10591063

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[project]
22
name = "owasp-depscan"
3-
version = "5.4.8"
3+
version = "5.5.0"
44
description = "Fully open-source security audit for project dependencies based on known vulnerabilities and advisories."
55
authors = [
66
{name = "Team AppThreat", email = "[email protected]"},
77
]
88
dependencies = [
9-
"appthreat-vulnerability-db==5.7.8",
9+
"appthreat-vulnerability-db==5.8.1",
1010
"defusedxml",
1111
"oras~=0.1.26",
1212
"PyYAML",

test/test_analysis.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,8 +708,7 @@ def test_cvss_to_vdr_rating():
708708
"severity": "HIGH",
709709
}
710710
# Test missing score and vector string
711-
assert cvss_to_vdr_rating(res) == [
712-
{'method': 'CVSSv31', 'score': 2.0, 'severity': 'high'}]
711+
assert cvss_to_vdr_rating(res) == []
713712
# Test parsing
714713
res["cvss_v3"]["vector_string"] = ("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I"
715714
":N/A:H")
@@ -729,6 +728,24 @@ def test_cvss_to_vdr_rating():
729728
'severity': 'high',
730729
'vector': 'CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H'
731730
}]
731+
assert cvss_to_vdr_rating({
732+
"cvss_v3": {
733+
"vector_string": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:H/A:H"
734+
},
735+
"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"
736+
}) == [{
737+
'method': 'CVSSv4',
738+
'score': 7.9,
739+
'severity': 'high',
740+
'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'
741+
},
742+
{
743+
'method': 'CVSSv31',
744+
'score': 10.0,
745+
'severity': 'critical',
746+
'vector': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:H/A:H'
747+
}
748+
]
732749

733750

734751
def test_get_version_range():

0 commit comments

Comments
 (0)