Skip to content

Commit 86b8bf0

Browse files
committed
add aboutcode:is_reachable property in CycloneDX export
Signed-off-by: tdruez <tdruez@aboutcode.org>
1 parent b5c6e49 commit 86b8bf0

2 files changed

Lines changed: 49 additions & 2 deletions

File tree

vulnerabilities/models.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from django.utils import timezone
2020
from django.utils.translation import gettext_lazy as _
2121

22+
from cyclonedx import model as cdx_model
2223
from cyclonedx.model import vulnerability as cdx_vulnerability
2324

2425
from dje.fields import JSONListField
@@ -266,7 +267,16 @@ def as_cyclonedx(self, affected_instances, analysis=None):
266267
for instance in affected_instances
267268
]
268269

269-
analysis = analysis.as_cyclonedx() if analysis else None
270+
properties = None
271+
if analysis is not None and analysis.is_reachable is not None:
272+
properties = [
273+
cdx_model.Property(
274+
name="aboutcode:is_reachable",
275+
value="true" if analysis.is_reachable else "false",
276+
)
277+
]
278+
279+
cdx_analysis = analysis.as_cyclonedx() if analysis else None
270280

271281
source = cdx_vulnerability.VulnerabilitySource(
272282
name="VulnerableCode",
@@ -278,7 +288,8 @@ def as_cyclonedx(self, affected_instances, analysis=None):
278288
source=source,
279289
description=self.summary,
280290
affects=affects,
281-
analysis=analysis,
291+
analysis=cdx_analysis,
292+
properties=properties,
282293
)
283294

284295

vulnerabilities/tests/test_models.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,42 @@ def test_vulnerability_model_as_cyclonedx(self):
319319
}
320320
self.assertEqual(expected, as_dict["analysis"])
321321

322+
def test_vulnerability_model_as_cyclonedx_is_reachable_property(self):
323+
vulnerability = make_vulnerability(self.dataspace)
324+
package = make_package(self.dataspace)
325+
product_package = make_product_package(make_product(self.dataspace), package=package)
326+
327+
def make_analysis(is_reachable):
328+
return VulnerabilityAnalysis(
329+
product_package=product_package,
330+
vulnerability=vulnerability,
331+
dataspace=self.dataspace,
332+
state=VulnerabilityAnalysis.State.IN_TRIAGE,
333+
is_reachable=is_reachable,
334+
)
335+
336+
cdx = vulnerability.as_cyclonedx(
337+
affected_instances=[package], analysis=make_analysis(True)
338+
)
339+
as_dict = json.loads(cdx.as_json())
340+
self.assertEqual(
341+
[{"name": "aboutcode:is_reachable", "value": "true"}], as_dict["properties"]
342+
)
343+
344+
cdx = vulnerability.as_cyclonedx(
345+
affected_instances=[package], analysis=make_analysis(False)
346+
)
347+
as_dict = json.loads(cdx.as_json())
348+
self.assertEqual(
349+
[{"name": "aboutcode:is_reachable", "value": "false"}], as_dict["properties"]
350+
)
351+
352+
cdx = vulnerability.as_cyclonedx(
353+
affected_instances=[package], analysis=make_analysis(None)
354+
)
355+
as_dict = json.loads(cdx.as_json())
356+
self.assertNotIn("properties", as_dict)
357+
322358
def test_vulnerability_model_vulnerability_analysis_save(self):
323359
vulnerability1 = make_vulnerability(dataspace=self.dataspace)
324360
product_package1 = make_product_package(make_product(self.dataspace))

0 commit comments

Comments
 (0)