Someone left a Python REPL bolted to your production workflow engine with no login screen
CVE-2026-58138 is an unauthenticated remote code execution vulnerability in Orkes Conductor (and Netflix Conductor OSS) versions 3.21.21 through 3.30.1. The INLINE, LAMBDA, DO_WHILE, and SWITCH task types evaluate user-supplied JavaScript or Python expressions inside a GraalVM context configured with HostAccess.ALL — effectively giving every expression full access to the Java runtime. An attacker submits a single unauthenticated POST to /api/metadata/workflow containing a workflow definition with a malicious INLINE task, triggers it via /api/workflow/{name}, and the GraalVM evaluator happily calls java.lang.Runtime.exec() to run arbitrary OS commands as the Conductor process — which in containerized deployments frequently runs as root. No credentials, no user interaction, no complexity. One HTTP request to register, one to fire.
The vendor's CRITICAL 9.8 rating is honest and, unusually, undersells no aspect of the real risk. This is textbook pre-auth RCE: network-reachable, zero-click, trivially weaponized. Multiple public PoCs landed within weeks of disclosure (9 GitHub repos, 3 weaponized, plus Exploit-DB EDB-52633). Active exploitation was confirmed by Empirical Security on August 21, 2026, and Fortinet blocked approximately 7,000 attempts between September 2–9, with attack traffic originating from Germany, Hong Kong, Indonesia, the U.A.E., and India. The only reason this isn't on CISA KEV yet is bureaucratic latency — the exploitation evidence already meets the listing criteria.
5 steps from start to impact.
Discover exposed Conductor instance
/swagger-ui.html) or API docs (/v3/api-docs). Shodan/Censys queries like http.title:"Conductor UI" enumerate targets. The Swagger endpoint both confirms the product and reveals the full API surface.- Target Conductor instance is network-reachable (internet or internal network)
- Many enterprises deploy Conductor behind internal networks, not internet-facing
- Conductor on Orkes Cloud (SaaS) is managed and patched by Orkes
http.title:"Conductor UI" identifies exposed instances. No credentialed Tenable or Qualys plugin exists as of September 2026.Register malicious workflow definition
POST /api/metadata/workflow with a JSON body containing an INLINE task whose expression field holds a JavaScript payload. The payload uses GraalVM's Java interop to call java.lang.Class.forName('java.lang.Runtime'), obtain the runtime instance, and build a command array for Runtime.exec(). No authentication token, API key, or session cookie is required — the community/OSS API ships open by default.- Conductor API accepts unauthenticated requests (default OSS configuration)
- GraalVM evaluator configured with HostAccess.ALL (default)
- Enterprises that front Conductor with an authenticated reverse proxy block this step
- Organizations using Orkes Cloud (managed SaaS) have authentication enforced
Runtime, ProcessBuilder, or java.lang.Class.forName in JSON POST bodies to /api/metadata/workflow. Fortinet IPS signature DB 36.267 detects this.Trigger workflow execution
POST /api/workflow/{workflowName} to execute the registered workflow. The Conductor server schedules the INLINE task, and the GraalVM evaluator processes the malicious JavaScript expression. The entire chain — registration plus execution — completes in two HTTP requests taking under a second.- Workflow registration in Step 2 succeeded
- None — if Step 2 works, Step 3 is automatic
Achieve OS command execution
java.lang.Runtime.exec() and spawns a child process (typically sh -c <command>). The command runs with the privileges of the Conductor JVM process — in containerized deployments, frequently root. The attacker retrieves output via GET /api/workflow/{workflowId}?includeTasks=true, reading stdout from the task result.- GraalVM evaluator has HostAccess.ALL (default)
- Container runtime security (gVisor, Kata, Falco) may detect anomalous child process spawning from a Java process
- Read-only container filesystems limit persistence options
Post-exploitation: lateral movement and data access
- Successful command execution from Step 4
- Network segmentation limits lateral movement
- Kubernetes NetworkPolicies restrict pod-to-pod traffic
- Secret management via Vault/KMS rather than environment variables limits credential exposure
The supporting signals.
| In-the-Wild Exploitation | Confirmed active. Empirical Security observed exploitation August 21, 2026. Fortinet blocked ~7,000 attempts Sept 2–9, with 1,290 in a single 24-hour window (132% daily increase). Attack origins: Germany, Hong Kong, Indonesia, U.A.E., India. |
|---|---|
| Proof-of-Concept | Weaponized and public. 9 GitHub PoC repos (3 marked weaponized), Exploit-DB EDB-52633, researcher 0xgh057r3c0n. Trivial one-liner: python3 exploit.py http://target:8080 -c 'id'. |
| EPSS | 0.09257 (94th percentile) — top 6% of all scored CVEs for predicted exploitation probability in the next 30 days. |
| KEV Status | Not listed as of 2026-09-20. Meets listing criteria (active exploitation confirmed, patch available). Expect addition imminently. |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (9.8) / CVSS v4.0: 9.3. Network-reachable, no authentication, no user interaction, full CIA impact. Every vector component is worst-case. |
| Affected Versions | Conductor OSS and Orkes Conductor 3.21.21 through 3.30.1. Versions 3.30.0 and 3.30.1 contain incomplete fixes — only 3.30.2+ fully resolves the flaw. |
| Fixed Version | 3.30.2 (released June 3, 2026, 27 days before CVE publication on June 30). |
| Scanning & Exposure | Shodan/Censys query: http.title:"Conductor UI". No quantified internet-exposure count published. Default port 8080. No credentialed Tenable or Qualys plugin exists as of September 2026. |
| Installed Base | Orkes claims 3,000+ enterprise deployments including LinkedIn, Twilio, Quest Diagnostics, Netflix, Tesla, JP Morgan Chase, American Express. Open-source deployments largely invisible to asset inventories. |
| Reporting Researcher | Vulnerability disclosed by Orkes; exploitation activity documented by Empirical Security, Fortinet FortiGuard Labs, and Previdian (honeypot telemetry since July 24, 2026). |
Why this verdict
- Zero authentication friction: The Conductor OSS API ships without authentication by default. No API key, no session token, no RBAC check stands between an attacker and workflow registration. This is not a misconfiguration — it is the default shipping state. Every prerequisite in the chain (register workflow → execute workflow → command execution) completes unauthenticated.
- Trivially weaponized, already exploited: Public PoC reduces the attack to
python3 exploit.py http://target:8080 -c 'whoami'. Fortinet telemetry shows ~7,000 blocked exploit attempts in a single week. This is not theoretical — it is in active mass exploitation. No skill barrier remains. - Attack complexity is genuinely low: The CVSS AC:L rating is accurate. No race condition, no memory corruption, no heap grooming. The attacker writes a JSON workflow definition with embedded JavaScript, posts it, and triggers it. Two HTTP requests, deterministic outcome.
- Role multiplier: Conductor is a production workflow orchestration engine — it is, by definition, a CI/CD-adjacent and microservices-orchestration component (mapping to the CI/CD + artifact stores high-value role catalog). In this role, ≥10% of Conductor installs are orchestrating production business logic, AI agent pipelines, and data workflows with credentials to downstream databases, message queues, and microservices. Compromise yields: (a) all stored workflow definitions (which frequently contain hardcoded API keys, DB connection strings, and secrets), (b) the Conductor process's network position inside the production environment, (c) in Kubernetes deployments, the pod's service account token with whatever RBAC the operator granted. Blast radius is tenant-to-supply-chain scale depending on what Conductor orchestrates. The high-value role floor is CRITICAL because the affected component *is* the orchestration platform — this is not a peripheral use case.
- No compensating default exists: Unlike products where a WAF, MFA, or network segmentation might be present by default, Conductor OSS ships with an open API on port 8080. The attacker needs only network reachability. The only real friction is whether the instance is internet-exposed — but exploitation telemetry proves many are.
Why not higher?
A 9.8 is already the ceiling for CVSS 3.1 without Scope change. The vendor score is at the maximum for an Unchanged-scope vulnerability, and the real-world conditions confirm every component of that rating. There is no basis to exceed the vendor's assessment.
Why not lower?
Downgrading requires identifying meaningful friction that reduces real-world exploitability. There is none here: no authentication, no complexity, public weaponized exploits, confirmed mass exploitation, and the affected component canonically occupies a high-value production orchestration role with supply-chain-adjacent blast radius. The absence from KEV is a bureaucratic delay, not evidence of low risk — the exploitation evidence already exists. Any deployment with a reachable Conductor API is one POST request from full host compromise.
What to do — in priority order.
- Place Conductor API behind an authenticated reverse proxy immediately — The root cause is unauthenticated API access. Deploy an authenticating reverse proxy (NGINX with OIDC, Envoy with ext_authz, or your API gateway) in front of
/api/metadata/workflowand/api/workflow/*endpoints. This is your noisgate mitigation SLA action — deploy within 3 days. This single control eliminates the entire attack chain regardless of patch status. - Restrict network access to Conductor port 8080 — Apply firewall rules or Kubernetes NetworkPolicies to ensure only authorized worker hosts and administrative IPs can reach the Conductor API. Block all internet ingress to port 8080. If you have a WAF, add rules blocking JSON POST bodies containing
Runtime,ProcessBuilder, orjava.lang.Class.forNameto workflow endpoints. - Upgrade to Conductor 3.30.2 or later — This is the definitive fix. Note that versions 3.30.0 and 3.30.1 contain incomplete patches — only 3.30.2+ fully resolves the flaw. Per the noisgate remediation SLA for CRITICAL, complete the upgrade within 90 days. Given active exploitation, treat this as urgent — ideally within days, not weeks.
- Deploy Fortinet IPS signature DB 36.267 if applicable — FortiGate, FortiADC, FortiProxy, FortiNDR, and FortiSASE users should ensure IPS signature database 36.267 is deployed, which includes detection for CVE-2026-58138 exploitation payloads.
- Audit workflow definitions for embedded secrets — Review all stored workflow definitions in Conductor for hardcoded credentials, API keys, and connection strings. Rotate any secrets found — if the instance was compromised, assume these are exfiltrated. Migrate secrets to a proper secret manager (Vault, AWS Secrets Manager, K8s Secrets with external provider).
- Enable runtime security monitoring on Conductor containers — Deploy Falco, Sysdig, or equivalent runtime security tooling to alert on shell processes (sh, bash, python) spawned as children of the Conductor Java process. This provides detection even if the exploit bypasses network-level controls.
- Standard vulnerability scanners (Tenable, Qualys) — No credentialed plugin exists for CVE-2026-58138 as of September 2026. You cannot rely on your regular scan cycle to find this. Use the Shodan query
http.title:"Conductor UI"or the verification script below instead. - Java security manager — The Java SecurityManager is deprecated (removed in JDK 17+) and does not apply to GraalVM polyglot contexts. It will not prevent this exploit.
- Application-layer rate limiting — The exploit requires only two HTTP requests. Rate limiting will not stop a targeted attacker, only slow mass scanning slightly.
- Container image scanning (Trivy, Grype) — These tools check for known-vulnerable packages in images but will not detect a running Conductor instance with the vulnerable evaluator configuration unless the image metadata maps to the affected version range.
Crowdsourced verification payload.
Run this script from any host with network access to the Conductor instance. No special privileges required. Usage: bash check_cve_2026_58138.sh http://conductor.internal:8080
#!/usr/bin/env bash
# CVE-2026-58138 Vulnerability Checker for Orkes/Netflix Conductor
# Checks whether a Conductor instance is running a vulnerable version.
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -uo pipefail
TARGET="${1:-}"
if [ -z "$TARGET" ]; then
echo "Usage: $0 <conductor_base_url>"
echo "Example: $0 http://conductor.internal:8080"
exit 2
fi
# Strip trailing slash
TARGET="${TARGET%/}"
VERSION=""
# Method 1: OpenAPI / Swagger docs (most reliable for version extraction)
echo "[*] Probing ${TARGET} for Conductor version..."
for ENDPOINT in "/v3/api-docs" "/v2/api-docs" "/swagger-resources"; do
RESP=$(curl -sk --connect-timeout 5 --max-time 10 "${TARGET}${ENDPOINT}" 2>/dev/null || true)
if [ -n "$RESP" ]; then
VER=$(echo "$RESP" | grep -oP '"version"\s*:\s*"([0-9]+\.[0-9]+\.[0-9]+[^"]*)"' | head -1 | grep -oP '[0-9]+\.[0-9]+\.[0-9]+' || true)
if [ -n "$VER" ]; then
VERSION="$VER"
echo "[*] Version found via ${ENDPOINT}: ${VERSION}"
break
fi
fi
done
# Method 2: Try /api/admin/build if available
if [ -z "$VERSION" ]; then
BUILD=$(curl -sk --connect-timeout 5 --max-time 10 "${TARGET}/api/admin/build" 2>/dev/null || true)
if [ -n "$BUILD" ]; then
VER=$(echo "$BUILD" | grep -oP '"version"\s*:\s*"([0-9]+\.[0-9]+\.[0-9]+[^"]*)"' | head -1 | grep -oP '[0-9]+\.[0-9]+\.[0-9]+' || true)
if [ -n "$VER" ]; then
VERSION="$VER"
echo "[*] Version found via /api/admin/build: ${VERSION}"
fi
fi
fi
# Method 3: Check if Swagger UI is accessible (exposure indicator)
if [ -z "$VERSION" ]; then
SWAGGER=$(curl -sk --connect-timeout 5 --max-time 10 -o /dev/null -w "%{http_code}" "${TARGET}/swagger-ui.html" 2>/dev/null || true)
if [ "$SWAGGER" = "200" ]; then
echo "[!] Swagger UI is accessible at ${TARGET}/swagger-ui.html (API exposed)"
echo "[!] Could not extract version automatically."
fi
fi
if [ -z "$VERSION" ]; then
echo "UNKNOWN - Could not determine Conductor version from ${TARGET}"
echo "Manually check: inspect conductor-server JAR version, container image tag,"
echo "or Maven/Gradle dependency declaration for conductor-core version."
exit 2
fi
# Parse version: MAJOR.MINOR.PATCH
IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"
# Validate parsed values are numeric
if ! [[ "$MAJOR" =~ ^[0-9]+$ ]] || ! [[ "$MINOR" =~ ^[0-9]+$ ]] || ! [[ "$PATCH" =~ ^[0-9]+$ ]]; then
echo "UNKNOWN - Could not parse version '${VERSION}' into numeric components"
exit 2
fi
# Vulnerable range: >= 3.21.21 AND < 3.30.2
VULN=0
if [ "$MAJOR" -eq 3 ]; then
if [ "$MINOR" -gt 30 ]; then
VULN=0 # 3.31+ is patched
elif [ "$MINOR" -eq 30 ] && [ "$PATCH" -ge 2 ]; then
VULN=0 # 3.30.2+ is patched
elif [ "$MINOR" -gt 21 ] || { [ "$MINOR" -eq 21 ] && [ "$PATCH" -ge 21 ]; }; then
VULN=1 # 3.21.21 through 3.30.1
else
VULN=0 # < 3.21.21 is not affected
fi
elif [ "$MAJOR" -gt 3 ]; then
VULN=0 # 4.x+ assumed patched
else
VULN=0 # < 3.x not in vulnerable range
fi
if [ "$VULN" -eq 1 ]; then
echo "========================================"
echo "VULNERABLE - Conductor ${VERSION} is affected by CVE-2026-58138"
echo "Unauthenticated RCE via GraalVM INLINE evaluator"
echo "Upgrade to 3.30.2+ immediately (3.30.0-3.30.1 have incomplete fixes)"
echo "========================================"
exit 1
else
echo "PATCHED - Conductor ${VERSION} is not in the affected range for CVE-2026-58138"
exit 0
fi- The Hacker News — Critical Pre-Auth RCE in Orkes Conductor Exploited in the Wild
- SecurityWeek — Critical Orkes Conductor Vulnerability Exploited in Attacks
- Empirical Security — September 2026 CVE of the Month: CVE-2026-58138
- FortiGuard Labs — Orkes Conductor Evaluator RCE Outbreak Alert
- Exploit-DB — OrkesConductor 3.30.2 Unauthenticated RCE (EDB-52633)
- GitHub PoC — 0xgh057r3c0n/CVE-2026-58138
- Bellator Cyber — Orkes Conductor RCE CVE-2026-58138: Active Exploits
- SOCRadar — CVE-2026-58138 CVE Radar
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.