X

Request a demo

Thank you. We will be in touch with you shortly.
Cybeats announces brand new BCA Marketplace for SBOM generation. Read the announcement.

The Importance Of Validation In SBOM Generation

Tern is an open source software composition analysis and SBOM generation tool that generates SBOMs from container images. However, upon running this tool and generating a CycloneDX SBOM, a problem arose. The SBOM was deemed invalid by several SBOM processing tools, such as the CycloneDXWeb Tool:



In addition to the CycloneDX CLI as shown here:


Upon further investigation the reason was found, within the SBOM’s licenses.

The CycloneDX SBOM format defines a license in two main ways; ID (with optional additional data) or Name. The difference between them was the key between a valid SBOM and an invalid one.

A CycloneDX Name is merely a string of characters, and can be of anything. However, a CycloneDX License ID is a string that must consist of a valid SPDXLicense ID e.g. “GPL-2.0”. With this information, we can now review a specific component case within the SBOM, specifically an SBOM created from a Debian Buster container image.

{
"name": "apt",
"version": "1.8.2.3",
"type": "application",
"purl": "pkg:deb/debian/apt@1.8.2.3",
"evidence": {
"licenses": [
{"license": { "id": "GPLv2+" }}
] }}

As we can see, the component apt contains a single license, that of the ID “GPLv2+”. However, this is not a valid SPDX License ID. This alone would render the entire SBOM invalid, and there were over 200 such cases in this particular SBOM.

The cause of this problem is unvalidated license generation. Tern creates the license cases for a CycloneDX SBOM using the data from container images “as is'', without regard for formatting  or validation in accordance with the CycloneDX Schema, as shown here:

def get_license_from_name(name):
                return{'license': {'id': name}}

As we can see, the get_license_from_name function simply returns a python dictionary, with the license variable name as the value to an ID key. This is then assembled into a wider CycloneDX dictionary and output as a JSON using the CycloneDXJSON class as shown here:

class CycloneDXJSON(generator.Generate):
def generate(self,image_obj_list,print_inclusive=False):
''' Generate aCycloneDX document
The whole document should be stored in adictionary which can be
converted to JSON and dumped to a file using the write_report function
in report.py.'''
logger.debug('Generating CycloneDX JSON document...')
report=get_document_dict(image_obj_list)
return json.dumps(report,indent=2)

This chain of events results in a CycloneDX SBOM that outwardly looks correct, but in reality is invalid.

There are several solutions to this issue. The first and easiest, is to simply have the get_license_from_name function always return the license as a name as shown here:

def get_license_from_name(name):
return{'license':{'id':name}}

However this robs the SBOM of potentially valuable license ID information that can be passed to an SBOM parser.

As such, a more elegant solution can be applied with the useof the CycloneDX Python Library. Utilizing this library, we can take advantage of its component validation functionality, and create avalidation step:

from cyclonedx.spdx import fixup_id as spdx_id_validate
def get_license_from_name(name):
spdx_id=spdx_id_validate(name)
if spdx_id:
return {'license':{'id':spdx_id}}
else:
return {'license':{'name':name}}

This modified function first checks the input name variable to determine if it is a valid SPDX License ID. If it is, it returns the license as a license ID. Otherwise, it returns it as a license Name. This can be validated by recreating the original SBOM, and checking the same component.

{
"name":"apt",
"version":"1.8.2.3",
"type":"application",
"purl":"pkg:deb/debian/apt@1.8.2.3",
"evidence":{
"licenses":[
{"license":{"name":"GPLv2+"}}
]}}

As we can see “GPLv2+” is now a license Name. If we run this new SBOM through the CycloneDX Webtool:



Inaddition to the CycloneDX CLI:


We can now see the SBOM is valid.

The Importance Of Validation In SBOM Generation

March 19, 2024

Tern is an open source software composition analysis and SBOM generation tool that generates SBOMs from container images. However, upon running this tool and generating a CycloneDX SBOM, a problem arose.

Read More →

The Power of SBOMs: Building Resilience in Our Critical Infrastructure

March 4, 2024

As a member of the PCAST Working Group on Cyber-Physical Resilience, I was involved in crafting the recent report outlining crucial steps to fortify the intricate systems that underpin our daily lives. One of our key recommendations, "Recommendation 4B: Promote Supply Chain

Read More →

Revolutionizing Healthcare Security: The Power of the Health-ISAC and Cybeats Partnership in SBOM use

December 15, 2023

Notably, the Health Information Sharing and Analysis Center (Health-ISAC) is entering into a partnership with Cybeats, a leading software supply chain intelligence company, marking a substantial advancement in healthcare cybersecurity.

Read More →

See Cybeats Security
Platform in Action Today.