
Apache Spark 4.2.0 - Alta - Remoto - Privilégio remanescente - proxy-user defaultExtraClassPath
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · spark-proxyuser-classpath
Write-up: https://abraxaslabs.tech/research/spark-proxyuser-classpath
Classe: Resíduo de privilégio (resíduo de CVE-2023-22946 / SPARK-41958) Alcance: Remoto
Apache Spark 4.2.0 (32f72996) - Apache Software Foundation
CVE-2023-22946 / SPARK-41958 ainda define spark.submit.proxyUser.allowCustomClasspathInClusterMode como false por padrão e ainda executa childClasspath.clear() no envio em cluster com --proxy-user. Esse é o caminho público --jars do YARN. O Spark 4.0 então adicionou spark.driver.defaultExtraClassPath. O launcher sempre prefixa essa chave ao -cp da JVM do spark-submit, inclusive no modo cluster. O SPARK-41958 nunca a enxerga.
Um tenant no estilo Livy ainda pode carregar um jar preparado dentro da JVM do spark-submit do gateway. O UserGroupInformation.doAs do Hadoop não altera esse UID Unix.
| ID | ainda sem CVE |
| Classe | Resíduo de privilégio (resíduo de CVE-2023-22946 / SPARK-41958) |
| Alcance | Remoto (envio de job --proxy-user no estilo Livy pelo gateway) |
| CWE | CWE-269, CWE-427 |
| CVSS | Alto: 8.8 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| Produto | Apache Spark |
| Afetado | Apache Spark 4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) |
| Autenticação | tenant autenticado de um gateway no estilo Livy / Kyuubi / Oozie que encaminha --conf e --jars preparados para spark-submit --proxy-user ... --deploy-mode cluster |
| Licença | GNU Affero GPL v3.0 |
| Lab | Apenas 127.0.0.1:18950. Arquivo de testemunho. Gadget dos caminhos citados do launcher / submit. |
Manter uma conta de tenant em um gateway Spark multi-tenant (Livy, Kyuubi, Oozie e similares) que executa spark-submit --proxy-user <tenant> --deploy-mode cluster como um UID de superusuário. Preparar um jar que a JVM do gateway consegue abrir. Enviar --conf spark.driver.defaultExtraClassPath=<staged jar>. A barreira do SPARK-41958 pode permanecer false. O spark-submit -cp construído ainda começa com esse jar. As classes nele contidas são carregadas com o UID Unix do gateway.
--conf spark.submit.proxyUser.allowCustomClasspathInClusterMode=true é um segundo caminho: .internal() existe apenas na documentação, --conf ainda grava a chave, e o cluster YARN então mantém --jars em childClasspath. O CVE-2023-22946 público continua sendo o caminho padrão --jars do YARN que clear() já cobre. Este resíduo é o defaultExtraClassPath sem barreira.
A representação do Hadoop após um envio limpo continua sendo o proxy user para o YARN AM / driver k8s. Este resíduo afeta apenas a JVM do gateway.
| Método | Sink | Recon | Integridade | Disponibilidade | Proveniência |
|---|---|---|---|---|---|
Envio no estilo Livy --proxy-user + cluster yarn/k8s/standalone + --conf spark.driver.defaultExtraClassPath=<staged local jar>, flag SPARK-41958 mantida como false | SparkSubmitCommandBuilder.buildSparkSubmitCommand SparkSubmitCommandBuilder.java:317-327 primeira entrada de -cp | Listar/ler arquivos que o UID do gateway consegue ler (diretório keytab, spark-defaults, staging local). A identidade Hadoop das RPCs posteriores continua sendo o proxy user. | Carregar classes do tenant dentro da JVM do spark-submit. O UID Unix permanece o gateway (superusuário do proxy Hadoop). Lab: defaultExtraClassPath-on-cp=yes childClasspath-cleared=yes lab.WitnessMain escreveu SPARK-PROXYUSER-CLASSPATH-WITNESS. Inferido a partir da classe pública da CVE: sobreposição de recursos de Configuration do Hadoop / lookup de implementação de FileSystem como aquele UID. | Crash da JVM de envio se a sobreposição lançar exceção. Não é a classe. | Carregamento comprovado em lab + escrita de witness conforme -cp construído. Sobreposição Hadoop inferida. Passthrough de --conf do Livy/Kyuubi inferido (essas árvores não são este pin). |
Mesmo envio com --conf spark.submit.proxyUser.allowCustomClasspathInClusterMode=true mais --jars / recurso primário | SparkSubmit.prepareSubmitEnvironment SparkSubmit.scala:333-336,738-743,917-924 depois runMain :980-987 | Mesmo recon do caminho A, no URLClassLoader filho em vez do loader do sistema. | Manter --jars em childClasspath para que addJarToClasspath seja executado. Lab: conf-flag-keeps-jars=yes. | O mesmo. | Manutenção de childClasspath comprovada em lab. Não é um re-file do caminho público de --jars do YARN que clear() cobre quando a flag permanece false. |
Comprovado em lab vs inferido: o -cp construído contém defaultExtraClassPath em modo cluster; childClasspath.clear() ainda é executado com a flag padrão; spark.driver.extraClassPath é omitido em cluster; --jars com flag false é limpo; uma classe witness nesse -cp escreve o oracle. A execução de classe de configuração do Hadoop é o mecanismo público da CVE-2023-22946, não reexecutado aqui. O encaminhamento de --conf pelo Livy/Kyuubi é a arquitetura que esses projetos documentam.