Finding

Langflow's default auto-login issued a year-long superuser token, and its validator ran submitted code. We rebuilt the chain and the 1.10.1 fix.

By Riftweld Labs

Findings4 min read

In this finding

Two defaults, one chain.

CVE-2026-9198 is a CVSS 9.8 unauthenticated remote code execution in Langflow 1.0.0 through 1.10.0. It was fixed in 1.10.1 and added to CISA's Known Exploited Vulnerabilities catalogue on 4 August 2026.

The vulnerability was not one faulty line. It was the interaction between two defaults. On deployments with LANGFLOW_AUTO_LOGIN=true — the default — GET /api/v1/auto_login returned a superuser JWT with no credentials. In affected versions that token lasted 365 days. Separately, POST /api/v1/validate/code compiled and ran submitted function definitions as part of validation, including decorators and default arguments. A crafted default argument executed a shell command, and the output came back in the HTTP response.

Neither half is enough on its own. Together they turn a single unauthenticated request into command execution on the host.

What we reproduced.

This is an independent reconstruction, not the original discovery. The vulnerability was disclosed publicly by IBM and CISA. Our research window was 17–18 August 2026, and all exploitation ran against lab instances we own.

Using the public record, we rebuilt the complete chain on langflowai/langflow:1.10.0:

  1. 01Get the token

    GET /api/v1/auto_login returned 200 with a superuser JWT that had a 365-day expiry and no credential check.

  2. 02Reach the execution sink

    POST /api/v1/validate/code with that token and a crafted function definition returned the command output in the errors array: uid=1000(user) gid=0(root) groups=0(root).

  3. 03Write to the host

    The same payload with a file-write command created a marker file inside the container and returned the hostname. The chain was complete.

We then ran the same steps against 1.10.1. The control returned short-lived tokens from the auto-login endpoint and empty errors from the validator. Both halves of the chain were closed.

How far the exposure reached.

We enumerated internet-facing instances passively through Shodan, then made one benign unauthenticated GET /api/v1/version per host. No exploitation was attempted against any third-party system.

The sweep collected 1,768 host:port matches. Version triage found 244 hosts below 1.10.1, seven patched hosts and 1,317 unresolved hosts. The vulnerable figure is a lower bound: most unresolved hosts timed out or sat behind a firewall and could not be versioned.

The exposed pool was almost entirely IP-literal cloud VMs — 242 of 244 had no identifying domain, certificate or public contact record. Direct owner notification was not possible, so we went through hosting-provider abuse desks. Eight consolidated reports covered 238 hosts, led by 219 on AWS. Two providers responded substantively: Hetzner confirmed the operator's remediation statement and locked the exposed IP, and AWS acknowledged the report and opened an investigation.

One detail from that operator statement matters. Their instance ran a vulnerable version, but auto-login was disabled, so the unauthenticated chain did not apply to that deployment. Version exposure is not the same as exploitability.

In the wild, KEVIntel telemetry recorded 793 exploitation attempts from 315 source IPs across 44 countries between 6 July and 17 August 2026. The requests followed the chain directly: auto_login, then validate/code. Exploitation began before the CVE was published, and a public nuclei template followed on 29 July.

What changed in 1.10.1.

The fix addresses both halves. Auto-login now issues short-lived access tokens with refresh tokens instead of a year-long superuser key. The code-validation endpoint no longer executes submitted code; the same payload returns empty errors.

The relevant upstream commits are e7c33dba for the validator and 744c36e5 for auto-login hardening, merged as langflow-ai/langflow#13696 and #13699.

The pattern is familiar. Langflow has shipped default-insecure behaviour before, including CVE-2025-3248, and this class of bug keeps reaching KEV because the defaults do the work for the attacker.

What this does not prove.

  • We did not discover this vulnerability. IBM and CISA published first. This is a post-disclosure reconstruction.
  • Exposure is not compromise. A vulnerable version tells you the route may exist. It does not show that anyone used it, or that a particular host was accessed.
  • The chain depends on configuration. The unauthenticated path requires auto-login to be enabled. We found at least one vulnerable-version deployment where it was not.
  • The exposure count is a lower bound. More than a thousand hosts could not be versioned at the time of the sweep.
  • We did not test third-party systems. All exploitation was confined to our lab. Field findings came from passive enumeration and one benign version request per host.

Evidence.

Adversary simulation

Prove the route before someone else does.

We reproduce the path an attacker would take, show the impact with evidence, then retest after the fix.