Skip to content

Commit b5ebcf8

Browse files
authored
feat: add workaround property for v1.5 and v1.6 (#642)
Property `workaround` was missing from the vulnerability model. It was added in spec v1.5 and was marked as TODO before. This is my first contribution on this project so if I done something wrong, just say me 😃 Signed-off-by: Louis Maillard <[email protected]> Signed-off-by: Louis Maillard <[email protected]> Co-authored-by: Louis Maillard <[email protected]>
1 parent 5b74b0f commit b5ebcf8

7 files changed

+29
-14
lines changed

cyclonedx/model/vulnerability.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,7 @@ def __init__(
942942
description: Optional[str] = None,
943943
detail: Optional[str] = None,
944944
recommendation: Optional[str] = None,
945+
workaround: Optional[str] = None,
945946
advisories: Optional[Iterable[VulnerabilityAdvisory]] = None,
946947
created: Optional[datetime] = None,
947948
published: Optional[datetime] = None,
@@ -964,6 +965,7 @@ def __init__(
964965
self.description = description
965966
self.detail = detail
966967
self.recommendation = recommendation
968+
self.workaround = workaround
967969
self.advisories = advisories or [] # type:ignore[assignment]
968970
self.created = created
969971
self.published = published
@@ -1120,15 +1122,23 @@ def recommendation(self) -> Optional[str]:
11201122
def recommendation(self, recommendation: Optional[str]) -> None:
11211123
self._recommendation = recommendation
11221124

1123-
# @property
1124-
# @serializable.view(SchemaVersion1Dot5)
1125-
# @serializable.xml_sequence(9)
1126-
# def workaround(self) -> ...:
1127-
# ... # TODO since CDX 1.5
1128-
#
1129-
# @workaround.setter
1130-
# def workaround(self, ...) -> None:
1131-
# ... # TODO since CDX 1.5
1125+
@property
1126+
@serializable.view(SchemaVersion1Dot5)
1127+
@serializable.view(SchemaVersion1Dot6)
1128+
@serializable.xml_sequence(9)
1129+
def workaround(self) -> Optional[str]:
1130+
"""
1131+
A bypass, usually temporary, of the vulnerability that reduces its likelihood and/or impact.
1132+
Workarounds often involve changes to configuration or deployments.
1133+
1134+
Returns:
1135+
`str` if set else `None`
1136+
"""
1137+
return self._workaround
1138+
1139+
@workaround.setter
1140+
def workaround(self, workaround: Optional[str]) -> None:
1141+
self._workaround = workaround
11321142

11331143
# @property
11341144
# @serializable.view(SchemaVersion1Dot5)
@@ -1310,8 +1320,8 @@ def __lt__(self, other: Any) -> bool:
13101320
def __hash__(self) -> int:
13111321
return hash((
13121322
self.id, self.source, tuple(self.references), tuple(self.ratings), tuple(self.cwes), self.description,
1313-
self.detail, self.recommendation, tuple(self.advisories), self.created, self.published, self.updated,
1314-
self.credits, tuple(self.tools), self.analysis, tuple(self.affects), tuple(self.properties)
1323+
self.detail, self.recommendation, self.workaround, tuple(self.advisories), self.created, self.published,
1324+
self.updated, self.credits, tuple(self.tools), self.analysis, tuple(self.affects), tuple(self.properties)
13151325
))
13161326

13171327
def __repr__(self) -> str:

tests/_data/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ def get_bom_with_component_setuptools_with_vulnerability() -> Bom:
477477
)
478478
],
479479
cwes=[22, 33], description='A description here', detail='Some detail here',
480-
recommendation='Upgrade',
480+
recommendation='Upgrade', workaround='Describe the workarounds here',
481481
advisories=[
482482
VulnerabilityAdvisory(url=XsUri('https://nvd.nist.gov/vuln/detail/CVE-2018-7489')),
483483
VulnerabilityAdvisory(url=XsUri('http://www.securitytracker.com/id/1040693'))

tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.5.json.bin

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@
199199
"vendor": "CycloneDX"
200200
}
201201
],
202-
"updated": "2021-09-03T10:50:42.051979+00:00"
202+
"updated": "2021-09-03T10:50:42.051979+00:00",
203+
"workaround": "Describe the workarounds here"
203204
}
204205
],
205206
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",

tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.5.xml.bin

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
<description>A description here</description>
104104
<detail>Some detail here</detail>
105105
<recommendation>Upgrade</recommendation>
106+
<workaround>Describe the workarounds here</workaround>
106107
<advisories>
107108
<advisory>
108109
<url>http://www.securitytracker.com/id/1040693</url>

tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.6.json.bin

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@
205205
"vendor": "CycloneDX"
206206
}
207207
],
208-
"updated": "2021-09-03T10:50:42.051979+00:00"
208+
"updated": "2021-09-03T10:50:42.051979+00:00",
209+
"workaround": "Describe the workarounds here"
209210
}
210211
],
211212
"$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",

tests/_data/snapshots/get_bom_with_component_setuptools_with_vulnerability-1.6.xml.bin

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
<description>A description here</description>
104104
<detail>Some detail here</detail>
105105
<recommendation>Upgrade</recommendation>
106+
<workaround>Describe the workarounds here</workaround>
106107
<advisories>
107108
<advisory>
108109
<url>http://www.securitytracker.com/id/1040693</url>

tests/test_model_vulnerability.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ def test_empty_vulnerability(self) -> None:
171171
self.assertIsNone(v.description)
172172
self.assertIsNone(v.detail)
173173
self.assertIsNone(v.recommendation)
174+
self.assertIsNone(v.workaround)
174175
self.assertFalse(v.advisories)
175176
self.assertIsNone(v.created)
176177
self.assertIsNone(v.published)

0 commit comments

Comments
 (0)