Netflix Conductor Unauthenticated RCE via INLINE GraalVM Evaluator — CVE-2026-58138
by Caio Fabrício (BiiTts) — [github.com/BiiTts](https://github.com/BiiTts) · 2026-07-05
- Severity
- Critical
- CVE
- CVE-2026-58138 ([VulnCheck advisory](https://www.vulncheck.com/advisories/orkes-conductor-unauthenticated-rce-via-graalvm-script-evaluators))
- Category
- misc
- Affected product
- Conductor (OSS / Orkes workflow orchestration engine), community API
- Affected versions
- 3.21.21 through versions before 3.30.2 (fixed in 3.30.2; lab reproduces against 3.22.3). Per source repository, 3.30.0/3.30.1 added a partial denyAccess blocklist that this specific PoC does not claim to bypass.
- Disclosed
- 2026-07-05
- Patch status
- patched
References
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-06-30 |
| Author / Researcher | Caio Fabrício (BiiTts) — github.com/BiiTts |
| CVE / Advisory | CVE-2026-58138 (VulnCheck advisory) |
| Category | misc |
| Severity | Critical |
| CVSS Score | 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H, per source repository) |
| Status | PoC |
| Tags | conductor, orkes, graalvm, script-evaluator, host-access, workflow-engine, unauth-rce |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | Conductor (OSS / Orkes workflow orchestration engine), community API |
| Versions Affected | 3.21.21 through versions before 3.30.2 (fixed in 3.30.2; lab reproduces against 3.22.3). Per source repository, 3.30.0/3.30.1 added a partial denyAccess blocklist that this specific PoC does not claim to bypass. |
| Language / Platform | Java / GraalVM (target); PoC client is Python 3 standard library only |
| Authentication Required | No — the community Conductor API has no authentication by default |
| Network Access Required | Yes — reach the Conductor REST API (default port 8080) |
Summary
Conductor evaluates user-supplied JavaScript (and Python) expressions in INLINE (and related LAMBDA/DO_WHILE/SWITCH) workflow tasks using a GraalVM polyglot context built with full host access (HostAccess.ALL / allowAllAccess(true)). Because the community REST API requires no authentication, an attacker can register and start a workflow whose INLINE task contains a script that uses Java reflection to reach java.lang.Runtime and execute OS commands, with the resulting stdout returned as the task’s output. The PoC reproduces this end-to-end against conductoross/conductor:3.22.3, confirming command execution running as root inside the container.
Vulnerability Details
Root Cause
core/.../events/ScriptEvaluator.java (versions up to ~3.29.x, including the lab’s 3.22.3) builds its GraalVM JavaScript context as:
| |
HostAccess.ALL disables GraalVM’s polyglot sandbox, allowing the script to call any public method or field on Java host objects. The INLINE task binds its input parameters as a live Java object ($) inside the script scope. From that object the script can call .getClass().getClass() to reach java.lang.Class, then use Class.forName to load arbitrary classes — including java.lang.Runtime — and invoke Runtime.exec(...) to run OS commands. PythonEvaluator.java has the equivalent issue via Context.newBuilder("python").allowAllAccess(true).
Attack Vector
- Register a workflow definition via
POST /api/metadata/workflow(unauthenticated) containing a singleINLINEtask whoseinputParameters.expressionis a JavaScript payload that bootstraps reflection from the bound$object to reachClass.forName, loadsjava.lang.Runtime, builds aString[]{"sh","-c",cmd}array reflectively, and callsRuntime.exec(...). - Start the workflow via
POST /api/workflow/{name}(unauthenticated); theINLINEtask’s expression is evaluated synchronously inside the GraalVM JS context. - The script reads the spawned process’s stdout via
InputStreamReader/BufferedReaderand returns it as the JS expression’s result, which Conductor stores as the task’soutputData.result. - The attacker retrieves the result via
GET /api/workflow/{id}?includeTasks=true, reading theINLINEtask’soutputData.resultfield — the live stdout of the executed command.
Impact
An unauthenticated remote attacker who can reach the Conductor API can execute arbitrary OS commands on the orchestrator host. In the reproduced lab this ran as root inside the container, giving full compromise of the workflow engine, its task queues/persistence layer, and any downstream systems or credentials reachable from workflows it orchestrates.
Environment / Lab Setup
Target: Docker container running conductoross/conductor:3.22.3 (all-in-one image), REST API on port 8080, no authentication configured.
Attacker: Python 3 standard library only (urllib.request); network reachability to target:8080.
Proof of Concept
PoC Script
See
exploit.pyin this folder.
| |
The script registers a workflow definition whose single INLINE task carries a JavaScript reflection payload, starts the workflow, waits briefly, then reads back the task’s output via the workflow status API — printing the target command’s live stdout (e.g. uid=0(root) gid=0(root) groups=0(root)) as confirmation of unauthenticated code execution on the Conductor host.
Detection & Indicators of Compromise
[*] registering workflow with a malicious INLINE (javascript) task ... (no auth)
[*] started workflow id=3c664bba-88c0-4730-a020-c1dafd94673e; reading INLINE task output ...
[+] UNAUTHENTICATED RCE CONFIRMED - command output from the Conductor host:
uid=0(root) gid=0(root) groups=0(root)
Signs of compromise:
- Workflow definitions registered via
POST /api/metadata/workflowwhoseINLINE/LAMBDA/DO_WHILE/SWITCHtaskexpressionfields referencegetClass,forName,Runtime,exec,ProcessBuilder, or other Java reflection primitives. - Conductor server process spawning shell (
sh -c) or other unexpected child processes. - Unexplained workflow executions from unauthenticated/unfamiliar clients, especially ones defining single-task
INLINEworkflows.
Remediation
| Action | Detail |
|---|---|
| Primary fix | Upgrade to Conductor >= 3.30.2, which adds allowHostClassLoading(false) and removes allowAllAccess from the Python evaluator, preventing scripts from materializing the host classes needed to reach Runtime. |
| Interim mitigation | Put authentication in front of the Conductor API; run the Conductor server process as a non-root, least-privilege user; restrict which clients/networks can register or start workflows; monitor workflow definitions for reflection-related script content. |
References
Notes
Mirrored from https://github.com/BiiTts/CVE-2026-58138-Conductor-Unauth-RCE on 2026-07-05.
| |