ネイティブイメージにおけるセキュリティに関する考慮事項

native-image ビルダーは、起動後のアプリケーションのスナップショットを生成し、それをバイナリ実行可能ファイルにバンドルします。ネイティブイメージの ビルド出力 のセキュリティレポートセクションには、ネイティブイメージビルドに関するセキュリティ関連の情報が記載されています。

クラス初期化 #

native-image ビルダーは、ビルド時に特定のクラスの静的初期化子を実行する場合があります(詳細については、クラス初期化を参照してください)。ビルド時に静的初期化子を実行すると、初期化後の状態がイメージヒープに保持されます。これは、静的初期化子で取得または計算された情報がネイティブ実行可能ファイルの一部になることを意味します。これにより、機密データがスナップショットに含まれたり、乱数シードなど、起動時に取得されるはずの初期化データが固定されたりする可能性があります。

開発者は、ネイティブ実行可能ファイルをビルドする際に、--initialize-at-run-time CLI パラメーターを指定し、その後に、実行時ではなくイメージビルド時に初期化する必要があるパッケージとクラス(および暗黙的にそのすべてのサブクラス)のコンマ区切りリストを指定することで、機密情報を処理する静的初期化子を実行時に実行するように要求できます。あるいは、開発者は RuntimeClassInitialization API を利用できます。

開発者は、最初に機密情報が含まれていないコンテナなどの専用環境で native-image ビルダーを実行する必要があります。

ソフトウェア部品表 #

GraalVM Native Image は、既知のセキュリティ脆弱性の影響を受ける可能性のあるライブラリを検出するために、ビルド時にソフトウェア部品表 (SBOM) を組み立てることができます。Native Image には、SBOM をネイティブ実行可能ファイルに埋め込むための --enable-sbom オプションがあります(Oracle GraalVM でのみ使用可能)。埋め込むだけでなく、--enable-sbom=classpath,export を使用して、SBOM をクラスパスに追加したり、JSON としてエクスポートしたりできます。

CycloneDX 形式がサポートされており、デフォルトです。CycloneDX SBOM をネイティブ実行可能ファイルに埋め込むには、native-image コマンドに --enable-sbom オプションを渡します。

この実装では、ネイティブ実行可能ファイルに含まれるクラスの外部ライブラリマニフェストで観測可能なすべてのバージョン情報を復元することにより、SBOM を構築します。また、SBOM のネイティブ実行可能ファイルサイズへの影響を制限するために、SBOM は圧縮されます。
SBOM は gzip 形式で保存され、エクスポートされた sbom シンボルがその開始アドレスを参照し、sbom_length シンボルがそのサイズを参照します。

圧縮された SBOM を実行可能ファイルに埋め込んだ後、ネイティブイメージインスペクトツール は、$JAVA_HOME/bin/native-image-inspect --sbom <path_to_binary> を介してアクセスできるオプションの --sbom パラメーターを使用して、実行可能ファイルと共有ライブラリの両方から圧縮された SBOM を抽出できます。次の形式で 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 シリアライゼーション #

Native Image は、ネイティブ実行可能ファイルに含まれるクラスのコンストラクターをユーザーが逆シリアル化するのに役立つようにシリアライゼーションをサポートしています。ネイティブイメージ分析によって自動的に取得されない限り、これらのクラスは事前指定する必要があり、ネイティブ実行可能ファイルに含まれていないクラスは逆シリアル化できません。Native Image は、シリアル化の脆弱性の悪用を単独で防ぐことはできません。Java SE のシリアル化と逆シリアル化に関するセキュアコーディングガイドラインに従う必要があります。

ネイティブイメージの ビルド出力 のセキュリティレポートセクションには、逆シリアル化コードがネイティブイメージの攻撃対象の一部であるかどうかに関する情報が記載されています。

その他 #

セキュリティマネージャーの設定は許可されていません。詳細については、互換性ドキュメントを参照してください。

Native Image には、デフォルトのトラストストアを定義するために使用される証明書ファイルを指定するための複数の方法が用意されています。native-image のデフォルトの動作は、ビルド時のホスト環境からデフォルトのトラストストアをキャプチャして使用することですが、「javax.net.ssl.trustStore*」システムプロパティを設定することで、実行時に変更できます。詳細については、ドキュメントを参照してください。

ネイティブ実行可能ファイルを含むディレクトリは、実行時に System.loadLibrary() を使用してネイティブライブラリをロードするときに検索パスの一部になります。

Java 17 以降この機能が非推奨になったため、Native Image では Java セキュリティマネージャーを有効にすることはできません。セキュリティマネージャーを設定しようとすると、ランタイムエラーが発生します。

つながろう