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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-64640 — Reproducer for CVE-2026-64640 — Apache Polaris Iceberg REST register/register-view vends storage credentials and reads an attacker-chosen metadata location before validating allowedLocations (confused-deputy cross-tenant read). Affected ≤ 1.6.0, fixed in 1.7.0. | Kitploit
ツール/GitHubGitHub/oscerd/cve-2026-64640
ReconnaissanceVulnerability AnalysisExploitationWeb Application ExploitationData ExfiltrationPenetration TestingCloud SecurityAPI Security
GitHuboscerd/cve-2026-64640

CVE-2026-64640

Reproducer for CVE-2026-64640 — Apache Polaris Iceberg REST register/register-view vends storage credentials and reads an attacker-chosen metadata location before validating allowedLocations (confused-deputy cross-tenant read). Affected ≤ 1.6.0, fixed in 1.7.0.

14日前未レビュー

人気

すべて見る →

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

すべてのツールを探索

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

すべてのツールを見る →
共有
リポジトリを見る

CVE-2026-64640 — Apache Polaris: register におけるロケーション検証前の資格情報発行

CVE-2026-64640 の自己完結型・ワンコマンド再現スクリプトです。Apache Polaris の Iceberg REST register エンドポイントは、呼び出し元が指定したパスに対してクラウドストレージ資格情報を発行し、そのパスをカタログの allowedLocations と照合する前にサーバー側で読み取ります。

自カタログでテーブルを作成する権限しか持たないプリンシパルでも、Polaris にカタログのストレージ資格情報を使って、カタログが決してアクセスを許されていないオブジェクト(別テナントのプレフィックス、別バケット、ストレージプリンシパルが到達可能な任意のオブジェクト)を読み取らせることができます。

CVECVE-2026-64640
コンポーネントpolaris-runtime-service — IcebergCatalog / LocalIcebergCatalog: registerTable, registerView
エンドポイントPOST /api/catalog/v1/{prefix}/namespaces/{namespace}/register
POST /api/catalog/v1/{prefix}/namespaces/{namespace}/register-view (1.6.0+)
CWECWE-441 (混乱した代理人), CWE-639 (ユーザー制御キーによる認可バイパス), CWE-918 (SSRF)
深刻度高 — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N (8.1)
影響を受けるバージョン≤ 1.6.0 (1.3.0-incubating、1.4.0、1.4.1、1.5.0、1.6.0 で確認)
修正バージョン1.7.0 — 1.6.0 はテーブルパスのみを修正し、新しいビューパスで欠陥を再発させています
必要な権限任意のカタログに対して TABLE_CREATE / CATALOG_MANAGE_CONTENT を持つ認証済みプリンシパル 1 つ — 管理者は不要

1.6.0 は修正ではありません。 これは register を(偶然にも機能 PR 内で)閉じただけで、同じ順序ミスを抱えた真新しい register-view エンドポイントを出荷しています。この再現スクリプトはその両方を証明します。1.7.0 にアップグレードしてください。

実行方法

要件: Docker(Compose v2 プラグイン)、curl、python3、bash。それ以外は不要です。環境は公開済みイメージから構築され、後に破棄されます。

root@kitploit:~
./exploit.sh                 # default: apache/polaris:1.4.1  -> reproduces via register
./exploit.sh --tag 1.6.0     # partially fixed               -> reproduces via register-view
./exploit.sh --tag 1.7.0     # comprehensively fixed         -> refuses cleanly on both
./scripts/version-matrix.sh  # every release, side by side

終了コード 0 は脆弱性が再現されたこと、1 は再現されなかったこと、2 は環境の起動に失敗したことを意味します。すべてのリクエストとレスポンスは evidence/<timestamp>-polaris-<tag>/ に書き込まれます。

環境の構成

