SBOM 简介以及如何将其与 CI 结合使用

452 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情

详细了解 SBOM(软件物料清单)、使用它的原因、标准是什么以及如何通过持续集成实现自动化。

什么是物料清单?

BOM代表物料清单,汽车行业长期以来一直将其用作供应链管理的一种方法。

想象一下,你刚买了一辆新车。也许你的车是由丰田、大众或任何你喜欢的品牌制造的(更准确地说,是组装的)。但是,如今分工如此普遍,以至于没有一家汽车公司可以单独制造汽车所需的所有部件。许多零件是由世界各地的其他公司、供应商或分包商制造的。

汽车行业的物料清单 (BOM) 告诉你每个零件的来源,详细说明你的汽车运行的每个组件。假设某批零件(例如安全气囊)已被生产它们的公司召回。在这种情况下,你的汽车制造商可以参考 BOM 以了解特定批次的安全气囊最终出现在哪些汽车上,因此它可以对那些受影响的车辆采取行动。

什么是SBOM?

SBOM 代表软件物料清单,它已成为软件安全和供应链管理领域的重要组成部分。

尽管构建软件与制造汽车并不完全相同,但它们之间存在相似之处。

SBOM的官方定义如下:

软件物料清单 (SBOM) 是一个完整的、正式结构化的组件、库和模块列表,这些组件、库和模块是构建(即编译和链接)给定软件以及它们之间的供应链关系所需的。这些组件可以是开源的或专有的,免费的或付费的,可以广泛使用或限制访问。

为什么 SBOM 在安全中发挥关键作用

扫描 SBOM 库比从头开始扫描整个基础架构更快、更容易。安全团队还可以利用 SBOM 根据问题的存在和位置确定修复问题的优先级,并创建特定于组件属性(例如供应商、版本或包类型等)的策略。

开发团队还可以受益于使用 SBOM 来跟踪应用程序中的开源、商业和定制软件组件。这有助于开发人员管理依赖关系、识别早期补救安全问题,并确保开发人员使用已批准的代码和源代码。当第三方库存在已知的常见漏洞时,如果你有SBOM,你可以快速判断软件是否受到影响。

由于其重要意义,可以在团队和公司之间无摩擦地共享的 SBOM 是未来几十年关键行业和数字基础设施软件管理的核心构建块。

SBOM格式标准

SBOM 是一种正式的结构化记录,它不仅详细说明了软件产品的组件,还描述了其供应链关系。SBOM 概述了哪些包和库进入了你的应用程序,以及这些包和库与其他上游项目之间的关系——这在涉及重用代码和开源时尤为重要。

由于 SBOM 包含大量信息,因此必须有一些标准才能有效地交换信息,尤其是在自动化方面。SBOM 格式就是为了这个目的:它们是定义统一结构的标准,用于生成 SBOM 并与最终用户或客户共享它们。它们以其他工具可以理解的标准格式描述软件组合。

主要的SBOM格式是软件包数据交换(SPDX)和CycloneDX,它们都被用于安全用例。

SPDX

SPDX是Linux基金会的一个项目,它的主要目标是为软件包相关的信息创建一个标准的数据交换格式。英特尔、微软、西门子和索尼等大公司都参与了SPDX社区。到目前为止,最新的SPDX规范是版本2.2.2。特定的字段和部分必须被认为是有效的SPDX文档。

CycloneDX

CycloneDX是一个轻量级的SBOM标准,设计用于应用程序安全上下文和供应链组件分析。该规范的战略方向和维护由CycloneDX Core工作组管理,该工作组起源于长期的安全社区领导者开放Web应用程序安全项目(OWASP)。CycloneDX的独特之处在于它被设计成BOM格式,并满足各种用例,包括软件即服务BOM (SaaSBOM)。

如何使用 CI 自动化 SBOM

当然,可以使用一堆工具来生成 SBOM,它们可以与您的 CI 系统集成。在本节中,我们将结合使用GitHub ActionsSyft来执行此操作。

Syft 是一个 CLI 工具和 Go 库,用于从容器镜像和文件系统生成 SBOM,它支持 SPDX 和 CycloneDX 格式。

首先,让我们创建一个带有模块的简单 Golang 应用程序(生成的 SBOM 将不包含任何内容)。

让我们看一下这段简单的代码:它是一个调用另一个 Go 模块的 HelloWorld 演示:

package main

import (
  "fmt"
    hello "github.com/ironcore864/go-hello-module"
)

func main() {
  fmt.Println(hello.Hello())
}

然后,让我们创建一个包含以下内容的 GitHub Action:

name: SBOM

on:
  release:
    types: [published]

jobs:
  sbom:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          ref: ${{ github.ref_name }}
      - name: Anchore SBOM Action
        uses: anchore/sbom-action@v0.12.0
        with:
          format: cyclonedx-json

这个动作:

  • 仅在发布时运行。
  • 检查标签。
  • 运行anchore/sbom-action,它用于syft生成 CycloneDX 格式的 SBOM 作为 JSON 文件。
  • 将 JSON 文件上传到发布的工件。

GitHub Actions 文件准备就绪后,通过创建发布来触发作业。

现在,我们可以下载 SBOM 并查看内容:

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.4",
  "serialNumber": "urn:uuid:a61bf508-f014-4cfb-98e5-5564e3699ec1",
  "version": 1,
  "metadata": {
    "timestamp": "2022-10-10T04:45:04Z",
    "tools": [
      {
        "vendor": "anchore",
        "name": "syft",
        "version": "0.53.4"
      }
    ],
    "component": {
      "bom-ref": "af63bd4c8601b7f1",
      "type": "file",
      "name": "."
    }
  },
  "components": [
    {
      "bom-ref": "pkg:golang/github.com/ironcore864/go-hello-module@v0.1.0?package-id=caa41d3c947da3ea",
      "type": "library",
      "name": "github.com/ironcore864/go-hello-module",
      "version": "v0.1.0",
      "cpe": "cpe:2.3:a:ironcore864:go-hello-module:v0.1.0:*:*:*:*:*:*:*",
      "purl": "pkg:golang/github.com/ironcore864/go-hello-module@v0.1.0",
      "properties": [
        {
          "name": "syft:package:foundBy",
          "value": "go-mod-file-cataloger"
        },
        {
          "name": "syft:package:language",
          "value": "go"
        },
        {
          "name": "syft:package:type",
          "value": "go-module"
        },
        {
          "name": "syft:cpe23",
          "value": "cpe:2.3:a:ironcore864:go_hello_module:v0.1.0:*:*:*:*:*:*:*"
        },
        {
          "name": "syft:location:0:path",
          "value": "go.mod"
        }
      ]
    }
  ]
}

简要说明:正如预期的那样,我们首先看到对 BOM 格式 (CycloneDX) 和版本的引用,然后是与此唯一 BOM 相对应的唯一序列号。如果我们在不更改内容的情况下重新生成 SBOM,则此 ID 将不同。

然后我们有一些元数据,最后是组件列表。你可以看到“CPE”和“PURL”字段,这些实际上是漏洞规范:CPE 实际上有点过时,但包 URL (PURL) 是另一个通用识别包的标准。

这意味着无论包属于哪个供应商、项目或生态系统,都可以为其关联一个唯一的 ID。因此,可以根据漏洞数据库计算相关风险。

总结

随着越来越多地使用第三方开源库来构建容器化的分布式应用程序,准确了解软件中的哪些部分变得更具挑战性。这就是 SBOM 越来越受欢迎的原因。