Apache Spark 4.2.0 - 高危 - 远程 - 权限残留 - standalone REST 忽略 spark.authenticate
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · spark-rest-auth-bypass
类别: 权限残留 可达性: 远程
Apache Spark 4.2.0 (32f72996) - Apache Software Foundation
Standalone Master REST 默认开启于端口 6066,且从不读取 spark.authenticate。CVE-2018-11770 曾承诺 REST 默认关闭,并且当 RPC 密钥已设置而 REST 开启时采取故障关闭(fail-closed)策略。本次版本固定(pin)将两者都反转了。MASTER_REST_SERVER_ENABLED 为 createWithDefault(true)。过滤器仅为 MASTER_REST_SERVER_FILTERS,默认为 Nil。未认证的 POST /v1/submissions/create 会以 Worker UID 运行攻击者的 main。Worker 会注入 _SPARK_AUTH_SECRET,因此 2018 年“无执行器的 driver”这一限制不再成立。
这是 11770 的残留,而非新的 CVE-2020-9480 RCE。RPC 7077 仍会安装 AuthServerBootstrap。在 spark.authenticate=false 的集群上提交作业是文档记载的默认行为,并非此漏洞。
| ID | 暂无 CVE |
| 类别 | 权限残留(CVE-2018-11770 的残留) |
| 可达性 | 远程(未认证 HTTP 访问 standalone Master 6066) |
| CWE | CWE-306、CWE-287 |
| CVSS | 高危:8.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| 产品 | Apache Spark |
| 受影响版本 | 4.2.0(32f7299601108917fb01920a54e084595b7b3bf8)standalone Master REST |
| 认证 | REST 上无认证。运维人员已设置 spark.authenticate=true。REST 保持默认。 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1:18900。官方 spark:4.2.0 镜像。 |
我固定了标签 v4.2.0,剥离后为 32f7299601108917fb01920a54e084595b7b3bf8(2026-07-11,v4.2.0-rc6)。不是 master。不是 4.3 RC。
访问 standalone Master REST 的 6066 端口。无需 Authorization 头。spark.authenticate 已开启。spark.master.rest.filters 未设置。至少有一个 Worker 在线。
| 方法 | 汇聚点 | 权限 |
|---|---|---|
未认证 POST /v1/submissions/create | RequestSubmitDriver(Master.scala:402-420),随后 Worker DriverWrapper 执行 classForName(mainClass).main | 完整性(实验环境已验证): 以 Worker UID 运行攻击者的 mainClass。实验环境:driver RUNNING,见证文件。 |
同样的 create;Worker CommandUtils.buildLocalCommand | driver 环境变量 _SPARK_AUTH_SECRET | 完整性(实验环境已验证): driver 可通过 SASL 加入已认证的 RPC 集群。实验环境:injected=yes。 |
未认证 GET /v1/submissions/status/{id} | RequestDriverStatus(Master.scala:489-503) | 侦察(针对所创建的 id 已在实验环境验证): driver 状态 / worker 主机。 |
未认证 GET /v1/submissions/readyz | RequestReadyz | 侦察(实验环境已验证): Master 未处于 STANDBY。 |
未认证 POST /v1/submissions/kill/{id} | RequestKillDriver(Master.scala:422-453) | 完整性 + 可用性(推断): 停止其他租户的 standalone driver。相同的未认证 servlet 接线;未实际验证。 |
未认证 POST /v1/submissions/killall | RequestKillAllDrivers(Master.scala:455-478) | 可用性(推断): 终止所有等待/运行中的 standalone driver。未实际验证。 |
未认证 POST /v1/submissions/clear | RequestClearCompletedDriversAndApps | 完整性(推断): 删除已完成 driver/app 的记账信息。未实际验证。 |
实验环境已验证 vs 推断: create、密钥注入、自身 id 状态查询和 readyz 为实验环境验证。kill / killall / clear 由相同的未认证 servlet 映射推断得出。
前提条件: standalone Master(非 YARN/K8s)。运维人员已设置 spark.authenticate=true。REST 保持默认(spark.master.rest.enabled 为 true,spark.master.rest.filters 未设置)。到 Master 6066 的网络路径。至少一个 Worker。不是文档记载的开放集群(spark.authenticate=false)。
| 攻击面 | 原因 |
|---|---|
启用 spark.authenticate=true 的 RPC 7077 | 仍需要 AuthServerBootstrap。CVE-2020-9480 的接收路径保持关闭。不是新的 9480 RCE。 |
| 设置后的 JWSFilter | spark.master.rest.filters=org.apache.spark.ui.JWSFilter 加上 secretKey。无 JWT 时测试返回 403。需主动启用。默认为 Nil。 |
UI doAs | 仍需要管理员权限。REST 不继承 UI 过滤器。 |
| CVE-2022-33891 UI shell | 此版本固定中 id -Gn argv 残留已关闭。 |
| YARN / Kubernetes 提交 | 此 REST 服务器仅适用于 standalone Master。 |
默认 spark.authenticate=false 的作业提交 | FAQ:设计如此。不是此残留。 |
| Mesos REST | 在 Spark 4.0 中已移除。 |
CLI spark-submit 默认 | 仍使用 RPC 7077(useRest 字符串默认为 false)。在 spark:// 上使用 --kill / --status 始终使用 REST。残留在于服务器监听器。 |
CVE-2018-11770 的代码修复(SPARK-25088)是:REST 默认关闭,并且当 spark.authenticate.secret 已设置而 REST 开启时,require Master 故障关闭。本次版本固定:
package.scala:2045-2048。文档称:“自 Spark 4.1 起,Spark Master 守护进程默认提供 REST API。”Master.scala 中缺失故障关闭。测试 SPARK-57451: Allows REST server and spark.authenticate.secret to be enabled together(MasterSuite.scala:253-261)断言启动必须成功。NETWORK_AUTH_ENABLED / AUTH_SECRET。addFilters 仅应用 spark.master.rest.filters,默认为 Nil。遵循 CVE-2018-17190 / FAQ(“启用 spark.authenticate”)的运维人员,在 6066 上仍然存在未认证 HTTP 作业提交。
错误方向:将开放集群上的未认证作业提交视为 CVE;声称这会在 RPC 7077 上重新打开 9480;将 JWSFilter 默认关闭视为残留,而非 spark.authenticate 未映射到 REST;固定 4.3 RC。
噱头:反向 shell。判定依据是见证字符串加上 injected=yes。
python3 spark-rest-auth-bypass-Abraxas-Labs.py
或
cd lab
./run.sh
回环地址 127.0.0.1:18900 发布到容器 6066。Compose 项目 spark-rest-auth-bypass。官方 spark:4.2.0 镜像。Master 和 Worker 均设置 spark.authenticate=true 和 spark.authenticate.secret。REST 过滤器未设置。见证字符串 SPARK-REST-AUTH-BYPASS-WITNESS。最后一行:
SUCCESS SPARK-REST-AUTH-BYPASS create-http=200 success=true submissionId=driver-20261012231831-0000 injected=yes state=RUNNING SPARK-REST-AUTH-BYPASS-WITNESS
将 spark.master.rest.enabled 默认值改回 false,或在 spark.authenticate 开启且 REST 过滤器为空时故障关闭。将 spark.authenticate 映射到 REST,或在设置 RPC 密钥时要求 JWSFilter。在此之前,开启 RPC 认证的运维人员仍必须设置 spark.master.rest.enabled=false,或安装 spark.master.rest.filters=org.apache.spark.ui.JWSFilter 并配置 secretKey。