
Apache Spark 4.2.0 - Hoch - Remote - Dateischreiben - Connect-Sitzung SET copyFromLocalToFs.allowDestLocal
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · spark-connect-copy-local
Write-up: https://abraxaslabs.tech/research/spark-connect-copy-local
Klasse: Dateischreiben (Überbleibsel von SPARK-58531; nur auf 4.3.0 statisch) Reichweite: Remote
Apache Spark 4.2.0 (32f72996) - Apache Software Foundation
spark.sql.artifact.copyFromLocalToFs.allowDestLocal ist bei diesem Pin noch buildConf (pro Sitzung setzbar). SPARK-58531 hat es in 4.3.0 nach StaticSQLConf verschoben. Eine Connect-Sitzung kann das nur für Tests gedachte Local-Dest-Gate per SET umschalten, danach überschreibt copyFromLocalToFs / AddArtifacts forward_to_fs/<abs> einen treiberlokalen Pfad unter der Spark-UID.
Connect-Sitzung SET, dann schreibt forward_to_fs treiberlokale Dateien. Ziel muss LocalFileSystem sein. Kein RCE.
| ID | noch keine CVE (Überbleibsel von SPARK-58531) |
| Klasse | Dateischreiben (Überbleibsel von SPARK-58531; nur auf 4.3.0 statisch) |
| Reichweite | Remote (Spark Connect Config + AddArtifacts) |
| CWE | CWE-22, CWE-732 |
| CVSS | Hoch: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H |
| Produkt | Apache Spark (ASF) |
| Betroffen | Apache Spark 4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8). 4.3.0 ist statisch. |
| Auth | Connect-Client, der ConfigRequest.SET und AddArtifacts ausführen kann. Standard-Connect hat kein PSK. |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1:18920 |
Ein Spark-Connect-Client, der gRPC erreichen kann (Standard-Bind-Port 15002, kein PSK, sofern der Betreiber nicht spark.connect.authenticate.token gesetzt hat), kann ein nur für Tests gedachtes Gate, mit dem der Treiber gestartet wurde, abschalten und dann einen gewählten lokalen Pfad auf dem Treiber unter der Spark-UID überschreiben.
| Methode | Senke | Privileg |
|---|---|---|
gRPC Config SET spark.sql.artifact.copyFromLocalToFs.allowDestLocal=true (oder SQL SET) | SparkConnectConfigHandler.handleSet -> RuntimeConfig.set -> SQLConf.setConfString | Integrität (Sitzungskonfiguration, im Lab nachgewiesen): schaltet das Local-Dest-Gate pro Sitzung um. Schreibt für sich genommen keine Datei. Ändert keine anderen Sitzungen. Lab: SET HTTP 200, modifiable=True. |
gRPC AddArtifacts Name forward_to_fs + absolutes Ziel, CRC ok | ArtifactManager.uploadArtifactToFs -> LocalFileSystem.copyFromLocalFile(delSrc=false, overwrite=true) | Integrität (Dateiüberschreiben, im Lab nachgewiesen): Schreiben/Überschreiben eines treiberlokalen Pfads unter der Spark-UID, außerhalb von artifactRootDirectory/<sessionUUID>/. Lab: Ziel /oracle/SPARK-CONNECT-COPY-LOCAL-WITNESS, uid 185, Inhalt WITNESS. |
| Dasselbe AddArtifacts auf HDFS/S3/ABFS-Ziel | dokumentiertes copyFromLocalToFs | Integrität (Cluster-FS, by design): nicht dieses Überbleibsel. Ein Ziel, das nicht LocalFileSystem ist, konsultiert das Test-Flag nie. |
Im Lab nachgewiesen vs. abgeleitet: das Sitzungs-SET des buildConf-Schlüssels und anschließend das Schreiben auf ein LocalFileSystem-Ziel als uid 185 außerhalb der Artefakt-Sandbox ist im Lab nachgewiesen. Das Überschreiben eines Pfads durch die Spark-UID, den der Prozess schreiben kann (Treiber-Arbeitsverzeichnis, ein weltweit beschreibbarer Drop, ein bereits ausführbares Skript, das der Betreiber später ausführt), ist abgeleitet. Keine RIP-Kontrolle. Dateischreiben nicht zu RCE aufblähen.
Voraussetzungen: Spark Connect muss lauschen. Client, der die Session-SQL-Conf setzen und AddArtifacts ausführen kann. Das Ziel muss das Hadoop-LocalFileSystem sein. Standard-Connect hat kein PSK; wenn der Betreiber ein Token gesetzt hat, benötigt der Leftover weiterhin diesen gemeinsamen Bearer. Es ist eine Umgehung der lokalen Ziel-Kontrolle, keine PSK-Umgehung.
| Oberfläche | Lab |
|---|---|
| Kopieren ohne SET | 400 _LEGACY_ERROR_TEMP_3161, Ziel fehlt |
Setzen der alten statischen spark.connect.copyFromLocalToFs.allowDestLocal | 400 CANNOT_MODIFY_STATIC_CONFIG |
Artefaktname .. / absolutes Staging (ArtifactUtils.concatenatePaths) | INVALID_ARTIFACT_PATH |
Nicht-forward_to_fs-Artefakte | bleiben unter artifactRootDirectory/<sessionUUID>/ |
| HDFS-/Cloud-Ziel ohne das Flag | dokumentierte API, nicht dieser Leftover |
Unauth SQL / Python UDF / Scala UdfPacket auf offenem Connect | Vendor-FAQ Job-Submit; DROP |
| SPARK-52122 ML DefaultParamsReader | Allowlist + safeMLClassLoader bei diesem Pin |
Keine Shell. Kein Heap-Dump. Kein Connect-PSK-Skip. Das Ziel muss weiterhin LocalFileSystem sein. Der Schreibvorgang erfolgt als Spark-UID, nicht als root.
uploadArtifactToFs verweigert ein LocalFileSystem-Ziel, es sei denn, das Test-Flag ist aktiviert, mit einem expliziten Kommentar, dass andernfalls ein Benutzer eine beliebige Datei auf dem Treiber überschreibt:
if (fs.isInstanceOf[LocalFileSystem]) {
val allowDestLocalConf =
session.sessionState.conf.getConf(SQLConf.ARTIFACT_COPY_FROM_LOCAL_TO_FS_ALLOW_DEST_LOCAL)
.getOrElse(
session.conf.get("spark.connect.copyFromLocalToFs.allowDestLocal").contains("true"))
if (!allowDestLocalConf) {
throw new SparkUnsupportedOperationException("_LEGACY_ERROR_TEMP_3161")
}
}
fs.copyFromLocalFile(false, true, new FSPath(localPath.toString), destFSPath)
Der 3.5-Schlüssel ist statisch, standardmäßig false. Der 4.0-Ersatz ist buildConf optional:
val ARTIFACT_COPY_FROM_LOCAL_TO_FS_ALLOW_DEST_LOCAL =
buildConf("spark.sql.artifact.copyFromLocalToFs.allowDestLocal")
.internal()
...
.booleanConf
.createOptional
buildConf ruft registerStaticConfigKey nicht auf. isModifiable ist containsConfigKey && !isStaticConfigKey. RuntimeConfig.set lehnt nur statische Schlüssel ab. Interne Schlüssel sind weiterhin setzbar. Nach SET gibt getConf(ARTIFACT_...) Some(true) zurück, und der getOrElse-Fallback auf die statische alte Konfiguration wird übersprungen.
SPARK-58531 / PR 57730 „Convert spark.sql.artifact.copyFromLocalToFs.allowDestLocal to a static conf“ ist am 2026-08-05 gelöst, Fix Version 4.3.0. JIRA: Die Konfiguration „controls whether a caller can write to an arbitrary path on the driver's local filesystem, so it is meant to be set by whoever starts the driver.“ 4.2.0 ist als Affects aufgeführt. Dieser Pin enthält weiterhin die Laufzeit-Konfiguration.