root@kitploit:~
  catalog  tenant_a_catalog        allowedLocations = [ s3://bucket123 ]
  actor    low_priv_user           CATALOG_MANAGE_CONTENT on that catalog, nothing else
  target   s3://tenant-b-private   another tenant's bucket:
                                     no allowedLocations entry, no grant, no relation
                                     to the attacker's catalog — but reachable by the
                                     credentials that back it

最後の行が現実的な部分です。運用者はカタログを allowedLocations でスコープしますが、その下にある IAM ロールはほとんどの場合 1 つのプレフィックスより広い範囲を持ちます。allowedLocations が壁です。このバグはその壁を迂回します。

実証されること

テスト 0 — 壁は本物です。 s3://tenant-b-private 内の明示的なロケーションでテーブルを作成しようとすると、何も読み取られる前に 403 ForbiddenException で拒否されます。Polaris はそのロケーションが範囲外であることを完全に認識しています。

テスト 1 — register はそれでも読み取ります。 同じプリンシパルが register を s3://tenant-b-private/sales/metadata/00007-tenant-b-sales.metadata.json に向けます。レスポンスも 403 です。しかし、そのレスポンスには s3://tenant-b-private/warehouse/CANARY-64640-4f1c9e2a-tenant-b-sales が引用されています。これはそのオブジェクトの本文内にのみ存在する文字列です。

root@kitploit:~
{"error":{"message":"Invalid locations '[s3://tenant-b-private/warehouse/sales/data,
s3://tenant-b-private/warehouse/CANARY-64640-4f1c9e2a-tenant-b-sales]' for identifier
'tenant_a_ns.pwn_canary': s3://tenant-b-private/warehouse/sales/data is not in the list
of allowed locations: [s3://bucket123/tenant_a_ns]","type":"ForbiddenException","code":403}}

リクエストは warehouse/ に一切言及していません。Polaris がこれらの文字列を生成できるのは、カタログの資格情報でオブジェクトを取得・解析した場合だけです。この 403 は、Polaris が防ぐはずだった読み取りの 1 ステップ後に違反を検知しているものです。

テスト 2 — 返ってくるもの。 被害者ドキュメントから解析された 2 つの異なるフィールドが呼び出し元に返されます。テーブルが宣言する location と、その write.data.path プロパティです。

テスト 3 — ストレージ列挙オラクル。 同じ呼び出しは、allowedLocations 外のターゲットの状態ごとに異なる応答を返します。

識別可能な 4 つの応答は、呼び出し元が知る権利のないストレージに関する 4 つの事実を意味します。実際の AWS では、バケット存在確認プローブはカタログの資格情報を使って グローバルな S3 バケット名前空間に到達します。

修正済みビルドでは、その表のすべての行がリクエストされたパスのみを挙げる同じ 403 になり、オブジェクト内部からの情報は何も返ってきません。スクリプトはそのシグネチャを検出して NOT VULNERABLE — pre-validation observed と報告します。

テスト 4 — register-view にも同じ欠陥。 Polaris 1.6.0 は POST .../namespaces/{ns}/register-view を追加し、registerView に到達します。これは事前検証なしで FileIO をロードし、呼び出し元のドキュメントを解析します。まさに registerTable が止めたばかりの動作です。1.6.0 ではビューカナリーは次のように返ります。

root@kitploit:~
{"error":{"message":"Invalid locations '[s3://tenant-b-private/warehouse/CANARY-64640-VIEW-8d3b7a15-tenant-b]'
for identifier 'tenant_a_ns.pwn_view': … is not in the list of allowed locations:
[s3://bucket123/tenant_a_ns]","type":"ForbiddenException","code":403}}

つまり、1.6.0 のデプロイは別のエンドポイントを通じて同じプリミティブに依然としてさらされています。1.4.1 以前ではこのエンドポイントは存在せず、スクリプトはその旨を表示します。

根本原因

修正前の IcebergCatalog.registerTable(1.6.0 からは LocalIcebergCatalog)— registerView もまったく同じ形です。

root@kitploit:~
String locationDir = metadataFileLocation.substring(0, lastSlashIndex);   // attacker-controlled
...
FileIO fileIO =
    loadFileIOForTableLike(
        identifier,
        Set.of(locationDir),                                              // credentials minted here
        resolvedParent,
        new HashMap<>(tableDefaultProperties),
        Set.of(PolarisStorageActions.READ, PolarisStorageActions.LIST));

InputFile metadataFile = fileIO.newInputFile(metadataFileLocation);       // server-side GET
TableMetadata metadata = TableMetadataParser.read(metadataFile);          // server-side parse
ops.commit(null, metadata);                                               // allowedLocations checked HERE

発行チェーン(loadFileIOForTableLike → StorageAccessConfigProvider.getStorageAccessConfig → *StorageIntegration.getSubscopedCreds)は独自の allowedLocations チェックを行わないため、唯一の強制はコミット時のものだけです。そしてその時点では、特権読み取りはすでに発生し、その結果はレスポンスに含まれています。

同じファイル内の類似パスは順序を正しく守っています。ビューの作成と sendNotificationForTableLike はどちらも FileIO をロードする前に検証します。registerTable だけが一貫していませんでした。詳細なウォークスルーは docs/ANALYSIS.md にあります。

修正内容(2 つの部分)

テーブルパス — コミット 1dd5feeb(2026-06-02、1.6.0 で初リリース)は、正しい場所に 1 行追加しました。

root@kitploit:~
validateLocationForTableLike(identifier, metadataFileLocation, resolvedParent);

FileIO fileIO = loadFileIOForTableLike(identifier, Set.of(locationDir), ...);

これはセキュリティ修正ではなく機能 PR(「add RegisterTable overwrite support」)内に含まれていたため、1.6.0 はこの修正をアドバイザリなしで出荷しました。

ビューパス — コミット 7e822f23(「Validate locations when registering tables and views」、#5114)、2026-07-20、1.7.0 で初リリース。registerView に同じガードを追加し、両パスの解析後チェックを統合しました。

1.7.0 には 85a0c292(#4860、「Fix native catalog credential vending skipping allowedLocations re-validation」)も含まれています。これは関連する多層防御のギャップを埋めます。資格情報パス自体が各呼び出し元を信頼するのではなく、再検証するようになったのです。これが問題の構造的な半分であり、1.6.0 ではなく 1.7.0 に移行すべきもう 1 つの理由です。

封じ込めはリリースタグに対して確認済みです。1dd5feeb は 1.6.0 と 1.7.0 に含まれ、7e822f23 と 85a0c292 は 1.7.0 のみに含まれます。

古いバージョンラインを使っている人のために、両方の変更はパッチとして提供されています。0001 は ≤ 1.5.0 のテーブルパス用、0002 は 1.6.0 のビューパス用です。

運用者向けガイダンス(アップグレードパス、緩和策、既存ログでの悪用の探し方)は docs/REMEDIATION.md にあります。

検証済みバージョンマトリクス

./scripts/version-matrix.sh で生成。各行は完全なスタックの起動と実際のエクスプロイト試行です。docs/AFFECTED-VERSIONS.md を参照してください。

1.4.1 が重要なのは、CVE-2026-42809(stage-create パスにおける同じ「発行後検証」の誤り)を修正したリリースだからです。その修正はレポート内のエンドポイントに限定され、その後このパターンは 2 回繰り返されました。register は 1.6.0 までその動作を維持し、1.6.0 の新しい register-view は最初からその動作を持って生まれました。

影響範囲と正直な評価

この再現スクリプトが実証することは、次のとおりです。それ以上ではありません。

  • Polaris は、カタログが宣言したストレージ境界の外にある、攻撃者が選択した任意のロケーションに対して、資格情報を発行した上でサーバー側読み取りを実行します。register 経由では ≤ 1.5.0、register-view 経由では 1.6.0 で発生します。
  • そのオブジェクトから解析されたロケーション形状のフィールドが呼び出し元に返されます。
  • オブジェクトの存在、バケットの存在、オブジェクトの種類は、カタログのストレージプリンシパルが到達できるすべての範囲で観察可能です。

実証しないこと: API を通じた範囲外オブジェクトの完全な内容の一括取得。後続の 2 つのチェック(メタデータロケーションがテーブルロケーションの配下にあること、解析されたロケーションが allowedLocations 内にあること)によって登録は完了しません。したがって、呼び出し元が得られるのはオラクルとメタデータの断片であり、ドキュメント全体ではありません。カタログに S3 エンドポイント上書きが設定されている場合、同じプリミティブは設定されたホストに対するサーバー側リクエストフォージェリになります。

安全性

すべてローカルで実行されます。ループバックポート上の 1 つの Docker Compose プロジェクト、使い捨ての S3(RustFS)インスタンス、そしてこのリポジトリ自体が配置する合成の「被害者」ファイル。外部ホストへの接続はなく、資格情報がマシンの外に出ることもありません。--keep を指定しない限り、終了時に docker compose down -v が実行されます。victim-data/ のオブジェクトは捏造されたものであり、ここに実データは一切ありません。

所有している、またはテストを許可されているシステムでのみ使用してください。

クレジットと開示

CVE-2026-42809 修正のレビュー中に発見し、プロジェクトの SECURITY.md に記載されたプロセスを通じて Apache Software Foundation のセキュリティチームに報告し、CVE-2026-64640 として追跡されました。

ライセンス

Apache License 2.0 — LICENSE を参照してください。Compose 環境は Apache Polaris クイックスタートに由来します。NOTICE を参照してください。

ツールをダウンロード
プローブ(すべて allowedLocations 外)1.4.1 の応答
有効な Iceberg メタデータが存在する403 ForbiddenException + 解析されたロケーションがエコーされる
キーが存在しない400 NotFoundException — Location does not exist: …
バケットが存在しない400 NoSuchBucketException — 生の S3 SDK エラー
存在するが Iceberg メタデータではない503 RuntimeIOException — Failed to read file: …
リリースregister(テーブル)register-view判定
1.3.0-incubating脆弱エンドポイントなし脆弱
1.4.0脆弱エンドポイントなし脆弱
1.4.1脆弱エンドポイントなし脆弱
1.5.0脆弱エンドポイントなし脆弱
1.6.0発行前に検証済み脆弱脆弱
1.7.0発行前に検証済み発行前に検証済み修正済み