Skip to content

Commit b9e9e17

Browse files
committed
feat: support for localising vectors (i.e. stripping out any scheme prefix)
Signed-off-by: Paul Horton <[email protected]>
1 parent 6a86ec2 commit b9e9e17

File tree

3 files changed

+79
-4
lines changed

3 files changed

+79
-4
lines changed

cyclonedx/model/vulnerability.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
# SPDX-License-Identifier: Apache-2.0
1818
# Copyright (c) OWASP Foundation. All Rights Reserved.
1919

20+
import re
2021
from enum import Enum
2122
from typing import List, Union
2223
from urllib.parse import ParseResult, urlparse
@@ -59,8 +60,16 @@ def get_localised_vector(self, vector: str) -> str:
5960
:param vector:
6061
:return:
6162
"""
62-
if self == VulnerabilitySourceType.CVSS_V3:
63-
return
63+
if self == VulnerabilitySourceType.CVSS_V3 and vector.startswith('CVSS:3.'):
64+
return re.sub('^CVSS:3\\.\\d/?', '', vector)
65+
66+
if self == VulnerabilitySourceType.CVSS_V2 and vector.startswith('CVSS:2.'):
67+
return re.sub('^CVSS:2\\.\\d/?', '', vector)
68+
69+
if self == VulnerabilitySourceType.OWASP and vector.startswith('OWASP'):
70+
return re.sub('^OWASP/?', '', vector)
71+
72+
return vector
6473

6574

6675
class VulnerabilitySeverity(Enum):
@@ -77,7 +86,7 @@ class VulnerabilitySeverity(Enum):
7786
@staticmethod
7887
def get_from_cvss_scores(scores: tuple[float] = None):
7988
if type(scores) is float:
80-
scores = (scores, )
89+
scores = (scores,)
8190

8291
if scores is None:
8392
return VulnerabilitySeverity.UNKNOWN

tests/fixtures/bom_v1.3_setuptools_with_vulnerabilities.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<v:rating>
2929
<v:severity>Low</v:severity>
3030
<v:method>OWASP Risk</v:method>
31-
<v:vector>OWASP/K9:M1:O0:Z2/D1:X1:W1:L3/C2:I1:A1:T1/F1:R1:S2:P3/50</v:vector>
31+
<v:vector>K9:M1:O0:Z2/D1:X1:W1:L3/C2:I1:A1:T1/F1:R1:S2:P3/50</v:vector>
3232
</v:rating>
3333
</v:ratings>
3434
<v:cwes>

tests/test_model_vulnerability.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,69 @@ def test_v_source_parse_owasp_1(self):
7676
VulnerabilitySourceType.get_from_vector('OWASP/K9:M1:O0:Z2/D1:X1:W1:L3/C2:I1:A1:T1/F1:R1:S2:P3/50'),
7777
VulnerabilitySourceType.OWASP
7878
)
79+
80+
def test_v_source_get_localised_vector_cvss3_1(self):
81+
self.assertEqual(
82+
VulnerabilitySourceType.CVSS_V3.get_localised_vector(vector='CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'),
83+
'AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'
84+
)
85+
86+
def test_v_source_get_localised_vector_cvss3_2(self):
87+
self.assertEqual(
88+
VulnerabilitySourceType.CVSS_V3.get_localised_vector(vector='CVSS:3.0AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'),
89+
'AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'
90+
)
91+
92+
def test_v_source_get_localised_vector_cvss3_3(self):
93+
self.assertEqual(
94+
VulnerabilitySourceType.CVSS_V3.get_localised_vector(vector='AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'),
95+
'AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'
96+
)
97+
98+
def test_v_source_get_localised_vector_cvss2_1(self):
99+
self.assertEqual(
100+
VulnerabilitySourceType.CVSS_V2.get_localised_vector(vector='CVSS:2.0/AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'),
101+
'AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'
102+
)
103+
104+
def test_v_source_get_localised_vector_cvss2_2(self):
105+
self.assertEqual(
106+
VulnerabilitySourceType.CVSS_V2.get_localised_vector(vector='CVSS:2.1AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'),
107+
'AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'
108+
)
109+
110+
def test_v_source_get_localised_vector_cvss2_3(self):
111+
self.assertEqual(
112+
VulnerabilitySourceType.CVSS_V2.get_localised_vector(vector='AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'),
113+
'AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'
114+
)
115+
116+
def test_v_source_get_localised_vector_owasp_1(self):
117+
self.assertEqual(
118+
VulnerabilitySourceType.OWASP.get_localised_vector(vector='OWASP/AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'),
119+
'AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'
120+
)
121+
122+
def test_v_source_get_localised_vector_owasp_2(self):
123+
self.assertEqual(
124+
VulnerabilitySourceType.OWASP.get_localised_vector(vector='OWASPAV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'),
125+
'AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'
126+
)
127+
128+
def test_v_source_get_localised_vector_owasp_3(self):
129+
self.assertEqual(
130+
VulnerabilitySourceType.OWASP.get_localised_vector(vector='AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'),
131+
'AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N'
132+
)
133+
134+
def test_v_source_get_localised_vector_other_1(self):
135+
self.assertEqual(
136+
VulnerabilitySourceType.OPEN_FAIR.get_localised_vector(vector='SOMETHING_OR_OTHER'),
137+
'SOMETHING_OR_OTHER'
138+
)
139+
140+
def test_v_source_get_localised_vector_other_2(self):
141+
self.assertEqual(
142+
VulnerabilitySourceType.OTHER.get_localised_vector(vector='SOMETHING_OR_OTHER'),
143+
'SOMETHING_OR_OTHER'
144+
)

0 commit comments

Comments
 (0)