
Apache Spark 4.2.0 - 높음 - 원격 - 권한 잔여 - proxy-user defaultExtraClassPath
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · spark-proxyuser-classpath
분류: 권한 잔존 (CVE-2023-22946 / SPARK-41958의 잔존) 도달 범위: 원격
Apache Spark 4.2.0 (32f72996) - Apache Software Foundation
CVE-2023-22946 / SPARK-41958은 여전히 spark.submit.proxyUser.allowCustomClasspathInClusterMode를 기본값 false로 두고 있으며, --proxy-user 클러스터 제출 시 여전히 childClasspath.clear()를 실행한다. 이것이 공개된 YARN --jars 경로이다. 이후 Spark 4.0은 spark.driver.defaultExtraClassPath를 추가했다. 런처는 클러스터 모드를 포함하여 항상 해당 키를 spark-submit JVM -cp 앞에 붙인다. SPARK-41958은 이를 전혀 인지하지 못한다.
Livy 스타일 테넌트는 여전히 게이트웨이 spark-submit JVM 내부에서 스테이징된 jar를 로드할 수 있다. Hadoop UserGroupInformation.doAs는 해당 Unix UID를 변경하지 않는다.
| ID | 아직 CVE 없음 |
| 분류 | 권한 잔존 (CVE-2023-22946 / SPARK-41958의 잔존) |
| 도달 범위 | 원격 (게이트웨이를 통한 Livy 스타일 --proxy-user 작업 제출) |
| CWE | CWE-269, CWE-427 |
| CVSS | 높음: 8.8 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| 제품 | Apache Spark |
| 영향받는 버전 | Apache Spark 4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) |
| 인증 | --conf와 스테이징된 --jars를 spark-submit --proxy-user ... --deploy-mode cluster로 전달하는 Livy / Kyuubi / Oozie 스타일 게이트웨이의 인증된 테넌트 |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1:18950 전용. Witness 파일. 인용된 런처 / 제출 경로의 가젯. |
슈퍼유저 UID로 spark-submit --proxy-user <tenant> --deploy-mode cluster를 실행하는 멀티테넌트 Spark 게이트웨이(Livy, Kyuubi, Oozie 등)에서 테넌트 계정을 보유한다. 게이트웨이 JVM이 열 수 있는 jar를 스테이징한다. --conf spark.driver.defaultExtraClassPath=<staged jar>를 전송한다. SPARK-41958 게이트는 false로 유지될 수 있다. 구성된 spark-submit -cp는 여전히 해당 jar로 시작한다. 그 안의 클래스들은 게이트웨이 Unix UID로 로드된다.
--conf spark.submit.proxyUser.allowCustomClasspathInClusterMode=true는 두 번째 경로이다: .internal()은 문서 전용이고, --conf는 여전히 해당 키를 기록하며, YARN 클러스터는 그 후 childClasspath에 --jars를 유지한다. 공개 CVE-2023-22946은 clear()가 이미 커버하는 YARN 기본 --jars 경로로 남아 있다. 이 잔존은 게이트되지 않은 defaultExtraClassPath이다.
깨끗한 제출 후의 Hadoop 임퍼소네이션은 YARN AM / k8s 드라이버에 대해 여전히 프록시 사용자이다. 이 잔존은 게이트웨이 JVM에만 해당한다.
| 방법 | 싱크 | 정찰 | 무결성 | 가용성 | 출처 |
|---|---|---|---|---|---|
Livy 스타일 제출 --proxy-user + yarn/k8s/standalone 클러스터 + --conf spark.driver.defaultExtraClassPath=<staged local jar>, SPARK-41958 플래그는 false로 유지 | SparkSubmitCommandBuilder.buildSparkSubmitCommand SparkSubmitCommandBuilder.java:317-327 -cp 첫 번째 항목 | 게이트웨이 UID가 읽을 수 있는 파일 나열/읽기 (keytab 디렉터리, spark-defaults, 로컬 스테이징). 이후 RPC의 Hadoop 신원은 여전히 프록시 사용자. | spark-submit JVM 내부에서 테넌트 클래스 로드. Unix UID는 게이트웨이(Hadoop 프록시 슈퍼유저)로 유지. 랩: defaultExtraClassPath-on-cp=yes childClasspath-cleared=yes lab.WitnessMain이 SPARK-PROXYUSER-CLASSPATH-WITNESS를 기록. 공개 CVE 클래스에서 추론: 해당 UID로서의 Hadoop Configuration 리소스 오버레이 / FileSystem 구현 조회. | 오버레이가 예외를 던지면 제출 JVM 충돌. 클래스는 아님. | 랩에서 입증된 로드 + 구성된 -cp로서의 witness 기록. Hadoop 오버레이는 추론. Livy/Kyuubi --conf 패스스루는 추론 (해당 트리는 이 핀에 해당하지 않음). |
동일 제출에 --conf spark.submit.proxyUser.allowCustomClasspathInClusterMode=true와 --jars / 기본 리소스 사용 | SparkSubmit.prepareSubmitEnvironment SparkSubmit.scala:333-336,738-743,917-924 이후 runMain :980-987 | 시스템 로더가 아닌 자식 URLClassLoader에서의 walk A와 동일한 정찰. | addJarToClasspath가 실행되도록 childClasspath에 --jars 유지. 랩: conf-flag-keeps-jars=yes. | 동일. | 랩에서 입증된 childClasspath 유지. 플래그가 false로 유지될 때 clear()가 커버하는 공개 YARN --jars 경로의 재신고가 아님. |
랩 입증 vs 추론: 구성된 -cp는 클러스터 모드에서 defaultExtraClassPath를 포함; childClasspath.clear()는 기본 플래그에서 여전히 실행; spark.driver.extraClassPath는 클러스터에서 생략; 플래그 false에서 --jars는 제거됨; 해당 -cp의 witness 클래스가 오라클을 기록. Hadoop config-class 실행은 공개 CVE-2023-22946 메커니즘이며 여기서 재실행되지 않음. Livy/Kyuubi의 --conf 전달은 해당 프로젝트가 문서화한 아키텍처.
| 방법 | 싱크 | 폐쇄 유지 |
|---|---|---|
클러스터 모드에서 --driver-class-path / spark.driver.extraClassPath | SparkSubmitCommandBuilder.java:318-319 | spark-submit -cp에 추가되지 않음. 랩: extraClassPath-omitted=yes. YARN/K8s가 프록시 사용자로 시작하는 클러스터 드라이버로 전달됨. |
기본 클러스터 + --proxy-user + --jars에서 플래그를 뒤집지 않고 defaultExtraClassPath도 없음 | SparkSubmit.scala:917-918 childClasspath.clear() | YARN/standalone/k8s 클러스터 자식 클래스패스 비워짐. 랩: 대조 walk에서 childClasspath-cleared=yes. 공개 CVE-2023-22946은 이 경로로 남음. |
게이트웨이에서 --proxy-user 클라이언트 모드 드라이버 | docs/security.md Proxy User 섹션 | 문서화됨: 클라이언트 모드 드라이버 JVM은 슈퍼유저. 벤더는 CVE가 아니라고 함. Livy/Kyuubi는 클러스터 모드를 강제하도록 지시받음. |
K8s 클러스터 모드 드라이버 컨테이너(spark.kubernetes.submitInDriver=true)가 클래스패스에 . 추가 | SparkSubmit.scala:420-431 SPARK-43540 | 드라이버 파드 내부의 두 번째 spark-submit이며 Livy 호스트가 아님. 파드 UID는 컨테이너 사용자. |
클러스터 모드에서 spark.driver.extraJavaOptions | SparkSubmitCommandBuilder.java:341-357 | spark-submit JVM에 적용되지 않음. SPARK_SUBMIT_OPTS는 게이트웨이 환경이며 테넌트 --conf가 아님. |
| 제출된 앱의 YARN AM / k8s 드라이버 | 깨끗한 제출 후의 Hadoop 임퍼소네이션 | 클러스터 실행에 대해 여전히 프록시 사용자. 이 잔존은 게이트웨이 JVM에만 해당. |
| 미인증 작업 제출 / Connect SQL / ML 모델 로드 | SECURITY.md FAQ / docs/ml-security.md | 설계상. 이 잔존이 아님. |
Spark 4.2.0(32f7299601108917fb01920a54e084595b7b3bf8)을 핀하고 SparkSubmit.submit / prepareSubmitEnvironment / runMain, SPARK-41958 플래그, 런처 -cp 빌더를 따라갔다. 공개 Medium은 여전히 --jars 경로에서 유효하다: 기본 allowCustomClasspathInClusterMode는 false(package.scala:2849-2854)이고 클러스터 + proxy-user는 여전히 childClasspath를 비운다. --conf는 여전히 해당 내부 키를 기록한다(SparkSubmitArguments.scala:474-476). 별도로, Spark 4.0.0 spark.driver.defaultExtraClassPath는 클러스터 모드를 포함하여 항상 spark-submit -cp에 있다:
boolean isClientMode = isClientMode(config);
String extraClassPath = isClientMode ? config.get(SparkLauncher.DRIVER_EXTRA_CLASSPATH) : null;
String defaultExtraClassPath = config.get(SparkLauncher.DRIVER_DEFAULT_EXTRA_CLASS_PATH);
if (extraClassPath == null || extraClassPath.trim().isEmpty()) {
extraClassPath = defaultExtraClassPath;
} else {
extraClassPath += File.pathSeparator + defaultExtraClassPath;
}
List<String> cmd = buildJavaCommand(extraClassPath);
4.0.0 키는 .internal()이다(package.scala:80-85). --conf는 여전히 이를 기록한다(SparkSubmitCommandBuilder.java:572-576). SPARK-41958은 이 경로를 게이트하지 않았다: jar는 SparkSubmit이 시작되기 전에 시스템 클래스로더에 있다.
이미 기록된 잘못된 방향: 공개 CVE-2023-22946 재신고(clear()가 커버하는 YARN --jars walk); 클라이언트 모드 드라이버-슈퍼유저를 CVE로 취급(security.md는 아니라고 함); Ivy spark.jars.ivySettings (다른 가젯); SPARK_DIST_CLASSPATH / SPARK_SUBMIT_OPTS (게이트웨이 환경이며 테넌트 --conf가 아님); clear() 이후의 로그 라인(이미 비어 있는 버퍼를 기록). 연극: 리버스 셸. 오라클은 구성된 -cp가 lab.WitnessMain을 로드할 때 기록되는 witness 문자열이다.
python3 spark-proxyuser-classpath-Abraxas-Labs.py
또는
cd lab
./run.sh
핀 SparkSubmitCommandBuilder.buildSparkSubmitCommand와 SparkSubmit.prepareSubmitEnvironment의 가젯. 루프백 127.0.0.1:18950. Docker. 한 프로세스에서 네 번의 walk: