
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 выключенным по умолчанию и fail-closed, если RPC-секрет задан, а REST включён. Этот пин развернул оба обещания. MASTER_REST_SERVER_ENABLED — это createWithDefault(true). Фильтры — только MASTER_REST_SERVER_FILTERS, по умолчанию Nil. Неаутентифицированный POST /v1/submissions/create запускает атакующий main от имени UID Worker. Worker внедряет _SPARK_AUTH_SECRET, поэтому ограничение 2018 года «driver без executors» не действует.
Это остаток от 11770, а не новый RCE CVE-2020-9480. RPC 7077 по-прежнему устанавливает AuthServerBootstrap. Отправка задания в кластере с spark.authenticate=false — это документированное поведение по умолчанию, и это не данный баг.
| ID | CVE пока нет |
| Класс | Остаточная привилегия (остаток от CVE-2018-11770) |
| Доступ | Удалённый (неаутентифицированный HTTP к standalone Master 6066) |
| CWE | CWE-306, CWE-287 |
| CVSS | High: 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, peel 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 | Целостность (доказано в лаборатории): запуск атакующего mainClass от имени UID Worker. Лаборатория: driver RUNNING, файл-свидетель. |
Тот же create; Worker CommandUtils.buildLocalCommand | переменная окружения driver _SPARK_AUTH_SECRET | Целостность (доказано в лаборатории): driver может присоединиться к аутентифицированному RPC-кластеру через SASL. Лаборатория: 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 другого арендатора. Та же неаутентифицированная конфигурация сервлета; не проверялось. |
Неаутентифицированный 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 — предположительны на основе той же неаутентифицированной карты сервлетов.
Требуется: standalone Master (не YARN/K8s). Оператор задал spark.authenticate=true. REST оставлен по умолчанию (spark.master.rest.enabled true, spark.master.rest.filters не задан). Сетевой путь к Master 6066. Как минимум один Worker. Не документированно-открытый кластер (spark.authenticate=false).
| Поверхность | Причина |
|---|---|
RPC 7077 с spark.authenticate=true | AuthServerBootstrap по-прежнему требуется. Путь приёма CVE-2020-9480 остаётся закрытым. Это не новый RCE 9480. |
| JWSFilter, когда задан | spark.master.rest.filters=org.apache.spark.ui.JWSFilter плюс secretKey. Тесты дают 403 без JWT. Опционально. По умолчанию Nil. |
UI doAs | по-прежнему требует admin. REST не наследует фильтры UI. |
| Оболочка UI CVE-2022-33891 | остаток argv id -Gn закрыт на этом пине. |
| Отправка YARN / Kubernetes | этот REST-сервер только для standalone Master. |
Отправка задания при spark.authenticate=false по умолчанию | FAQ: так задумано. Не этот остаток. |
| Mesos REST | удалён в Spark 4.0. |
CLI spark-submit по умолчанию | по-прежнему использует RPC 7077 (useRest по умолчанию false). --kill / --status на spark:// всегда используют REST. Остаток — это серверный слушатель. |
Исправление кода CVE-2018-11770 (SPARK-25088) заключалось в следующем: REST по умолчанию выключен, и require Master fail-closed, если spark.authenticate.secret задан, а REST включён. Этот пин: