Someone left the master key under the doormat and a loaded code compiler on the kitchen table
CVE-2026-9198 is a chained unauthenticated remote code execution vulnerability in IBM Langflow OSS versions 1.0.0 through 1.10.0. The platform ships with LANGFLOW_AUTO_LOGIN=true by default, which causes the /api/v1/auto_login endpoint to mint a SUPERUSER-scoped bearer token to *any* network caller — no credentials required. An attacker then passes that token to /api/v1/validate/code, an endpoint that runs attacker-supplied Python through exec() (Python evaluates decorators, default arguments, and annotations at function-definition time, so the attacker's payload runs during 'validation'). The chain composes two sub-vulnerabilities (CVE-2026-9103 for the auth bypass, CVE-2026-8481 for the code injection) into a single two-request, zero-click, zero-auth RCE. Fixed in version 1.10.1, released on disclosure day (2026-07-17); version 1.10.2+ recommended because it addresses additional issues.
The vendor CVSS of 9.8 CRITICAL is accurate and, if anything, understates the operational blast radius. The CVSS vector (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) correctly captures the trivial, unauthenticated, remotely exploitable nature. What CVSS cannot encode is that Langflow is an AI workflow orchestration platform that aggregates LLM provider API keys, database connection strings, OAuth secrets, cloud credentials, and integration tokens — so 'Confidentiality: High' actually means 'every credential the platform ever touched.' Bitbison's honeypot research recorded a median time-to-first-exploitation of 15 hours after exposure, with 45% of attackers immediately hunting for stored credentials. CISA validated the threat by adding CVE-2026-9198 to KEV on 2026-08-04 with an emergency 3-day federal deadline. The vendor severity matches reality: this is as bad as the number says.
5 steps from start to impact.
Discover internet-exposed Langflow instance
/api/v1/ routes) or port 7860. Langflow is frequently deployed as shadow IT — data science prototyping on cloud VMs, Helm-charted containers in dev clusters, or business-unit accounts outside central IT oversight. Many instances sit on public IPs with no WAF or reverse-proxy authentication layer.- Langflow instance reachable over the network (internet or internal)
- Instances behind corporate VPN or segmented networks are not directly reachable
- Organizations with mature asset inventory may catch rogue deployments
Mint SUPERUSER token via auto_login
/api/v1/auto_login. Because the default configuration sets LANGFLOW_AUTO_LOGIN=true, the endpoint returns a valid SUPERUSER bearer token in the JSON response. No credentials, no brute force, no session hijacking — the server simply hands out the highest-privilege token to anyone who asks. This is the authentication bypass component (CVE-2026-9103).- LANGFLOW_AUTO_LOGIN=true (the default)
- The /api/v1/auto_login endpoint is reachable
- If an operator has explicitly set LANGFLOW_AUTO_LOGIN=false, this step fails entirely
- A WAF rule blocking unauthenticated requests to /api/v1/auto_login would stop the chain
Execute arbitrary Python via validate/code
/api/v1/validate/code containing malicious Python source. The endpoint calls exec() on the submitted code ostensibly to 'validate' it. Python evaluates decorator expressions, default argument values, and type annotations at function-definition time, so the attacker embeds their payload in these positions. The code runs in-process with the full privileges of the Langflow server process — typically a container root or an unprivileged Linux user with access to all environment variables, mounted secrets, and network interfaces. This is the code injection component (CVE-2026-8481). Weaponized tooling: public PoCs by rmhowe425 and ywh-jfellus on GitHub; also cataloged in SecureWithUmer/CVE-2026-PoCs.- Valid SUPERUSER token (obtained in step 2)
- The /api/v1/validate/code endpoint is reachable
- Network segmentation preventing the attacker from reaching the API after obtaining the token (unlikely if step 1 succeeded)
- Runtime application security (RASP) blocking exec() calls on user-supplied input — rare in Python deployments
Harvest credentials and establish persistence
- Successful code execution from step 3
- Credentials stored in environment variables or accessible files
- Credential rotation and vault-based secret injection (never in env vars) limits what can be harvested
- Container isolation and read-only filesystems can impede persistence
- EDR on the host may detect implant deployment
Lateral movement via harvested credentials
- Credentials harvested in step 4 are valid and unrotated
- Downstream systems accessible from attacker's position
- MFA on downstream services blocks credential reuse for interactive access
- Network segmentation between Langflow and production systems
- Short-lived or scoped credentials limit lateral movement window
- EDR/antivirus on the host — the exploit is pure Python executed within the Langflow interpreter process via exec(). There is no binary drop, no shellcode, no file write in the initial exploitation phase. EDR may catch *post-exploitation* (cryptominer binaries, C2 implants) but will not prevent the initial code execution.
- Network-level IDS/IPS with generic signatures — the exploit payload is a standard HTTPS POST with JSON containing Python source code. Without Langflow-specific signatures matching the /api/v1/validate/code + decorator/default-arg pattern, generic IDS will not flag it.
- Rate limiting alone — the full exploit is two requests. Rate limiting would need to be set so aggressively it would block legitimate users.
- Upgrading only to 1.10.1 without credential rotation — if the instance was ever exposed while vulnerable, credentials are already compromised. Patching stops future exploitation but does not revoke exfiltrated secrets.
The supporting signals.
| In-the-wild exploitation | Confirmed active. ~650 exploitation attempts from 244 unique IPs across 41 countries observed between 2026-07-06 and 2026-08-04 (pre-KEV). Bitbison honeypot research recorded 320 exploit requests from 31 IPs with 67% successful code execution rate and median 15-hour time-to-exploitation. Post-exploit activity: 45% credential harvesting, 29% API key exfiltration, 13% cryptomining (XMRig), 6.5% implant deployment (AdaptixC2 Gopher, Mirai-like bot). |
|---|---|
| CISA KEV status | Listed 2026-08-04. Federal remediation deadline: 2026-08-07 (3-day emergency window under BOD 26-04). One of three CVEs added in that batch. CISA alert |
| Proof-of-concept availability | Multiple public PoCs. GitHub repos: rmhowe425/PoC-CVE-2026-9198, ywh-jfellus/CVE-2026-9198 (includes Docker lab with vulnerable 1.10.0 and patched 1.10.1), 0xgh057r3c0n/CVE-2026-9198. Also cataloged in SecureWithUmer/CVE-2026-PoCs. All are weaponized Python scripts automating the full chain. |
| EPSS | 0.28658 (top 1% of all CVEs). This is an exceptionally high EPSS score, reflecting the trivial exploitability, default-vulnerable configuration, public PoCs, and confirmed active exploitation. |
| CVSS vector interpretation | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (9.8 Critical). Every base metric is at maximum severity except Scope (Unchanged). Network-accessible, zero complexity, zero privilege, zero interaction, full CIA impact. The Scope:Unchanged is arguably conservative given the credential-aggregator blast radius. |
| Affected versions | IBM Langflow OSS 1.0.0 through 1.10.0 inclusive. The vulnerability chain combines CVE-2026-9103 (auto_login auth bypass) and CVE-2026-8481 (validate/code exec injection). The default LANGFLOW_AUTO_LOGIN=true setting enables the chain on every fresh install. |
| Fixed versions | 1.10.1 (released 2026-07-17, same day as disclosure). 1.10.2+ recommended — addresses additional security issues. Fix disables auto-login by default and adds input sanitization to the validate/code endpoint. See langflow-ai/langflow PR #14993. |
| Scanning & exposure | Langflow instances discoverable via Shodan/FOFA/Censys on default port 7860 and via React SPA fingerprints. Frequently deployed as shadow IT in data science environments, developer cloud accounts, and Kubernetes clusters outside formal asset inventory. GreyNoise has tagged Langflow-targeting scan traffic. |
| Disclosure timeline | Pre-disclosure exploitation observed 2026-07-06. IBM advisory and patch published 2026-07-17. Public PoCs appeared ~late July 2026. CISA KEV listing 2026-08-04. Federal deadline 2026-08-07. |
| Reporting researcher / org | Credited to IBM X-Force as CNA. Honeypot research and post-exploitation analysis by Bitbison (bitbison.io). Blast radius analysis by ComplianceHub, isMalicious, and Cloud Security Alliance (CSA research note). |
Sources.
- NVD — CVE-2026-9198 Detail
- CISA KEV Alert — 2026-08-04
- Bitbison — Langflow RCE: 34 minutes to server compromise
- ComplianceHub — Langflow CVE-2026-9198 Credential Blast Radius
- isMalicious — CVE-2026-9198 AI Agent Control Plane RCE
- Cloud Security Alliance — Langflow Auto-Login Bypass Research Note
- ywh-jfellus/CVE-2026-9198 — PoC with Docker lab
- langflow-ai/langflow PR #14993 — Disable auto-login by default
Why this verdict
- Zero-auth, two-request chain on default config: The exploit requires no credentials, no user interaction, and works against every default Langflow installation. The
LANGFLOW_AUTO_LOGIN=truedefault means the vulnerable population is *every unpatched install that hasn't explicitly hardened this setting* — not a subset, not an edge case, the entire installed base. - Active exploitation with observed credential harvesting: This is not theoretical. CISA KEV-listed with a 3-day emergency deadline. Bitbison recorded 67% successful exploitation rate in honeypots with median 15-hour dwell-to-first-exploit. Attackers are actively weaponizing this for credential theft, cryptomining, and C2 implant deployment.
- Multiple weaponized public PoCs: At least three GitHub repositories contain turnkey Python exploit scripts. The exploit is trivial — two HTTP requests — meaning any script kiddie with curl can replicate it. EPSS at 0.28658 (top 1%) reflects this reality.
- Role multiplier: Langflow is an AI workflow orchestration platform that functions as a credential aggregator by design. It holds LLM provider API keys, database connection strings, OAuth client secrets, cloud IAM credentials, and SaaS integration tokens. This places it squarely in the *CI/CD + secrets manager* high-value-role category. A compromised Langflow instance yields the credential set for every downstream system wired into its workflows. The blast radius is not host-level — it is tenant-to-fleet scale, equivalent to compromising a Jenkins controller or HashiCorp Vault instance. Per the high-value-role floor rule: the affected component IS canonically a credential aggregator (≥10% of installs hold production secrets by design), and the chain succeeds trivially in that role → verdict floor is CRITICAL.
- Negligible friction in real deployments: The only meaningful friction point is network reachability. However, Langflow is commonly deployed as shadow IT on public cloud IPs, and the default config is vulnerable. There is no configuration prerequisite the attacker must overcome, no authentication to bypass (the bypass IS the vuln), and no user interaction required. The friction that exists (VPN, segmentation) is deployment-specific and does not narrow the vulnerable population below the floor threshold.
Why not higher?
CVSS 9.8 is already near-maximum. The only metric not at ceiling is Scope (Unchanged), which could theoretically be argued as Changed given the credential-aggregator blast radius into downstream systems. However, the CVSS 3.1 specification defines Scope: Changed narrowly around sandbox escapes and cross-component privilege changes at the vulnerability level, not operational blast radius. The 9.8 score is the correct ceiling for this vector.
Why not lower?
Every downgrade argument fails the friction audit. 'Requires network access' — true of every network vulnerability; Langflow is internet-exposed in many deployments and the default config is vulnerable. 'Only affects Langflow users' — Langflow is a rapidly growing AI orchestration platform adopted by enterprises for production AI workflows; it is not niche. 'Shadow IT instances are few' — shadow IT is *harder* to patch, not less dangerous. The KEV listing, active exploitation, trivial exploit complexity, default-vulnerable configuration, credential-aggregator blast radius, and EPSS top-1% score collectively make any reduction below CRITICAL indefensible.
Crowdsourced verification payload.
Run this script from any machine with network access to the target Langflow instance. It checks whether the /api/v1/auto_login endpoint hands out a superuser token without authentication — the critical first step of the CVE-2026-9198 chain. Usage: bash check_cve_2026_9198.sh https://langflow.example.com:7860 — no special privileges required, just curl and jq.
#!/usr/bin/env bash
# check_cve_2026_9198.sh — CVE-2026-9198 Langflow auto_login auth bypass detector
# Tests whether /api/v1/auto_login mints a SUPERUSER token without credentials.
# Exit codes: 0 = VULNERABLE, 1 = PATCHED, 2 = UNKNOWN
set -euo pipefail
if [ $# -lt 1 ]; then
echo "Usage: $0 <LANGFLOW_BASE_URL>"
echo "Example: $0 https://langflow.example.com:7860"
exit 2
fi
BASE_URL="${1%/}"
ENDPOINT="${BASE_URL}/api/v1/auto_login"
echo "[*] Testing CVE-2026-9198 against: ${BASE_URL}"
echo "[*] Endpoint: ${ENDPOINT}"
echo ""
# Step 1: Attempt unauthenticated auto_login
HTTP_RESPONSE=$(curl -sk -w "\n%{http_code}" -X POST "${ENDPOINT}" \
-H "Content-Type: application/json" \
-d '{}' 2>/dev/null) || {
echo "[!] UNKNOWN — Could not reach ${ENDPOINT}"
echo " Verify the URL and network connectivity."
exit 2
}
HTTP_BODY=$(echo "$HTTP_RESPONSE" | sed '$d')
HTTP_CODE=$(echo "$HTTP_RESPONSE" | tail -1)
echo "[*] HTTP status code: ${HTTP_CODE}"
if [ "$HTTP_CODE" -eq 200 ]; then
# Check if response contains an access token
if echo "$HTTP_BODY" | grep -qi '"access_token"'; then
TOKEN=$(echo "$HTTP_BODY" | python3 -c "import sys,json; print(json.load(sys.stdin).get('access_token',''))" 2>/dev/null || echo "")
if [ -n "$TOKEN" ]; then
echo ""
echo "[!] VULNERABLE — CVE-2026-9198"
echo " auto_login returned a token without authentication."
echo " Token prefix: ${TOKEN:0:20}..."
echo ""
echo " LANGFLOW_AUTO_LOGIN is likely set to true (the insecure default)."
echo " Immediate action: set LANGFLOW_AUTO_LOGIN=false and upgrade to 1.10.2+."
exit 0
fi
fi
echo ""
echo "[?] UNKNOWN — Got HTTP 200 but no access_token in response."
echo " Manual review recommended."
exit 2
elif [ "$HTTP_CODE" -eq 403 ] || [ "$HTTP_CODE" -eq 401 ]; then
echo ""
echo "[+] PATCHED — auto_login returned ${HTTP_CODE} (authentication required)."
echo " LANGFLOW_AUTO_LOGIN appears to be disabled or the endpoint is secured."
exit 1
elif [ "$HTTP_CODE" -eq 404 ]; then
echo ""
echo "[+] PATCHED — auto_login endpoint not found (404)."
echo " Endpoint may have been removed in a newer version."
exit 1
else
echo ""
echo "[?] UNKNOWN — Unexpected HTTP status ${HTTP_CODE}."
echo " Response body (first 500 chars):"
echo "$HTTP_BODY" | head -c 500
exit 2
fi