目录
尽管现代 SBOM 都标榜让依赖关系和工具链"可见",但其中许多仍然是盲目的:它们只列出你在 pom.xml 中指定的库,却忽略了实际进入生产环境的茂密依赖树。这些盲区正是恶意软件、过期库和许可问题的藏身之所。在本博文中,我们将讨论为什么捕获直接依赖和可传递依赖都很重要,为什么 Maven 项目尤其棘手,以及如何用一条命令通过 SafeDep Vet 构建完整的 CycloneDX SBOM(附带可视化图!)。在此过程中,我们将比较主流生成器,梳理 EU CRA 等法律的监管压力,并为开发者和 CISO 提出关闭缺口的行动计划。
如果你想了解更多关于 EU CRA 的信息,请参阅我们的博文《SBOM 与欧盟网络弹性法案 (CRA) ——软件供应商需要了解什么》。
背景
自最早的文档起,Maven 就承诺"自动更新"和"依赖闭包"(也称为可传递依赖),这意味着 pom.xml 中的一个条目会静默扩展为该依赖及其所有子依赖所需的所有库。官方文档解释说,"依赖可以收集的层级数量没有上限",解析在构建时递归执行,生成的"项目依赖"页面经常显示数十个从未出现在根 POM 中的 jar。然而,与 pnpm、cargo、pdm 等构建系统和包管理器不同,Maven 和整个 Java 生态缺乏可靠的 lockfile 基础。
虽然这种抽象加速了开发,但也隐藏了风险:除非维护者明确排除了它们(例如,可选依赖),否则不想要的或过时的库可能会搭便车进入。对一百万个 Java 包的行业分析发现,几乎三分之一的可利用漏洞只存在于可传递层中,对那些只停留在一级导入的工具是不可见的。Log4Shell 危机说明了这种危险——组织被从未自己声明过的 log4j-core 的间接副本所攻击,攻击者多年来一直在探测这一向量。
问题:停在第一分支的 SBOM
Maven 隐藏了完整的依赖树
Maven 自动解析可传递依赖,"依赖可以收集的层级数量没有上限"。流行的dependency:tree 目标以文本、DOT 或 JSON 格式显示这种扩展,通常揭示的制品数量是根 POM 中的 10–50 倍。对 300 万个 Maven 包的研究证实,近三分之一的项目只有在考虑这些更深的层级时才会变得脆弱。
风险在可传递层中叠加
Log4Shell 漏洞进入了许多从未直接声明 Log4j 的 Java 应用程序;它通过间接依赖到达。对真实事件的研究表明,更新一个直接库通常无法修补埋藏在图更深处的缺陷,而停留在第一层的工具无法暴露这些盲点。
许多 SBOM 生成器仍然简写
针对 Syft 提交的问题报告称,1.30 之前的版本只列出 Java 的一级包,缺少审计员所需的依赖关系。然而,NTIA 的最低要素文档将"X 包含在 Y 中"作为每个 SBOM 必须捕获的唯一强制关系。
监管势头要求完整性
欧盟网络弹性法案将要求向欧洲发货的供应商在 2027 年 12 月前提供覆盖完整依赖链的机器可读 SBOM,违规罚款高达 1500 万欧元。在美国,第 14028 号行政命令推动联邦机构只购买附带符合 NIST 指南的 SBOM 的软件。因此,不完整的清单将无法通过采购审查。
对开发者和 CISO 的运营影响
扁平的 SBOM 隐藏了哪个直接升级可以切除有漏洞的可传递包,延长事件响应时间。换句话说,扁平的 SBOM 在捕获可传递依赖方面无效。OpenSSF 指出,它还模糊了许可继承,使组织面临意外的 LGPL 或 GPL 义务。
解决方案 — 捕获完整的图
不过,有些方法可以绕过这种情况,而无需切换到 Gradle。
从 Maven 提取权威图
由于 Maven 已经计算了完整解析,利用它。mvn dependency:tree -DoutputType=dot 命令生成下游工具可以摄取的规范图。为了自动化,CycloneDX Maven 插件发出一份 CycloneDX v1.6 SBOM,在单一步骤中聚合所有直接和可传递依赖。
优先使用图感知的 SCA 工具
SafeDep Vet解析 Maven 树,并在一次 CLI 调用中写出 CycloneDX SBOM 加可选的 DOT 图,消除手动粘合代码。相比之下,Syft 需要 Java 的环境标志,在某些模式下仍然缺少完整的图输出,正如其自身的问题跟踪器所指出的。
在 CI/CD 中嵌入验证
添加一个管道步骤:
- 在构建时生成
bom.json(CycloneDX)和deps.dot(图)。 - 验证 SBOM。
- 如果在图的任何位置检测到任何关键 CVE,则使构建失败。
这满足了 CRA 对整个供应链持续漏洞监控的即将到来的要求。
就这样!因为 SBOM 现在包含边数据,修复工具可以精确定位消除有漏洞间接库的最接近的直接依赖升级,缩短平均修复时间并降低破坏上游 API 的风险。
工具景观概览
景观分析涵盖输出带有完整可传递覆盖的 CycloneDX 文件的 Maven 原生插件、仍在完善 Java 依赖图支持的开源扫描器如 Syft、专注许可数据的 SPDX 工具,以及将图完整的 SBOM 与恶意软件和政策检查相结合的 SafeDep 的 Vet。下表比较了它们的默认能力、导出格式和已知怪癖:
| 用例 | 仅直接依赖 | 可传递依赖 | 图导出 | 值得注意的怪癖 |
|---|---|---|---|---|
| Syft | ✅ | ⚠️(Java 需要 SYFT_JAVA_RESOLVE_TRANSITIVE_DEPENDENCIES) | ❌(扁平列表) | 默认包含 test 作用域 |
| CycloneDX Maven Plugin | ✅ | ✅ | 通过 dependencyGraph | 在构建中运行,无多生态系统 |
| SPDX-tools | ✅ | ❌ | N/A | 专注许可数据 |
| SafeDep Vet | ✅ | ✅ | --report-graph | 带策略引擎的多语言支持 |
| OSV Scanner | ❌ | ✅ | ❌ | 默认可传递 Maven 扫描;—no-resolve 禁用可传递;无原生图导出 |
- dynamic-analysis
- oss
- malware
- security
SafeDep 博客最新动态
关注以获取开源安全与工程的最新更新和洞察