3、SBOM(软件物料清单)基础:SBOM的定义与格式(SPDX、CycloneDX)、SBOM的生成工具(syft、cyclonedx-maven-plugin)

聊到供应链安全,SBOM 是个绕不开的话题。

说白了,SBOM 就是一份「软件成分清单」。你想想看,你写一个应用,用了多少开源库?这些库又依赖了哪些底层组件?很多时候,我们自己都说不清楚。SBOM 就是帮你把这些东西清清楚楚列出来的一份文档。

我刚开始接触这个领域时,也觉得 SBOM 不就是个依赖列表吗?后来在一次安全事件复盘时才发现,没有 SBOM,你根本不知道漏洞到底影响到了哪个版本、哪个模块。嗯,从那以后,我再也不敢轻视它了。

3.1 SBOM 的定义

SBOM,全称 Software Bill of Materials。它记录了软件中所有组件的详细信息,包括组件名称、版本号、许可证、依赖关系等。

你可以把它想象成食品包装上的配料表。有了它,你才能知道吃进去的是什么。同样,有了 SBOM,你才能知道你的软件里「吃」进了哪些第三方组件。

核心价值:当一个新的漏洞(比如 Log4j)爆发时,你只需要拿着 SBOM 去匹配,就能秒级定位受影响的应用。而不是让团队花几天时间去翻代码、查依赖。

3.2 SBOM 的格式标准

目前业界主流的 SBOM 格式有两种:SPDX 和 CycloneDX。我个人习惯两个都生成,因为不同的工具链可能只支持其中一种。

3.2.1 SPDX

SPDX(Software Package Data Exchange)由 Linux 基金会维护。它是最早的 SBOM 标准,在合规和许可证管理方面非常成熟。

  • 优点:许可证信息详尽,适合法律合规场景
  • 格式:支持 JSON、YAML、RDF/XML、Tag:Value
  • 典型场景:开源合规审计、法律部门审查

3.2.2 CycloneDX

CycloneDX 由 OWASP 社区推动。它更轻量,而且对安全场景的支持更好。我在项目中遇到过几次,CycloneDX 能直接标注出组件的漏洞编号(CVE),这一点非常实用。

  • 优点:安全属性丰富,支持漏洞关联
  • 格式:支持 JSON、XML
  • 典型场景:漏洞管理、安全扫描流水线
特性 SPDX CycloneDX
维护方 Linux 基金会 OWASP
许可证信息 非常详细 基础支持
漏洞关联 需扩展 原生支持
文件大小 较大 轻量
推荐场景 合规审计 安全扫描

我的建议:如果你的团队偏合规和法律方向,优先用 SPDX。如果你们是做 DevSecOps 流水线、漏洞扫描,CycloneDX 会更顺手。当然,两个都生成也不费事。

3.3 SBOM 的生成工具

工具这块,我重点讲两个:syft 和 cyclonedx-maven-plugin。一个通用,一个专精。

3.3.1 syft

syft 是 Anchore 公司开源的工具。它能从容器镜像、文件系统、源码目录中生成 SBOM。支持 SPDX 和 CycloneDX 两种格式。

我曾经在一个客户现场,他们的容器镜像有 3GB 大,里面装了各种乱七八糟的东西。用 syft 一扫描,几分钟就生成了完整的 SBOM,直接定位到了几个过期的 OpenSSL 版本。

安装方式:

# macOS
brew install syft

# Linux (脚本安装)
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin

使用示例:

# 从容器镜像生成 CycloneDX 格式的 SBOM
syft nginx:latest -o cyclonedx-json > sbom.cyclonedx.json

# 从本地文件系统生成 SPDX 格式的 SBOM
syft dir:./my-project -o spdx-json > sbom.spdx.json

关键参数说明:

  • -o cyclonedx-json:输出 CycloneDX JSON 格式
  • -o spdx-json:输出 SPDX JSON 格式
  • dir:./path:扫描本地目录
  • nginx:latest:扫描 Docker 镜像

3.3.2 cyclonedx-maven-plugin

这个插件是专门为 Maven 项目设计的。如果你用的是 Java 技术栈,这个插件几乎是标配。

我记得有一次,团队在排查一个 Log4j 漏洞时,就是靠这个插件快速生成了所有微服务的 SBOM,然后批量匹配漏洞库,半小时就搞定了排查工作。

在 pom.xml 中配置:

<plugin>
    <groupId>org.cyclonedx</groupId>
    <artifactId>cyclonedx-maven-plugin</artifactId>
    <version>2.7.9</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>makeAggregateBom</goal>
            </goals>
        </execution>
    </executions>
</plugin>

生成命令:

mvn package

执行后,会在 target/ 目录下生成 bom.json 和 bom.xml 两个文件,默认是 CycloneDX 格式。

注意:如果你用的是多模块 Maven 项目,记得用 makeAggregateBom 目标,它会聚合所有子模块的依赖。否则你只能拿到单个模块的 SBOM,排查问题时容易漏掉。

3.4 实战建议

说了这么多,我总结几条实战经验:

  • 生成时机:每次构建时自动生成 SBOM,不要手动做。我习惯在 CI/CD 流水线的 package 阶段触发。
  • 存储策略:SBOM 文件要跟制品一起归档。比如 Docker 镜像的 SBOM 就存到镜像仓库的 metadata 里。
  • 格式选择:如果团队刚起步,先用 CycloneDX。它更简单,安全属性也够用。等合规要求来了再补 SPDX。
  • 版本管理:SBOM 也要版本化。我见过有人把 SBOM 直接提交到 Git 仓库,跟源码一起管理,效果不错。

一个小技巧:生成 SBOM 后,可以用 grype(也是 Anchore 的工具)直接对 SBOM 做漏洞扫描。命令很简单:grype sbom:./sbom.cyclonedx.json。一步到位,省时省力。

好了,SBOM 的基础内容就这些。下一章我们会聊怎么把 SBOM 集成到 CI/CD 流水线里,实现自动化漏洞排查。到时候我会分享一些我在实际项目中踩过的坑,保证有用。