原生镜像中的安全注意事项

native-image 构建器在应用程序启动后生成应用程序快照,并将其捆绑到二进制可执行文件中。原生镜像的 构建输出 的安全报告部分提供了有关原生镜像构建的安全相关信息。

类初始化 #

native-image 构建器可能会在构建时执行某些类的静态初始化器(有关更多详细信息,请参阅 类初始化)。在构建时执行静态初始化器会在镜像堆中持久化初始化后的状态。这意味着在静态初始化器中获取或计算的任何信息都将成为原生可执行文件的一部分。这会导致敏感数据最终出现在快照中,或者修复应该在启动时获取的初始化数据(例如,随机数种子)。

开发人员可以通过在构建原生可执行文件时指定 --initialize-at-run-time CLI 参数(后跟必须在运行时初始化而不是在镜像构建期间初始化的包和类的逗号分隔列表(及其所有子类的隐式列表))来请求在运行时执行处理敏感信息的静态初始化器。或者,开发人员可以使用 RuntimeClassInitialization API

开发人员应该在专用环境(例如容器)中运行 native-image 构建器,该环境从一开始就不包含任何敏感信息。

软件物料清单 #

GraalVM 原生镜像可以在构建时组装软件物料清单 (SBOM) 以检测可能容易受到已知安全漏洞影响的任何库。原生镜像提供 --enable-sbom 选项,用于将 SBOM 嵌入到原生可执行文件中(仅在 Oracle GraalVM 中可用)。除了嵌入外,SBOM 可以通过使用 --enable-sbom=classpath,export 添加到类路径或导出为 JSON。

支持 CycloneDX 格式,它也是默认格式。要将 CycloneDX SBOM 嵌入到原生可执行文件中,请将 --enable-sbom 选项传递给 native-image 命令。

该实现通过恢复包含在原生可执行文件中的类中所有外部库清单中可观察到的版本信息来构建 SBOM。SBOM 也被压缩,以限制其对原生可执行文件大小的影响。
SBOM 以 gzip 格式存储,其中导出的 sbom 符号引用其起始地址,sbom_length 符号引用其大小。

将压缩后的 SBOM 嵌入到可执行文件后,原生镜像检查工具 能够使用可选的 --sbom 参数从可执行文件和共享库中提取压缩后的 SBOM,该参数可通过 $JAVA_HOME/bin/native-image-inspect --sbom <path_to_binary> 访问。它以以下格式输出 SBOM

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.4",
  "version": 1,
  "components": [
    {
      "type": "library",
      "group": "io.netty",
      "name": "netty-codec-http2",
      "version": "4.1.76.Final",
      "properties": [
        {
          "name": "syft:cpe23",
          "value": "cpe:2.3:a:codec:codec:4.1.76.Final:*:*:*:*:*:*:*"
        },
        {
          "name": "syft:cpe23",
          "value": "cpe:2.3:a:codec:netty-codec-http2:4.1.76.Final:*:*:*:*:*:*:*"
        },
        {
          "name": "syft:cpe23",
          "value": "cpe:2.3:a:codec:netty_codec_http2:4.1.76.Final:*:*:*:*:*:*:*"
        },
        ...
      ]
    },
    ...
  ],
  "serialNumber": "urn:uuid:51ec305f-616e-4139-a033-a094bb94a17c"
}

要扫描任何易受攻击的库,请将 SBOM 提交到漏洞扫描器。例如,流行的 Anchore 软件供应链管理平台 免费提供 grype 扫描器。您可以检查 SBOM 中给出的库是否在 Anchore 数据库中记录了已知漏洞。为此,该工具的输出可以直接馈送到 grype 扫描器以检查易受攻击的库,使用命令 $JAVA_HOME/bin/native-image-inspect --sbom <path_to_binary> | grype,这将产生以下输出

NAME                 INSTALLED      VULNERABILITY   SEVERITY
netty-codec-http2    4.1.76.Final   CVE-2022-24823  Medium

然后,您可以使用此报告来更新可执行文件中发现的任何易受攻击的依赖项。

请注意,如果 native-image-inspect 在没有 --sbom 选项的情况下使用,它将执行指定原生二进制文件的部分内容以提取方法级信息。此功能不应用于来自未知或不可信来源的原生镜像可执行文件。

原生镜像中的 Java 序列化 #

原生镜像支持序列化,以帮助用户反序列化包含在原生可执行文件中的类的构造函数。除非被原生镜像分析自动获取,这些类必须预先指定,因为不包含在原生可执行文件中的类无法被反序列化。原生镜像无法单独阻止对反序列化漏洞的利用。Java SE 的序列化和反序列化安全编码指南 应得到遵循。

原生镜像的 构建输出 的安全报告部分提供了有关反序列化代码是否是原生镜像攻击面的一部分的信息。

其他 #

不允许设置安全管理器。有关更多信息,请参阅 兼容性文档

原生镜像提供了多种方法来指定用于定义默认 TrustStore 的证书文件。虽然 native-image 的默认行为是捕获并使用构建时主机环境中的默认 TrustStore,但这可以通过设置“javax.net.ssl.trustStore*”系统属性在运行时更改。有关更多详细信息,请参阅 文档

包含原生可执行文件的目录是使用 System.loadLibrary() 在运行时加载原生库时搜索路径的一部分。

原生镜像将不允许启用 Java 安全管理器,因为此功能自 Java 17 以来已过时。尝试设置安全管理器将触发运行时错误。

联系我们