Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-64640 — Riproduttore per CVE-2026-64640 — Apache Polaris Iceberg REST register/register-view fornisce credenziali di storage e legge una posizione di metadati scelta dall'attaccante prima di validare allowedLocations (lettura cross-tenant confuso-deputato). Interessate versioni ≤ 1.6.0, corretto in 1.7.0. | Kitploit
Strumenti/GitHubGitHub/oscerd/cve-2026-64640
RicognizioneAnalisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebEsfiltrazione DatiPenetration TestingSicurezza CloudSicurezza delle API
GitHuboscerd/cve-2026-64640

CVE-2026-64640

Vedi Repository
151 mese faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →

Informazioni

Riproduttore per CVE-2026-64640 — Apache Polaris Iceberg REST register/register-view fornisce credenziali di storage e legge una posizione di metadati scelta dall'attaccante prima di validare allowedLocations (lettura cross-tenant confuso-deputato). Interessate versioni ≤ 1.6.0, corretto in 1.7.0.

Condividi

CVE-2026-64640 — Apache Polaris: emissione di credenziali prima della validazione della location in register

Uno strumento di riproduzione autonomo, con un solo comando, per CVE-2026-64640: gli endpoint register dell'Iceberg REST in Apache Polaris generano credenziali di storage cloud per un percorso fornito dal chiamante e leggono quel percorso lato server prima di controllarlo rispetto agli allowedLocations del catalogo.

Un principal il cui unico privilegio è creare tabelle nel proprio catalogo può far sì che Polaris usi le credenziali di storage del catalogo per leggere oggetti che il catalogo non avrebbe mai dovuto toccare — il prefisso di un altro tenant, un altro bucket, qualsiasi cosa raggiungibile dal principal di storage.

CVECVE-2026-64640
Componentepolaris-runtime-service — IcebergCatalog / LocalIcebergCatalog: registerTable, registerView
EndpointPOST /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 (authorization bypass through user-controlled key), CWE-918 (SSRF)
GravitàAlta — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N (8.1)
Versioni affette≤ 1.6.0 (verificato su 1.3.0-incubating, 1.4.0, 1.4.1, 1.5.0, 1.6.0)
Corretto in1.7.0 — la 1.6.0 corregge solo il percorso delle tabelle e reintroduce il difetto nel nuovo percorso delle viste
Privilegio richiestoun principal autenticato con TABLE_CREATE / CATALOG_MANAGE_CONTENT su qualsiasi catalogo — nessun admin

La 1.6.0 non è una correzione. Chiude register (incidentalmente, dentro una PR di funzionalità) e introduce il nuovo endpoint register-view con lo stesso errore di ordinamento. Lo strumento di riproduzione dimostra entrambe le metà. Aggiornare alla 1.7.0.

Esecuzione

Requisiti: Docker con il plugin Compose v2, curl, python3, bash. Nient'altro — l'ambiente è costruito da immagini pubblicate e smantellato al termine.

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

Il codice di uscita 0 significa che la vulnerabilità è stata riprodotta, 1 che non lo è stata, 2 che l'ambiente non è riuscito ad avviarsi. Ogni richiesta e risposta viene scritta in evidence/<timestamp>-polaris-<tag>/.

Com'è fatto l'ambiente

  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

L'ultima riga è la parte realistica. Gli operatori delimitano un catalogo con allowedLocations; il ruolo IAM sottostante è quasi sempre più ampio di un singolo prefisso. allowedLocations è il muro. Questo bug lo aggira.

Cosa dimostra

Test 0 — il muro è reale. La creazione di una tabella con una location esplicita in s3://tenant-b-private viene rifiutata con 403 ForbiddenException, prima che venga letta qualsiasi cosa. Polaris sa perfettamente che la location è fuori dai limiti.

Test 1 — register la legge comunque. Lo stesso principal punta register a s3://tenant-b-private/sales/metadata/00007-tenant-b-sales.metadata.json. La risposta è anch'essa un 403 — ma cita s3://tenant-b-private/warehouse/CANARY-64640-4f1c9e2a-tenant-b-sales, una stringa che esiste solo all'interno del corpo di quell'oggetto:

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

La richiesta non menziona mai warehouse/. Polaris può produrre quelle stringhe solo recuperando e analizzando l'oggetto con le credenziali del catalogo. Il 403 è Polaris che intercetta la violazione un passo dopo la lettura che avrebbe dovuto impedire.

Test 2 — cosa torna indietro. Due campi distinti estratti dal documento della vittima vengono restituiti al chiamante: la location dichiarata della tabella e la sua proprietà write.data.path.

Test 3 — un oracolo di enumerazione dello storage. La stessa chiamata risponde in modo diverso per ogni stato di un target esterno agli allowedLocations:

probe (tutti fuori dagli allowedLocations)risposta 1.4.1
metadati Iceberg validi, esistenti403 ForbiddenException + location analizzate restituite
chiave mancante400 NotFoundException — Location does not exist: …
bucket inesistente400 NoSuchBucketException — errore S3 SDK grezzo
esiste ma non è metadati Iceberg503 RuntimeIOException — Failed to read file: …

Quattro risposte distinguibili significano quattro informazioni sullo storage che il chiamante non ha il diritto di apprendere. Su AWS reale la sonda sull'esistenza del bucket raggiunge lo spazio dei nomi globale dei bucket S3, usando le credenziali del catalogo.

Su una build corretta ogni riga di quella tabella è lo stesso 403 che nomina solo il percorso richiesto, e nulla dall'interno dell'oggetto torna indietro — lo script rileva quella firma e riporta NOT VULNERABLE — pre-validation observed.

Test 4 — lo stesso difetto su register-view. Polaris 1.6.0 ha aggiunto POST .../namespaces/{ns}/register-view, che raggiunge registerView, il quale carica la FileIO e analizza il documento del chiamante senza alcuna validazione preliminare — esattamente ciò che registerTable aveva appena smesso di fare. Sulla 1.6.0 il canary della vista torna:

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

Quindi un'installazione 1.6.0 è ancora esposta, attraverso un endpoint diverso, alla stessa primitiva. Sulla 1.4.1 e precedenti l'endpoint non esiste e lo script lo segnala.

Causa principale

IcebergCatalog.registerTable (LocalIcebergCatalog dalla 1.6.0), prima della correzione — registerView ha la forma identica:

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

La catena di emissione (loadFileIOForTableLike → StorageAccessConfigProvider.getStorageAccessConfig → *StorageIntegration.getSubscopedCreds) non esegue alcun controllo su allowedLocations per conto proprio, quindi l'unica verifica è quella al momento del commit — e a quel punto la lettura privilegiata è già avvenuta e il suo risultato è nella risposta.

Scarica lo strumento