CVE-2026-9198 is an unauthenticated remote code execution chain (CWE-94) in IBM Langflow OSS, the open-source visual builder for LLM and agent workflows. NVD scores it 9.8 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H). IBM published its bulletin on July 2, 2026 and shipped the fix in Langflow 1.10.1, which reached PyPI on June 23. CISA added the CVE to the Known Exploited Vulnerabilities catalog on August 4, 2026 with an August 7 remediation deadline, which is the event that makes this urgent: a bug that had been patchable for six weeks is now confirmed under active exploitation. IBM lists no workaround. Upgrading is the only vendor-sanctioned remediation.
Am I vulnerable?
Any Langflow OSS build from 1.0.0 through 1.10.0 is affected. Exposure is a function of version, not configuration: the flaw is in the application's own routes, so a vulnerable build is exploitable by anyone who can reach its HTTP API. Langflow's default listener is localhost:7860, but the product is routinely deployed to a public interface by data teams standing up AI infrastructure outside normal change control, which is how prior Langflow flaws found their victims.
Affected versions
| Product |
Vulnerable range |
Fixed in |
| IBM Langflow OSS |
1.0.0 through 1.10.0 (inclusive) |
1.10.1 (current release line is 1.11.2) |
Diagnostic commands
Read-only checks to confirm exposure:
- Installed package version (pip):
pip show langflow | grep -i '^Version:'. Vulnerable if the reported version is 1.0.0 through 1.10.0.
- Installed package version (uv environments):
uv pip list | grep -i langflow. Same version threshold applies.
- Running service version:
curl -4 -s http://127.0.0.1:7860/api/v1/version -H 'accept: application/json'. Returns the live application version, which is the authoritative check when images are pinned by digest or the tag is mutable. If this endpoint answers with no credentials from a non-loopback source, the instance is also unauthenticated-reachable.
- Auto-login state:
env | grep -i LANGFLOW_AUTO_LOGIN. No output means the variable is unset and auto-login sits at its default-enabled state.
- Kubernetes image inventory:
kubectl get deploy -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{"\t"}{.spec.template.spec.containers[*].image}{"\n"}{end}' | grep -i langflow. Treat a :latest tag as unknown rather than patched, and confirm with pip show langflow inside the container.
Setting LANGFLOW_AUTO_LOGIN=false breaks the first half of the chain but does not remediate the CVE. Only 1.10.1 or later does.
Vulnerability
CVE-2026-9198 chains two defects that are individually bounded and jointly fatal. The first is an authentication flaw: the auto-login endpoint issues a long-lived superuser bearer token to any caller on the network, with no credential check, on deployments where auto-login is enabled. Auto-login is the default. The second is a code-injection sink (CWE-94) at POST /api/v1/validate/code, an endpoint whose stated job is to validate the Python in a custom flow component.
Picus Security documented the mechanism of that sink while analyzing the same endpoint in earlier Langflow CVEs. The validator parses the submitted source into an AST and nominally executes only function definitions rather than arbitrary statements, but Python evaluates decorator expressions and default argument values at function-definition time. Code placed in either position runs inside the validator's exec() call. The AST check constrains the shape of the input without constraining what executes.
Alone, the sink requires a token. Alone, the token grants access to a UI. Together they collapse into an unauthenticated path from an HTTP request to code execution in the Langflow server process, running as the service account, which is what produces the AV:N/PR:N/AC:L vector and the 9.8 score. IBM titled its bulletin "Unauthenticated Remote Code Execution via Auto-Login Bypass and Code Validation," naming both halves.
The upstream project fixed the two halves separately in 1.10.1 under distinct advisories: GHSA-fjgc-vj2f-77hm stopped auto-login issuing a 365-day superuser token, and GHSA-2wcq-pvw2-xh7v stopped validate_code executing at all. The same release carried three further code-injection fixes, covering the Tweaks API, code-bearing nodes with an empty type, and PythonREPL execution. Note that no advisory in the langflow-ai repository carries this CVE ID; the curated GitHub Advisory Database entry is GHSA-5wm9-vgmg-cjv6. Route prefixes also differ between public writeups (/api/v1/auto_login and /api/v1/login/auto_login), so a path-based proxy rule that covers only one form will miss the other.
Threat model
Who would exploit this: Opportunistic criminal operators are the dominant category. An unauthenticated HTTP path to code execution on an internet-facing product is the shape that commodity crews find by mass-scanning Shodan and FOFA, and Trend Micro documented exactly that scan-and-drop workflow against two earlier Langflow RCEs. Second are credential thieves and initial-access brokers, who value Langflow less for its compute than for the provider keys and database secrets its flows embed. State-aligned interest is plausible but unproven for this CVE.
What they are after:
- An unauthenticated foothold on a reachable host
- Secrets from the host and from flow definitions: LLM provider API keys, cloud credentials, database connection strings
- Cryptomining revenue from host CPU and attached GPU capacity
- Botnet enlistment for DDoS, or resale of the access
- Lateral movement into production databases and cloud accounts
- Exfiltration of RAG source documents and connected internal data stores
Attack chain: An attacker who can reach the Langflow HTTP API requests a token from the unauthenticated auto-login endpoint, which issues superuser credentials to any caller on default deployments. With that token the attacker calls the code-validation endpoint, which passes user-supplied Python to the interpreter and runs it inside the Langflow server process. Execution lands with the privileges of the Langflow service account, giving the attacker the host filesystem, environment variables, stored flow definitions, and outbound network position. No user interaction, credential guessing, or prior access is required.
Blast radius: A compromised instance hands over every secret the platform needs to do its job: LLM provider API keys, vector database and SQL credentials stored in flow components, object storage keys, and anything in the container environment or .env files. The attacker also inherits the instance's network reachability, which in typical cloud deployments includes the metadata service for cloud role credentials, internal databases, and any SSH-reachable hosts whose keys are on the box. Sysdig's JADEPUFFER report traced that path end to end on an earlier Langflow RCE (CVE-2025-3248): the operator persisted via cron, pivoted with root credentials to a production MySQL server running Alibaba Nacos, and encrypted 1,342 Nacos service configuration items before deleting the originals.
CISA has now listed six Langflow vulnerabilities in KEV, four of them in the last five months. CVE-2025-3248 shares the validate/code endpoint with this one and carries a known ransomware campaign use flag. That is lineage, not evidence about CVE-2026-9198 specifically: no named security firm has published telemetry, honeypot data, or an incident tied to this CVE. Public proof-of-concept code has been reported. CISA publishes no technical detail, victim data, or attribution for the entry, and knownRansomwareCampaignUse reads "Unknown."
Mitigation
Patch
Upgrade to Langflow OSS 1.10.1 or later. IBM's bulletin states "Workarounds and Mitigations: None," so this is the only vendor-sanctioned remediation.
pip install --upgrade "langflow==1.10.1"
# or move to the current line:
pip install --upgrade "langflow>=1.11.2"
uv pip install --upgrade "langflow==1.10.1"
Pin the floor in requirements.txt so a rebuild cannot regress:
langflow>=1.10.1
For containers, pull an explicit tag and redeploy. Do not assume a :latest deployment has been re-pulled:
docker pull langflowai/langflow:1.10.1
Configuration mitigation
The following reduce exposure but do not fix the CVE. They come from third-party analysis (SentinelOne, Picus Security), not from IBM. Apply them as stopgaps if you cannot upgrade today, and upgrade regardless.
Disable auto-login and set explicit superuser credentials. This breaks the token-minting half of the chain only:
# .env or container environment
LANGFLOW_AUTO_LOGIN=false
LANGFLOW_SUPERUSER=<admin-username>
LANGFLOW_SUPERUSER_PASSWORD=<strong-password>
# restart the Langflow service after changing
Bind to loopback and front the service with an authenticating gateway:
LANGFLOW_HOST=127.0.0.1
LANGFLOW_PORT=7860
# expose only via a reverse proxy or VPN that enforces authentication
Restrict the two chained endpoints at the reverse proxy. Cover both route prefixes, since public writeups disagree on which the deployment uses:
location = /api/v1/auto_login {
allow 10.0.0.0/8; # trusted admin range only
deny all;
}
location = /api/v1/login/auto_login {
allow 10.0.0.0/8;
deny all;
}
location = /api/v1/validate/code {
allow 10.0.0.0/8;
deny all;
}
Compensating controls
- Assume secret exposure on any instance that was internet-reachable while unpatched. Rotate LLM provider API keys, database credentials, object storage keys, and cloud role credentials referenced by flows or present in the container environment. A patch does not invalidate a key already taken.
- Constrain egress. Langflow's legitimate outbound set is short: LLM and embedding providers, your vector database, a package mirror. An allowlist turns miner drops, C2 beacons, and payload downloads into blocked connections rather than detection problems.
- Block instance metadata service access (169.254.169.254) from the Langflow workload. This severs the shortest route from application RCE to cloud account compromise.
- Run Langflow non-root, in its own network segment, with no standing credentials to production databases. The JADEPUFFER path depended on reaching a production database from the Langflow host.
- Audit for post-exploitation persistence on any instance that ran an affected build while exposed: unexpected cron entries, added SSH authorized keys, and processes inside the container that the image entrypoint did not start.
Detection (starter rules, validate before deploying)
These rules are AI-generated starter content. Test against your own telemetry and tune falsepositives before deploying to production.
Network and log signals
- Unauthenticated GET to
/api/v1/auto_login (or /api/v1/login/auto_login) from an external or non-workstation source IP returning HTTP 200 with an access_token in the body. On a normal deployment this call comes from browser sessions on known internal ranges, not from cloud VPS or hosting ASNs.
- A call to the auto-login route followed by a POST to
/api/v1/validate/code from the same source within seconds, with no intervening UI traffic (no /api/v1/flows, static assets, or websocket requests). The visual editor generates surrounding chatter; exploit tooling generates the two calls back to back.
- POST to
/api/v1/validate/code with a non-browser User-Agent (python-requests, curl, Go-http-client, empty) or a missing Referer. That endpoint is normally called only by the Langflow frontend.
- Repeated 200 responses on
/api/v1/validate/code from one source across many hosts in your estate in a short window, which is the mass-scanning pattern seen against Langflow previously.
- Outbound TCP from the Langflow host or container to an IP outside its short legitimate allowlist, especially raw TCP on a high port immediately after a
validate/code POST.
- New egress to mining pool ports (3333, 4444, 5555, 7777, 8888, 14444, 45700) or DNS lookups for pool domains (
pool.*, xmr.*, *.minexmr.*, *.nanopool.*, *.supportxmr.*) from the Langflow workload.
- HTTP or FTP downloads of extensionless payload files from a bare IP with no Host header, fetched by curl or wget originating inside the Langflow container.
- New outbound SSH from the Langflow host to internal peers it has never contacted, which is the lateral-spread behavior of loaders reusing harvested keys and
known_hosts entries.
- Container runtime signal: a process inside the Langflow pod that the image entrypoint did not start, plus egress from that pod to the cluster API server or 169.254.169.254.
YARA
rule CVE_2026_9198_Langflow_Exploit_Chain_Artifact
{
meta:
description = "Starter rule. Detects CVE-2026-9198 Langflow auto_login plus validate/code exploit chain artifacts in HTTP request bodies extracted from pcap or proxy captures, WAF payload dumps, and staged public PoC tooling. Behavioural strings only, no file hashes."
author = "CVE Brief (AI-generated starter rule)"
date = "2026-08-05"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-9198"
cve = "CVE-2026-9198"
confidence = "medium"
scope = "Scan pcap or proxy extracted HTTP bodies, WAF payload logs, attacker staging directories, and process memory dumps of the Langflow worker. Do NOT run this as a general filesystem sweep and do NOT run it against the Langflow source tree, which legitimately contains these route strings."
strings:
$ep_login1 = "/api/v1/auto_login" ascii nocase
$ep_login2 = "api/v1/login/auto_login" ascii nocase
$ep_code = "/api/v1/validate/code" ascii nocase
$py1 = "__import__" ascii
$py2 = "os.system" ascii
$py3 = "subprocess.Popen" ascii
$py4 = "subprocess.check_output" ascii
$py5 = "os.popen" ascii
$py6 = "socket.socket" ascii
$py7 = "pty.spawn" ascii
$py8 = "def __init__(self, x=" ascii
$cmd1 = "curl " ascii
$cmd2 = "wget " ascii
$cmd3 = "/dev/tcp/" ascii
$cmd4 = "chmod +x" ascii
$cmd5 = "base64 -d" ascii
$cmd6 = "bash -i" ascii
$tok1 = "access_token" ascii
$tok2 = "Bearer " ascii
condition:
filesize < 2MB and
(
( ( $ep_login1 or $ep_login2 ) and $ep_code and 1 of ($tok*) )
or
( $ep_code and 2 of ($py*) )
or
( $ep_code and 1 of ($py*) and 1 of ($cmd*) )
)
}
Sigma
title: Langflow Python Server Process Spawning Shell or Download Utility (CVE-2026-9198)
id: 7b3c1f42-9d5e-4a86-b0c7-2e5f1a9d4c38
status: experimental
description: |
Detects a Langflow or uvicorn Python server process spawning an OS shell, a
download utility, or an inline Python interpreter on Linux. IBM Langflow OSS
1.0.0 through 1.10.0 (CVE-2026-9198, fixed in 1.10.1) allows an unauthenticated
attacker to mint a SUPERUSER token via the auto_login endpoint and then execute
arbitrary Python through POST /api/v1/validate/code. Successful exploitation
surfaces as the web application process spawning operating system commands,
which is the behaviour observed during mass exploitation of the closely related
Langflow validate/code flaw CVE-2025-3248 (Flodrix botnet, Monero miner drops).
This rule targets post exploitation execution rather than request shape, so it
survives payload obfuscation and TLS encrypted request bodies.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-9198
- https://www.ibm.com/support/pages/node/7278927
- https://www.trendmicro.com/en_us/research/25/f/langflow-vulnerability-flodric-botnet.html
author: CVE Brief (AI-generated starter rule, validate before deploying)
date: 2026-08-05
tags:
- attack.initial-access
- attack.t1190
- attack.execution
- attack.t1059.004
- attack.t1059.006
- cve.2026-9198
logsource:
category: process_creation
product: linux
detection:
parent_langflow:
ParentCommandLine|contains:
- 'langflow'
- 'uvicorn'
- 'gunicorn'
parent_python:
ParentImage|contains: '/python'
child_shell:
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/zsh'
- '/busybox'
child_download:
Image|endswith:
- '/curl'
- '/wget'
- '/nc'
- '/ncat'
- '/socat'
- '/base64'
- '/chmod'
child_inline_python:
Image|contains: '/python'
CommandLine|contains:
- ' -c '
- 'os.system'
- 'subprocess'
- 'socket.socket'
- 'pty.spawn'
child_recon:
CommandLine|contains:
- 'whoami'
- 'printenv'
- '/root/.bash_history'
- '/dev/tcp/'
- 'chmod +x'
- 'systemctl status sshd'
- '169.254.169.254'
filter_expected:
CommandLine|contains:
- 'pip install'
- '/usr/bin/uv '
- 'nvidia-smi'
- 'healthcheck'
condition: (parent_langflow or parent_python) and (child_shell or child_download or child_inline_python or child_recon) and not filter_expected
falsepositives:
- Langflow flows that legitimately execute code, for example the Python Code component, custom components, or a shell or terminal tool wired into a flow by design
- Developers authoring and testing custom components in the Langflow UI, which calls the same code validation endpoint as part of normal use
- Container entrypoint, init, or liveness probe scripts running under the same Python parent process
- Runtime dependency installation when a flow pulls a package on first use
- Authorised vulnerability scanners, internal red team exercises, and patch validation testing
level: high
Rule notes
The Sigma rule watches process creation rather than request shape, deliberately. A path-based webserver rule looks tempting but is structurally weak here: auto-login is called by every legitimate browser session when it is enabled (the default), and /api/v1/validate/code is called by the Langflow UI every time a user edits a custom component, so matching those paths alerts on normal product usage. TLS terminating elsewhere also means the request body is often unavailable. Watching for the uvicorn or Langflow Python parent spawning a shell, curl, wget, or inline Python catches the outcome of exploitation regardless of payload obfuscation, and it catches the follow-on loader stage seen in prior Langflow campaigns.
Known limitations: the parent_python branch is broad and should be dropped, or the rule scoped to Langflow hosts only, if other Python services share the same telemetry. Teams that intentionally use Langflow's Python Code or shell components need a per-host or per-flow allowlist. Field names assume Sysmon for Linux or auditd normalized to the Sigma process_creation taxonomy, so EDR-specific mapping is required. The YARA rule is scoped to extracted HTTP bodies, WAF payload dumps, and staged tooling, not to live traffic or a filesystem sweep, and it will match the Langflow source tree itself, so exclude the application directory.
References