Technical Introduction to Software Bill of Materials (SBOMs)

What is an SBOM

Software Bill of Materials (or SBOMs) have been around for over a decade and in their simplest form are a structured list of 3rd party software, components and libraries included directly, or indirectly, in your code.

Why are SBOMs useful

SBOMs are useful from a number of use cases/personas:

  • List all dependencies (developer)
  • Remove unused software (developer)
  • Update stale software (developer)
  • Identify non-compliant software license (developer/product)
  • Remediate dependencies with know vulnerabilities (developer/security/product)

SBOM Standards

In 2011, the Linux Foundation released the SPDX standard to ease software licensing compliance issues [^1]. Over time, the spec has evolved to support broader use cases such as out-of-date software, security vulnerabilities and more.

More recently, CycloneDX emerged as another open standard and is being actively developed. It was accepted as a Flagship OWASP Project and provides links to many useful SBOM tools. CycloneDX is also tightly integrated with Dependency-Track, another open source OWASP project for continuous analysis of SBOMs.

Example SBOM component entry (CycloneDX)

For a quick example, it’s helpful to take a look at a component entry from a CycloneDX SBOM. For this example, I generated an SBOM for ios-triage, a cli app I wrote years ago for iOS incident response. I chose to output the SBOM in JSON (CycloneDX also supports XML) and am showing the async npm package (stored in an array of components):

  "components": [
    {
      "type": "library",
      "bom-ref": "pkg:npm/async@2.6.1",
      "author": "Caolan McMahon",
      "name": "async",
      "version": "2.6.1",
      "description": "Higher-order functions and common patterns for asynchronous code",
      "hashes": [
        {
          "alg": "SHA-512",
          "content": "7cd1222f6f8066de80940c3fdbd0abd140dee2c4401c2a441e1e7858ccfe05bed07cd705c38877968a1fc89a4b790b38631ef2baa
bbfd9d2e033984a3ace8795"
        }
      ],
      "licenses": [
        {
          "license": {
            "id": "MIT"
          }
        }
      ],
      "purl": "pkg:npm/async@2.6.1",
      "externalReferences": [
        {
          "type": "website",
          "url": "https://caolan.github.io/async/"
        },
        {
          "type": "issue-tracker",
          "url": "https://github.com/caolan/async/issues"
        },
        {
          "type": "vcs",
          "url": "git+https://github.com/caolan/async.git"
        }
      ]
    },
	<snip>
	]

As you can see, there are a number of really helpful properties tracked for each dependency.

package URL

One key item to point out in the example above is the purl property, short for package URL. If you’ve been in security for a while and worked on matching software components with known vulnerabilities (e.g. CVEs tracked in the National Vulnerability Database), it can get really tricky! NIST developed a structured naming scheme called Common Platform Enumeration (CPE) which is thorough but in practice I found it cumbersome to work with. For example, the above async package has (quite a few) vulnerabilities. One example is CVE-2021-43138 and the CPE entries for the listing are:

cpe:2.3:a:async_project:async:*:*:*:*:*:*:*:*
cpe:2.3:a:async_project:async:*:*:*:*:*:*:*:*

If you visit the CVE detail page, you can expand each CPE configuration to see a full list of matching CPEs. But both reading and coding for the sheer number of * was always fraught with error for me.

So that’s what I like about purls - they are very simple structures that specifically describe a package and the ecosystem it’s a part of. And when you leverage software like Dependency-Track, it will handle look ups against vulnerability databases (future topic for this series!).

Next Steps

If you’re new to Software Bill of Materials, I hope you found this blog useful. I’m planning on a number of follow up parts to this series including:

  1. Technical introduction to Software Bill of Materials (SBOMs)
  2. How to generate a Node.JS SBOM in CycloneDX format
  3. Source code vs binary analysis for SBOMs
  4. How to generate an Android (React Native) SBOM in CycloneDX format
  5. Generating an Android SBOM on each build of your mobile app with GitHub Actions
  6. Generating an iOS SBOM on each build of your mobile app with GitHub Actions
  7. Leveraging Dependency-Track to continuously analyze your mobile SBOMs

If you have any suggestions for other topics or feedback in general, please connect with me and let me know!

[^1] https://en.wikipedia.org/wiki/Software_Package_Data_Exchange#cite_note-computer-weekly-3