Spring Boot 3.3 中的 SBOM 支持

工程 | 莫里茨·哈尔布里特 | 2024 年 5 月 24 日 | ...

Spring Boot 3.3.0 已发布,其中包含对 SBOM 的支持。SBOM 代表“软件物料清单”(Software Bill of Materials),描述了用于构建软件工件的组件。在本博文的上下文中,那就是您的 Spring Boot 应用程序。这些 SBOM 非常有用,因为它们精确地描述了您的应用程序包含的内容。有了这些信息,您就可以评估安全漏洞是否会影响您的应用程序,或者使用自动安全工具扫描您的应用程序并提醒您安全漏洞。

市面上存在多种 SBOM 格式,最广泛使用的是 CycloneDXSPDXSyft。Spring Boot 3.3.0 开箱即用地支持 CycloneDX。支持包括三个支柱:

  • 在构建应用程序时生成 SBOM 的 CycloneDX 插件配置
  • 将生成的 SBOM 文件打包到 uber jar 中
  • 一个执行器端点,用于公开生成的 SBOM(如果已启用)

让我们来看看它是如何工作的

首先,在 start.spring.io 上生成一个新项目(确保选择 Spring Boot 3.3.0),并包含以下依赖项:

  • Spring Web
  • 执行器 (Actuator)

现在,在您的 IDE 中打开生成的项目,如果您使用的是 Gradle,请将以下内容添加到您的 build.gradle 文件中:

plugins {
  id 'org.cyclonedx.bom' version '1.8.2'
}

这会将 CycloneDX Gradle 插件应用于您的构建。Spring Boot 会检测到这一点,并负责插件的配置,您无需进行任何进一步的更改。

如果您使用的是 Maven,请将以下内容添加到您的 pom.xml 文件中:

<plugins>
  <plugin>
    <groupId>org.cyclonedx</groupId>
    <artifactId>cyclonedx-maven-plugin</artifactId>
  </plugin>
</plugins>

这会将 CycloneDX Maven 插件添加到您的构建中。Spring Boot 通过其父项目自动管理此插件的版本,并负责配置插件。

现在使用 gradle buildmvn package 命令构建您的 uber jar。在构建过程中,Spring Boot 会借助 CycloneDX 插件生成一个 SBOM,并将其包含在 uber jar 中。如果您查看 uber jar 的内容,会发现在 META-INF/sbom/application.cdx.json 文件中包含了 SBOM。Spring Boot 还会在 jar 清单中添加 SBOM 的位置和格式,以便扫描工具能够找到它。

Sbom-Location: META-INF/sbom/application.cdx.json
Sbom-Format: CycloneDX

现在,如果您能让正在运行的应用程序告诉您 SBOM,以便您确切地知道服务器上运行的是什么,那不是很棒吗?

通过执行器公开 SBOM

为此,我们需要公开 SBOM 执行器端点,该端点默认情况下未公开。不过,这很容易。在您的应用程序配置文件中添加以下内容:

management.endpoints.web.exposure.include=health,sbom

现在重新构建应用程序并从 jar 文件运行它。启动完成后,您可以查询 SBOM 执行器端点:

curl https://:8080/actuator/sbom

HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v3+json

{"ids":["application"]}

这将返回一些 JSON,其中包含所有 SBOM 的 ID。可能存在多个 SBOM:一个描述您的应用程序,一个描述您的 JVM,一个描述您的操作系统,等等。默认情况下,只有一个名为 application 的 SBOM,描述您的 Spring Boot 应用程序。

让我们看看 application SBOM:

curl -i https://:8080/actuator/sbom/application

HTTP/1.1 200
Content-Type: application/vnd.cyclonedx+json
Content-Length: 161738

{
  "bomFormat" : "CycloneDX",
  "specVersion" : "1.5",
  "serialNumber" : "urn:uuid:3842be09-b12e-45ed-8038-babb72a53750",
  "version" : 1,
  ...

这将返回一个大型 JSON 文档,描述您的应用程序的内容。它包含有关应用程序所有依赖项(包括其哈希和许可证、网站和问题跟踪器 URL 等)的信息。它还包含有关您的应用程序的数据,例如版本号、SBOM 生成时间等。有了这些信息,您就能确切地知道服务器上运行的是什么。这涵盖了 SBOM 支持的基本用法。接下来,让我们看看更高级的功能。

不同格式的应用程序 SBOM

如果您不想为应用程序使用 CycloneDX SBOM,而是倾向于使用其他格式,您也可以这样做。但是,您需要自己配置创建 SBOM 的插件。在撰写本文时,Spring Boot 只会自动配置 CycloneDX 插件。

在配置好构建以创建 SBOM 后,您可以使用 management.endpoint.sbom.application.location 属性将此 SBOM 指向 Spring Boot。如果引用的 SBOM 是 CycloneDX、SPDX 或 Syft 格式,Spring Boot 将自动检测其类型,该类型将用于执行器响应的 Content-Type 标头。如果您使用的是其他格式,则可以使用 management.endpoint.sbom.application.media-type 属性明确指定 SBOM 的媒体类型。此示例显示了如何使用 SPDX 格式的 SBOM:

management.endpoint.sbom.application.location=classpath:/sbom/application.spdx.json

要使其正常工作,SPDX SBOM 必须存储在 src/main/resources/sbom/application.spdx.json 中。

包含其他 SBOM

Spring Boot 支持应用程序的多个 SBOM。如果您想包含其他 SBOM,可以使用 management.endpoint.sbom.additional 下的配置属性。例如,添加一个名为 jvm 的 SBOM,操作如下:

management.endpoint.sbom.additional.jvm.location=file:/path/to/sbom.json

这个 jvm SBOM 存储在文件系统中,路径为 /path/to/sbom.json。您需要自己生成此 SBOM,或者由您的 JVM 供应商提供。

与应用程序 SBOM 一样,如果引用的 SBOM 是 CycloneDX、SPDX 或 Syft 格式,Spring Boot 将自动检测其类型。否则,您可以使用以下属性自行设置媒体类型:

management.endpoint.sbom.additional.jvm.media-type=application/json

使用此配置启动应用程序后,您可以再次运行以下 curl 命令:

curl -i https://:8080/actuator/sbom

HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v3+json

{"ids":["application","jvm"]}

现在,端点返回两个 SBOM:applicationjvm。您可以使用以下 curl 命令访问 jvm SBOM:

curl -i https://:8080/actuator/sbom/jvm

HTTP/1.1 200
Content-Type: application/spdx+json
Content-Length: 48739

<content of the jvm SBOM>

您可以包含任意数量的 SBOM,它们都将通过执行器端点公开。

可选 SBOM

请注意,配置中引用的 SBOM 文件或资源必须存在,否则启动会失败。您可以在 SBOM 位置前加上 optional: 前缀,以防止启动失败——如果文件不存在,Spring Boot 将会忽略它。

总结

我们希望您喜欢这个功能,并且它能帮助您保护您的软件供应链。

请告诉我们您对这个新功能的看法,并且一如既往,如果您发现任何问题,请随时 访问我们的问题跟踪器

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有