Skip to content
Codenotary
All posts

Apps Need to Provide Their Own SBOM

Software Bill of Materials (SBOM) isn’t a particularly complex concept: it’s a manifest that identifies the components that make up a particular software artifact. It’s like the list of ingredients of a cake. Accordingly, for applications an SBOM is a list of all the ingredients or components that went into building the app. 

While SBOMs aren’t a new thing, they have lately become very important because of a surge of software supply chain attacks that have made our most critical government and businesses vulnerable to ill-intentioned actors (state and criminal). A good example is the supply chain vulnerability thru Log4j, a highly popular logging framework, which infected hundreds of thousands of applications and the businesses and governments running them. 

When the log4j supply chain vulnerability was discovered in December 2021, the first question of every CIO was “how can I find all instances of this log4j library in the hundreds or thousands of applications in my business?”. In other words, every organization wants to know which applications to trust and which ones to sanitize immediately.

However, traditional SBOMs are just a snapshot in time of the list of components of an app. It needs to be kept up to date and provided with the application every time a simple update or patch to the application is performed. What guarantee do we have that the SBOM is truly up to date and that it includes the true, full list of contents of an application? None. 

But wait, it gets even more complicated! Some applications update themselves at runtime. Or even think of serverless applications that only run for a short period of time. Who generates an SBOM for an application that self-updates?

If we had a true and trustworthy SBOM of every application available, then it’s a simple and fast search. So, how to obtain an SBOM for the apps we use?

We at Codenotary have created a patent-pending solution to both these questions and thus guarantee that an SBOM of an app is always:

a) a true reflection of the components of an application, even when it self-updates, and 

b) the SBOM is not some file that is stored separately from the application, 

but rather it’s the application itself that – on authenticated request – will export its own SBOM or list of ingredients 

How do we do that

By simply adding 2 lines of code to your source code

That enables any developer to add automatic SBOM export to applications and they always travel with them. We call it TrueSBOM.

Let’s look into a Python and a Golang example:

Python

import truesbom
truesbom.start_http_server(8001)

Go

go truesbom.Start_http_Handler(":8001")

What are the benefits of using TrueSBOM?:

  • Always updated SBOM
  • Runtime changes of dependency usage
  • Diff between compile SBOM and actual runtime SBOM
  • Alert on dependency on change events 
  • Works for open-source and closed source
  • Machine-readable for automation
  • Great in combination with serverless applications

How does it work

When the application reaches its destination (i. E. the customer) the SBOM can always be retrieved by accessing the system on Port 8001 (in the example above). The result is machine-readable and can be used to collect, compare and update the central SBOM information.

The minimal SBOM structure looks like this:

  • Supplier name
  • Component name
  • Version of the component
  • Cryptographic hash of the component
  • Any other unique identifier
  • Dependency relationship
  • Author of the SBOM data

TrueSBOM also allows the enrichment of the SBOMs with vulnerability scanner results or trust and integrity information.

Example output:

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.4",
  "version": 1,
  "metadata": {
    "tools": [
      {
        "vendor": "Codenotary",
        "name": "vcn",
        "version": "v1.0.2-dev"
      }
    ],
    "component": {
      "type": "application",
      "name": "."
    }
  },
  "components": [
    {
      "bom-ref": ".-1",
      "type": "library",
      "name": "github.com/rakyll/statik",
      "version": "v0.1.7",
      "hashes": [
        {
          "alg": "SHA-256",
          "content": "385dd009952ec8fc6e1843fb078ca951aeec07f887b6a3930d865718cf0a39d4"
        }
      ],
      "licenses": [
        {
          "expression": "Apache-2.0"
        }
      ],
      "purl": "pkg:golang/github.com%!F(MISSING)rakyll%!F(MISSING)statik@v0.1.7",
      "properties": [
        {
          "name": "LinkType",
          "value": "direct"
        },
        {
          "name": "TrustLevel",
          "value": "TRUSTED"
        }
      ]
    }
  ]
}