Skip to content
KitploitKITPLOIT
ToolsBlog
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.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
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
Tools/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.

vor 14 TagenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Repository anzeigen

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.

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

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

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

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:

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

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:

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:

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

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:

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

Die Vending-Kette (loadFileIOForTableLike → StorageAccessConfigProvider.getStorageAccessConfig → *StorageIntegration.getSubscopedCreds) führt selbst keine allowedLocations-Prüfung durch, sodass die einzige Durchsetzung die zur Commit-Zeit ist — und bis dahin hat der privilegierte Lesevorgang bereits stattgefunden und sein Ergebnis steckt in der Antwort.

Andere Codepfade in derselben Datei machen es richtig: Die View-Erstellung und sendNotificationForTableLike validieren beide, bevor sie die FileIO laden. registerTable war der inkonsistente Pfad. Vollständige Analyse in docs/ANALYSIS.md.

Der Fix, in zwei Teilen

Tabellenpfad — Commit 1dd5feeb (2026-06-02, erstmals in 1.6.0 veröffentlicht) fügte eine Zeile an der richtigen Stelle hinzu:

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

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

Er kam innerhalb eines Feature-PRs („add RegisterTable overwrite support"), nicht als Security-Fix, daher wurde die Korrektur in 1.6.0 ohne ein Advisory ausgeliefert, das sie benennt.

View-Pfad — Commit 7e822f23 („Validate locations when registering tables and views", #5114), 2026-07-20, erstmals in 1.7.0 veröffentlicht, fügte dieselbe Absicherung zu registerView hinzu und konsolidierte die Post-Parse-Prüfungen für beide Pfade.

1.7.0 enthält außerdem 85a0c292 (#4860, „Fix native catalog credential vending skipping allowedLocations re-validation"), der die damit verbundene Defense-in-Depth-Lücke schließt: Der Credential-Pfad selbst validiert jetzt erneut, statt jedem Aufrufer zu vertrauen. Das ist die strukturelle Hälfte des Problems und ein weiterer Grund, warum 1.7.0 und nicht 1.6.0 die Version ist, auf der man sein sollte.

Die Abdeckung wurde anhand der Release-Tags geprüft: 1dd5feeb ist in 1.6.0 und 1.7.0 enthalten; 7e822f23 und 85a0c292 nur in 1.7.0.

Für alle, die an einer älteren Release-Linie festhalten, werden beide Änderungen als Patches bereitgestellt: 0001 für den Tabellenpfad ≤ 1.5.0, 0002 für den View-Pfad von 1.6.0.

Hinweise für Betreiber — Upgrade-Pfad, Gegenmaßnahmen und wie man in vorhandenen Logs nach Ausnutzung sucht — finden sich in docs/REMEDIATION.md.

Verifizierte Versionsmatrix

Erstellt mit ./scripts/version-matrix.sh; jede Zeile ist ein vollständiger Stack-Start und ein Live-Exploit-Versuch. Siehe docs/AFFECTED-VERSIONS.md.

1.4.1 ist wichtig: Es ist das Release, das CVE-2026-42809 behob, denselben Validieren-nach-Vergabe-Fehler im stage-create-Pfad. Dieser Fix war auf den im Report genannten Endpunkt beschränkt, und das Muster wiederholte sich dann zweimal — register behielt das Verhalten bis 1.6.0, und das neue register-view von 1.6.0 wurde damit geboren.

Umfang und Ehrlichkeit bezüglich der Auswirkungen

Was dieser Reproduktor nachweist, und nichts weiter:

  • Polaris führt einen serverseitigen Lesevorgang mit ausgegebenen Credentials an einem beliebigen, vom Angreifer gewählten Standort außerhalb der deklarierten Speichergrenze des Katalogs durch — über register auf ≤ 1.5.0 und über register-view auf 1.6.0.
  • Standortförmige Felder, die aus diesem Objekt geparst werden, werden an den Aufrufer zurückgegeben.
  • Objektexistenz, Bucket-Existenz und Objekttyp sind über alles hinweg beobachtbar, was der Speicher-Principal des Katalogs erreichen kann.

Was es nicht nachweist: das massenhafte Abrufen des vollständigen Inhalts eines Objekts außerhalb des Geltungsbereichs über die API. Zwei spätere Prüfungen (der Metadaten-Standort muss unter dem Tabellenstandort liegen, und der geparste Standort muss in allowedLocations sein) verhindern, dass die Registrierung abgeschlossen wird. Der Aufrufer erhält also ein Orakel plus Metadatenfragmente, nicht das gesamte Dokument. Mit einem auf dem Katalog konfigurierten S3-Endpunkt-Override ist dieselbe Primitive eine serverseitige Request Forgery gegen den konfigurierten Host.

Sicherheit

Alles läuft lokal: ein Docker-Compose-Projekt auf Loopback-Ports, eine Wegwerf-S3-Instanz (RustFS) und synthetische „Opfer"-Dateien, die dieses Repository selbst anlegt. Es wird kein externer Host kontaktiert, keine Credentials verlassen die Maschine, und docker compose down -v wird beim Beenden ausgeführt, sofern man nicht --keep übergibt. Die Objekte in victim-data/ sind fabriziert; hier gibt es nirgendwo echte Daten.

Nutze es nur auf Systemen, die dir gehören oder zu deren Test du autorisiert bist.

Anerkennung und Offenlegung

Gefunden bei einer Überprüfung des CVE-2026-42809-Fixes, gemeldet an das Sicherheitsteam der Apache Software Foundation über den Prozess in der SECURITY.md des Projekts und als CVE-2026-64640 erfasst.

Lizenz

Apache License 2.0 — siehe LICENSE. Die Compose-Umgebung ist vom Apache-Polaris-Quickstart abgeleitet; siehe NOTICE.

Tool herunterladen
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: …
Releaseregister (Tabelle)register-viewErgebnis
1.3.0-incubatingverwundbarEndpunkt fehltverwundbar
1.4.0verwundbarEndpunkt fehltverwundbar
1.4.1verwundbarEndpunkt fehltverwundbar
1.5.0verwundbarEndpunkt fehltverwundbar
1.6.0vor der Vergabe validiertverwundbarverwundbar
1.7.0vor der Vergabe validiertvor der Vergabe validiertbehoben