anchore / syft

CLI tool and library for generating a Software Bill of Materials from container images and filesystems
Apache License 2.0
6.1k stars 562 forks source link

OS information missing in SPDX format SBOM for a container image #3012

Open kl-sinclair opened 3 months ago

kl-sinclair commented 3 months ago

What happened:

When generating an SPDX for container images like Redis or Ubuntu, only package information is included, but OS information, such as Alpine or Ubuntu, is not included in the Package Information section.

Redis: https://gist.github.com/kl-sinclair/eec66cc2a577a4c702521b20217a1bac

Ubuntu: https://gist.github.com/kl-sinclair/dfab9b10e93be204d8d76b69e2662333

What you expected to happen:

OS information should be included as a package. For example, as follows:

...
  "packages": [
    ...
    {
      "name": "alpine",
      "SPDXID": "SPDXRef-OperatingSystem-alpine-xxxxxxxxxxxxxxxx",
      "versionInfo": "3.20.1",
      "downloadLocation": "NONE",
      "filesAnalyzed": false,
      ...
      "primaryPackagePurpose": "OPERATING-SYSTEM"
    }
...

or

##### Package: ubuntu

PackageName: ubuntu
SPDXID: SPDXRef-OperatingSystem-ubuntu-xxxxxxxxxxxxxxxx
PackageVersion: 24.04
PackageDownloadLocation: NONE
PrimaryPackagePurpose: OPERATING-SYSTEM
FilesAnalyzed: false
...

Steps to reproduce the issue:

syft scan redis:6-alpine -o spdx-json=syft-redis.spdx.json
syft scan ubuntu:latest -o spdx-json=syft-ubuntu.spdx.json

Anything else we need to know?:

With CycloneDX, OS information is included as a component:

syft-redis.cdx.json:

...
  "components": [
    ...
    {
      "bom-ref": "os:alpine@3.16.0",
      "type": "operating-system",
      "name": "alpine",
      "version": "3.16.0",
      "description": "Alpine Linux v3.16",
      "swid": {
        "tagId": "alpine",
        "name": "alpine",
        "version": "3.16.0"
      },
      "externalReferences": [
        {
          "url": "https://gitlab.alpinelinux.org/alpine/aports/-/issues",
          "type": "issue-tracker"
        },
        {
          "url": "https://alpinelinux.org/",
          "type": "website"
        }
      ],
      "properties": [
        {
          "name": "syft:distro:id",
          "value": "alpine"
        },
        {
          "name": "syft:distro:prettyName",
          "value": "Alpine Linux v3.16"
        },
        {
          "name": "syft:distro:versionID",
          "value": "3.16.0"
        }
      ]
    }
...

syft-ubuntu.cdx.json:

...
  "components": [
    ...
    {
      "bom-ref": "os:ubuntu@22.04",
      "type": "operating-system",
      "name": "ubuntu",
      "version": "22.04",
      "description": "Ubuntu 22.04.1 LTS",
      "swid": {
        "tagId": "ubuntu",
        "name": "ubuntu",
        "version": "22.04"
      },
      "externalReferences": [
        {
          "url": "https://bugs.launchpad.net/ubuntu/",
          "type": "issue-tracker"
        },
        {
          "url": "https://www.ubuntu.com/",
          "type": "website"
        },
        {
          "url": "https://help.ubuntu.com/",
          "comment": "support",
          "type": "other"
        },
        {
          "url": "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy",
          "comment": "privacyPolicy",
          "type": "other"
        }
      ],
      "properties": [
        {
          "name": "syft:distro:id",
          "value": "ubuntu"
        },
        {
          "name": "syft:distro:idLike:0",
          "value": "debian"
        },
        {
          "name": "syft:distro:prettyName",
          "value": "Ubuntu 22.04.1 LTS"
        },
        {
          "name": "syft:distro:versionCodename",
          "value": "jammy"
        },
        {
          "name": "syft:distro:versionID",
          "value": "22.04"
        }
      ]
    }
...

Environment:

$ syft version
Application: syft
Version:    1.8.0
BuildDate:  2024-06-24T15:27:29Z
GitCommit:  Homebrew
GitDescription: [not provided]
Platform:   darwin/amd64
GoVersion:  go1.22.4
Compiler:   gc
popey commented 3 months ago

Thanks for the issue. I've reproduced this on Syft 1.9.0.

spiffcs commented 3 months ago

Just to add some supporting evidence for this issue: https://spdx.github.io/spdx-spec/v2.3/package-information/#724-primary-package-purpose-field

The package information in v2.3 allows for formats that identify the primary package purpose:

APPLICATION | FRAMEWORK | LIBRARY | CONTAINER | 
OPERATING-SYSTEM | DEVICE | FIRMWARE | SOURCE | 
ARCHIVE | FILE | INSTALL | OTHER |

Operating System is included in this enum so including the discovered operating system as a package in spdx would be the correct spot. Syft has data for this in it's underlying json format. It's just a matter of creating the package during the format serialization.