Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

FeedsKontaktDatenschutz© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-64640 — Reproducer für CVE-2026-64640 — Apache Polaris Iceberg REST register/register-view gibt Speicheranmeldeinformationen aus und liest einen vom Angreifer gewählten Metadaten-Speicherort, bevor allowedLocations validiert wird (Confused-Deputy-Cross-Tenant-Read). Betroffen ≤ 1.6.0, behoben in 1.7.0. | Kitploit
Tools/GitHubGitHub/oscerd/cve-2026-64640
AufklärungSchwachstellenanalyseExploitationWebanwendungs-ExploitationDatenexfiltrationPenetrationstestsCloud-SicherheitAPI-Sicherheit
GitHuboscerd/cve-2026-64640

CVE-2026-64640

Repository anzeigen
15vor 1 MonatNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →

Über

Reproducer für CVE-2026-64640 — Apache Polaris Iceberg REST register/register-view gibt Speicheranmeldeinformationen aus und liest einen vom Angreifer gewählten Metadaten-Speicherort, bevor allowedLocations validiert wird (Confused-Deputy-Cross-Tenant-Read). Betroffen ≤ 1.6.0, behoben in 1.7.0.

Teilen

CVE-2026-64640 — Apache Polaris: Credential-Vergabe vor der Standortvalidierung in register

Ein eigenständiger Reproduktor für CVE-2026-64640, der mit einem einzigen Befehl läuft: Die register-Endpunkte der Iceberg-REST-API in Apache Polaris vergeben Cloud-Speicher-Credentials für einen vom Aufrufer gelieferten Pfad und lesen diesen Pfad serverseitig, bevor sie ihn gegen die allowedLocations des Katalogs prüfen.

Ein Principal, dessen einziges Privileg das Erstellen von Tabellen in seinem eigenen Katalog ist, kann Polaris dazu bringen, die Speicher-Credentials des Katalogs zu verwenden, um Objekte zu lesen, die der Katalog nie berühren durfte — das Präfix eines anderen Mandanten, ein anderer Bucket, alles, was der Speicher-Principal erreichen kann.

CVECVE-2026-64640
Komponentepolaris-runtime-service — IcebergCatalog / LocalIcebergCatalog: registerTable, registerView
EndpunktePOST /api/catalog/v1/{prefix}/namespaces/{namespace}/register
POST /api/catalog/v1/{prefix}/namespaces/{namespace}/register-view (1.6.0+)
CWECWE-441 (Confused Deputy), CWE-639 (Autorisierungsumgehung über benutzerkontrollierten Schlüssel), CWE-918 (SSRF)
SchweregradHoch — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N (8.1)
Betroffen≤ 1.6.0 (verifiziert auf 1.3.0-incubating, 1.4.0, 1.4.1, 1.5.0, 1.6.0)
Behoben in1.7.0 — 1.6.0 behebt nur den Tabellenpfad und führt den Fehler im neuen View-Pfad wieder ein
Erforderliches Privilegein authentifizierter Principal mit TABLE_CREATE / CATALOG_MANAGE_CONTENT auf einem beliebigen Katalog — kein Admin erforderlich

1.6.0 ist kein Fix. Es schließt register (beiläufig, innerhalb eines Feature-PRs) und liefert den brandneuen register-view-Endpunkt mit demselben Reihenfolgefehler aus. Der Reproduktor beweist beide Hälften. Upgrade auf 1.7.0.

Ausführen

Voraussetzungen: Docker mit dem Compose-v2-Plugin, curl, python3, bash. Sonst nichts — die Umgebung wird aus veröffentlichten Images erstellt und danach wieder abgebaut.

./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

Exit-Code 0 bedeutet, dass die Schwachstelle reproduziert wurde, 1, dass sie nicht reproduziert wurde, 2, dass die Umgebung nicht hochkommen konnte. Jede Anfrage und Antwort wird nach evidence/<timestamp>-polaris-<tag>/ geschrieben.

Wie die Umgebung aussieht

  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

Diese letzte Zeile ist der realistische Teil. Betreiber grenzen einen Katalog mit allowedLocations ein; die darunterliegende IAM-Rolle ist fast immer breiter als ein einzelnes Präfix. allowedLocations ist die Mauer. Dieser Bug geht darum herum.

Was es beweist

Test 0 — die Mauer ist real. Das Erstellen einer Tabelle mit einem expliziten Standort in s3://tenant-b-private wird mit 403 ForbiddenException abgelehnt, bevor irgendetwas gelesen wird. Polaris weiß genau, dass der Standort außerhalb der Grenzen liegt.

Test 1 — register liest es trotzdem. Derselbe Principal richtet register auf s3://tenant-b-private/sales/metadata/00007-tenant-b-sales.metadata.json. Die Antwort ist ebenfalls ein 403 — aber sie zitiert s3://tenant-b-private/warehouse/CANARY-64640-4f1c9e2a-tenant-b-sales, eine Zeichenkette, die nur im Inhalt dieses Objekts existiert:

{"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}}

Die Anfrage erwähnt warehouse/ nie. Polaris konnte diese Zeichenketten nur erzeugen, indem es das Objekt mit den Credentials des Katalogs abrief und parste. Das 403 ist Polaris, das den Verstoß einen Schritt nach dem Lesevorgang abfängt, den es hätte verhindern sollen.

Test 2 — was zurückkommt. Zwei verschiedene Felder, die aus dem Opferdokument geparst werden, werden an den Aufrufer zurückgespiegelt: die deklarierte location der Tabelle und ihre Eigenschaft write.data.path.

Test 3 — ein Speicher-Enumeration-Orakel. Derselbe Aufruf antwortet für jeden Zustand eines Ziels außerhalb von allowedLocations unterschiedlich:

Sonde (alle außerhalb von allowedLocations)1.4.1-Antwort
gültige Iceberg-Metadaten, vorhanden403 ForbiddenException + geparste Standorte zurückgespiegelt
Schlüssel fehlt400 NotFoundException — Location does not exist: …
Bucket existiert nicht400 NoSuchBucketException — roher S3-SDK-Fehler
vorhanden, aber keine Iceberg-Metadaten503 RuntimeIOException — Failed to read file: …

Vier unterscheidbare Antworten bedeuten vier Fakten über den Speicher, die der Aufrufer nicht erfahren darf. Auf echtem AWS erreicht die Bucket-Existenz-Sonde mit den Credentials des Katalogs den globalen S3-Bucket-Namespace.

Bei einem behobenen Build ist jede Zeile dieser Tabelle dasselbe 403, das nur den angeforderten Pfad nennt, und nichts aus dem Inneren des Objekts kommt zurück — das Skript erkennt diese Signatur und meldet NOT VULNERABLE — pre-validation observed.

Test 4 — derselbe Fehler bei register-view. Polaris 1.6.0 fügte POST .../namespaces/{ns}/register-view hinzu, das registerView erreicht, welches die FileIO lädt und das Dokument des Aufrufers ohne vorherige Validierung parst — genau das, was registerTable gerade aufgehört hatte zu tun. Auf 1.6.0 kommt der View-Canary zurück:

{"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}}

Eine 1.6.0-Bereitstellung ist also über einen anderen Endpunkt weiterhin derselben Primitive ausgesetzt. Auf 1.4.1 und älter existiert der Endpunkt nicht, und das Skript sagt genau das.

Grundursache

IcebergCatalog.registerTable (LocalIcebergCatalog ab 1.6.0), vor dem Fix — registerView hat dieselbe Form:

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
Tool herunterladen