CVE-2026-10129: Verified Repro With Script Download
CVE-2026-10129: Langflow OSS SSRF and privilege escalation
CVE-2026-10129 is verified against the affected target. Vulnerability class: SSRF. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00240.
What Is CVE-2026-10129?
CVE-2026-10129 is a high-severity Server-Side Request Forgery vulnerability (CWE-918) in IBM Langflow OSS that bypasses SSRF protection and can be chained to escalate privileges. Pruva reproduced it (reproduction REPRO-2026-00240).
CVE-2026-10129 Severity & CVSS Score
CVE-2026-10129 is rated high severity, with a CVSS base score of 8.5 out of 10.
High — serious impact or readily exploitable. Prioritize remediation.
How to Reproduce CVE-2026-10129
pruva-verify REPRO-2026-00240 curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00240/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-10129
- reached the target end-to-end
- full exploit chain demonstrated
- on the real production code path
- high confidence
- the upstream fix blocks the same trigger
API Request component URL set to a public redirector that redirects to http://127.0.0.1:9999/admin-token with follow_redirects=true
- POST /api/v1/flows/ then POST /api/v1/build/{flow_id}/flow?event_delivery=direct executes API Request component
internal marker service listening on 127.0.0.1:9998
127.0.0.1 - "GET /marker HTTP/1.1" 200 -
127.0.0.1 - "GET /marker HTTP/1.1" 200 - Alternate same-root-cause redirect SSRF trigger through Langflow URLComponent: vulnerable lfx 0.4.6 validates the initial public URL then RecursiveUrlLoader follows a redirect to loopback; latest HEAD blocks the same redirect, so this is not a fixed-version bypass.
How the agent worked
Root Cause and Exploit Chain for CVE-2026-10129
CVE-2026-10129 is a Server-Side Request Forgery (SSRF) protection bypass in the Langflow OSS API Request component. When SSRF protection is enabled, the component validates the initial URL and pins DNS for that original host, but if follow_redirects=true it lets httpx automatically follow redirects without re-validating each redirect destination. A low-privileged Langflow flow author can submit a public URL that redirects to 127.0.0.1 or another internal address and receive the internal response through normal Langflow build events. In this run, the SSRF was chained on the real Langflow HTTP API surface to a privilege boundary effect: the low-privileged attacker retrieved a loopback-only internal admin bearer token, used it against Langflow's real admin-only user-management API, promoted their own account, and verified that the original attacker session became a superuser.
- Package/component affected:
lfx.components.data_source.api_request.APIRequestComponent, used by Langflow OSS as the "API Request" component. - Affected versions: IBM reports Langflow OSS 1.0.0 through 1.9.3 as affected. The reproduction installs
langflow==1.9.3, pinslangflow-base==0.9.3, and confirms the resolved vulnerable component stack islfx==0.4.6with no_follow_redirects_with_validationmethod. - Risk level and consequences: High. An authenticated low-privileged flow author can bypass SSRF protections intended to block loopback/private/link-local destinations. The bypass can expose internal admin panels, metadata services, credentials, or tokens. This run demonstrates a concrete privilege escalation consequence: an internal admin token was obtained through the API Request component and used to promote the attacker account to superuser.
Impact Parity
- Disclosed/claimed maximum impact: Privilege escalation through an SSRF protection bypass to an internal/admin endpoint.
- Reproduced impact from this run: Full production-surface privilege escalation. The script runs a real Langflow 1.9.3 server in multi-user mode, creates a real non-superuser attacker account through
POST /api/v1/users/, proves that the attacker receives403from the admin-onlyGET /api/v1/users/endpoint before exploitation, runs a real API Request flow throughPOST /api/v1/build/{flow_id}/flow, retrieves a loopback-only internal admin bearer token from the flow output, uses that stolen token against real Langflow admin APIs, promotes the attacker withPATCH /api/v1/users/{attacker_id}, and verifies the original attacker token now returnsis_superuser=truefromGET /api/v1/users/whoami. - Parity:
fullfor the ticket claim. The validated surface isapi_remote, and the observed impact isprivilege_escalation. - Not demonstrated: The proof does not attempt arbitrary code execution or cloud metadata compromise; it focuses on the claimed SSRF-to-privilege-escalation chain.
Root Cause
The vulnerable API Request component performs SSRF validation only for the initial user-supplied URL:
- It parses and validates the URL and resolves the initial hostname.
- It rejects private, loopback, link-local, and otherwise blocked IP ranges for that initial host.
- It creates an SSRF-protected transport that pins DNS for the original hostname.
- It calls the HTTP request layer with
follow_redirects=follow_redirects.
When follow_redirects=true, httpx handles 3xx redirects internally. For a redirect from a public host to http://127.0.0.1:9999/..., the original public URL passes validation, but the redirect destination is a new host. The vulnerable code does not call validate_and_resolve_url() again for that redirect target. As a result, the 127.0.0.1 destination is reached even though a direct request to the same URL is correctly blocked by SSRF protection.
The fixed code path present in repository HEAD / fixed api_request.py adds _follow_redirects_with_validation, which performs each request with redirects disabled, resolves the Location header, and re-runs SSRF validation before following every redirect hop. The reproduction's fixed-control swap uses that official HEAD api_request.py and observes the expected error: SSRF Protection: blocked redirect to http://127.0.0.1:9999/admin-token.
Reproduction Steps
- Script:
bundle/repro/reproduction_steps.sh. - What the script does:
- Reuses/creates
bundle/data/venvand installs the vulnerable stack:langflow==1.9.3,langflow-base==0.9.3,lfx==0.4.6. - Starts a real Langflow server on
127.0.0.1:7860in multi-user mode with SSRF protection enabled. - Configures a real Langflow superuser (
admin) and creates a real low-privileged user (attacker) via the public user API. - Starts a loopback-only internal admin/metadata service on
127.0.0.1:9999. This service reads the real Langflow admin user from SQLite and returns a real admin JWT signed with the same LangflowSECRET_KEY. - Generates a real Langflow flow containing the API Request component with a public
postman-echo.com/redirect-toURL that redirects tohttp://127.0.0.1:9999/admin-token. - Logs in as the low-privileged attacker, creates the flow through
POST /api/v1/flows/, executes it throughPOST /api/v1/build/{flow_id}/flow?event_delivery=direct, extracts the internal admin token from returned build events, and uses it against real admin-only Langflow endpoints to promote the attacker. - Runs a negative control showing a direct
http://127.0.0.1:9999/admin-tokenAPI Request is blocked by SSRF protection. - Runs a fixed control by swapping in the official fixed
api_request.py, showing redirect re-validation blocks the same public-to-loopback redirect.
- Reuses/creates
- Expected evidence of reproduction:
logs/exploit_summary.jsoncontainsattacker_is_superuser_before=false,lowpriv_admin_list_status_before=403,marker_found=true,stolen_token_is_superuser=true,stolen_token_admin_list_status=200,promote_attacker_status=200,attacker_is_superuser_after=true, andprivilege_escalation_observed=true.logs/direct_summary.jsoncontainsmarker_found=falseandssrf_blocked=true.logs/fixed_harness.jsoncontainsok=falseand a blocked-redirect SSRF protection error.bundle/repro/runtime_manifest.jsonrecordsentrypoint_kind="api_remote",service_started=true,healthcheck_passed=true, andtarget_path_reached=true.
Evidence
Primary evidence artifacts:
bundle/logs/reproduction_steps.log— high-level script log and final verdict.bundle/logs/exploit_summary.json— structured exploit and privilege-escalation evidence.bundle/logs/build_exploit.ndjson— raw Langflow build events showing the API Request component response from the loopback internal service.bundle/logs/direct_summary.jsonandbundle/logs/build_direct.ndjson— negative control showing direct loopback access is blocked.bundle/logs/fixed_harness.json— fixed-control evidence that redirect re-validation blocks the attack.bundle/logs/vuln_harness.json— secondary component-level evidence that the vulnerable component follows the redirect.bundle/logs/langflow_server.log— real Langflow server runtime log.bundle/logs/internal_admin.log— loopback internal admin service log.bundle/repro/runtime_manifest.json— runtime manifest written by the reproduction script.
Key excerpts from the successful run:
- Vulnerable stack confirmation:
installed: langflow 1.9.3 langflow-base 0.9.3 lfx 0.4.6andinstalled api_request.py has redirect re-validation fix? no. - Pre-exploit privilege boundary:
attacker_is_superuser_before: falseandlowpriv_admin_list_status_before: 403with bodyThe user doesn't have enough privileges. - SSRF bypass:
marker_found: true,reached_internal: true, andstolen_admin_token_found: trueinlogs/exploit_summary.json. - Admin-token use:
stolen_token_whoami_status: 200,stolen_token_username: admin,stolen_token_is_superuser: true, andstolen_token_admin_list_status: 200. - Privilege escalation:
promote_attacker_status: 200,attacker_is_superuser_after: true, andprivilege_escalation_observed: true. - Direct SSRF protection control:
direct_blocked=trueandSSRF Protection: Hostname 127.0.0.1 resolves to blocked IP address(es): 127.0.0.1. - Fixed control:
ValueError: SSRF Protection: blocked redirect to http://127.0.0.1:9999/admin-token.
Environment details captured by the script include the Langflow package versions, SQLite runtime, internal admin service endpoint, public redirector URL, and all runtime proof artifact paths in bundle/repro/runtime_manifest.json.
Recommendations / Next Steps
- Apply per-hop SSRF validation for all redirects. Each
Locationdestination should be resolved and checked against the same denylist/allowlist policy before the client connects. - Prefer manually handling redirects with
follow_redirects=False, validating the next URL before each hop, enforcing a maximum redirect count, and preserving DNS pinning semantics for every validated host. - Upgrade affected deployments to a Langflow/Langflow-base/LFX build containing
_follow_redirects_with_validationor an equivalent redirect-validation fix. - Add regression tests for public-to-loopback, public-to-private, public-to-link-local, and multi-hop redirect chains with SSRF protection enabled.
- Treat internal admin/metadata endpoints as sensitive. Avoid exposing reusable admin credentials on loopback-only HTTP services where possible, because SSRF bugs can convert loopback trust into remote privilege escalation.
Additional Notes
- Idempotency:
bundle/repro/reproduction_steps.shwas executed twice consecutively and exited successfully both times. - The primary proof uses the real Langflow HTTP API and real API Request component. The direct component harnesses are secondary controls only.
- The internal admin service is intentionally local to the reproduction environment and models the internal/admin endpoint class described by the ticket. The privilege escalation effect is real within the running Langflow product: a non-superuser account is promoted via Langflow's actual admin-only API after SSRF leaks an admin bearer token.
- The proof redacts JWT values in summaries where possible while preserving enough context to verify that an internal admin credential was retrieved and used.
Variant Analysis & Alternative Triggers for CVE-2026-10129
A distinct same-root-cause alternate trigger was found in Langflow's built-in URL data-source component (lfx.components.data_source.url.URLComponent). On the vulnerable langflow==1.9.3 / lfx==0.4.6 stack, URLComponent validates only the initial attacker-supplied URL and then delegates fetching to RecursiveUrlLoader, whose HTTP clients follow redirects without re-validating redirect destinations. A public URL that redirects to 127.0.0.1 therefore reaches a loopback-only marker service. This is a real alternate component entry point for the same redirect-SSRF class, but it is not a bypass of latest repository HEAD: the later fixed/latest URLComponent implementation blocks the redirect with per-hop SSRF revalidation.
Fix Coverage / Assumptions
The original parent fix for the reproduced ticket is commit 44d43dbeaf9ce76e7ddf8371317232d07e3f6336 (fix: re-validate redirects against SSRF protection in API Request component (#13394)). It covers src/lfx/src/lfx/components/data_source/api_request.py by replacing automatic httpx redirect following with manual redirect handling that calls validate_and_resolve_url() for every Location hop.
The fix invariant is: if the API Request component follows a redirect, each redirected URL must pass the same SSRF denylist and DNS-pinning checks as the original URL. That invariant is sound for the parent APIRequestComponent path.
What the parent fix does not cover by itself is other components that accept attacker-controlled URLs and use their own HTTP clients. The tested gap is URLComponent, which in lfx==0.4.6 uses RecursiveUrlLoader after only initial URL validation. Later repository commits separately fixed this component, especially 9a868386f2e35ad78041867b22e161665408a8d2 (fix(components): follow HTTP redirects in URL component with per-hop SSRF revalidation (#13572)). Latest HEAD tested here includes that URLComponent fix.
Variant / Alternate Trigger
Tested alternate path:
- Entrypoint kind:
component_harnessrepresenting Langflow flow execution of theURLdata-source component. - Component:
lfx.components.data_source.url.URLComponent. - Method:
fetch_url_contents(). - Attacker-controlled input:
urls=["https://postman-echo.com/redirect-to?url=http%3A%2F%2F127.0.0.1%3A9998%2Fmarker"]. - Internal target: loopback-only marker service on
127.0.0.1:9998/marker.
Vulnerable code path:
URLComponent.ensure_url()validates the initial public URL.URLComponent._create_loader()constructsRecursiveUrlLoader.URLComponent.fetch_url_contents()callsloader.load().RecursiveUrlLoader._get_child_links_recursive()callsrequests.get(...), which follows redirects by default.- The redirect to
http://127.0.0.1:9998/markeris fetched without Langflow re-validation.
Fixed/latest code path:
src/lfx/src/lfx/components/data_source/url.pyat HEAD315cc41b43c446bfb0e63d420ca55021f6f8987econtains_fetch_with_revalidated_redirects()and_build_http_client()and performs per-hop validation. The same redirect is blocked.Package/component affected:
lfx/ LangflowURLdata-source component.Affected version tested: installed reproduction stack
langflow==1.9.3,langflow-base==0.9.3,lfx==0.4.6.Fixed/latest version tested: repository HEAD
315cc41b43c446bfb0e63d420ca55021f6f8987e, by overlaying HEADurl.pyandssrf_transport.pyinto the repro venv without changing the repository checkout.Risk: high in affected deployments with untrusted or low-privileged flow authors. The component can reach loopback/private/link-local services despite SSRF protection, enabling internal data exposure and potential privilege escalation when internal credentials or admin APIs are reachable.
Impact Parity
- Parent disclosed/claimed maximum impact: SSRF protection bypass chained to privilege escalation.
- Reproduced variant impact: internal loopback resource disclosure through a distinct component. The proof retrieves a loopback-only marker JSON containing
INTERNAL_ADMIN_TOKEN_CVE_2026_10129throughURLComponentoutput. - Parity:
partial. The same SSRF primitive is reproduced through a distinct component, but this variant script does not repeat the full admin-token promotion chain from the parent reproduction. - Not demonstrated: full remote Langflow API flow creation/build for
URLComponent, cloud metadata compromise, or final privilege escalation from this alternate component. The component harness is sufficient to prove the vulnerable server-side sink and fixed/latest blocking behavior.
Root Cause
The root cause is the same redirect-validation error as the parent: SSRF validation was applied to only the original user-controlled URL while the actual HTTP client could follow a redirect to a new, unvalidated host.
For the parent, the downstream client was httpx inside APIRequestComponent. For the variant, the downstream client was RecursiveUrlLoader (requests/aiohttp) used by URLComponent. In both cases, the security boundary is crossed when an authenticated flow author supplies a URL to a server-side Langflow component while SSRF protection is expected to prevent loopback/internal network access.
Known fixes:
- Parent API Request fix:
44d43dbeaf9ce76e7ddf8371317232d07e3f6336. - URLComponent redirect fix:
9a868386f2e35ad78041867b22e161665408a8d2. - Latest tested HEAD:
315cc41b43c446bfb0e63d420ca55021f6f8987e.
Reproduction Steps
- Run
bundle/vuln_variant/reproduction_steps.sh. - The script:
- Uses the successful repro virtualenv (
bundle/data/venv) containing vulnerablelfx==0.4.6. - Starts a loopback-only marker service on
127.0.0.1:9998. - Runs
bundle/vuln_variant/run_url_component.pyagainst vulnerable installedURLComponentwith a public redirector URL. - Confirms the vulnerable component returns the loopback marker.
- Creates an isolated Python overlay containing fixed/latest
URLComponentcopied from repository HEAD, without mutating the repro checkout. - Runs the same input against the fixed/latest overlay.
- Confirms fixed/latest blocks the redirect and does not return the marker.
- Uses the successful repro virtualenv (
- Expected script exit:
1, because the variant is an alternate vulnerable-version trigger but not a HEAD bypass. The script ran twice successfully and produced this expected exit code both times.
Evidence
Primary evidence:
bundle/logs/vuln_variant/reproduction_steps.log— high-level run log and verdict.bundle/logs/vuln_variant/url_component_vulnerable.json— vulnerable URLComponent reached internal marker.bundle/logs/vuln_variant/url_component_fixed_latest.json— fixed/latest URLComponent blocked the same redirect.bundle/vuln_variant/runtime_manifest.json— runtime identity and evidence list.bundle/logs/vuln_variant/latest_version.txtandbundle/logs/vuln_variant/latest_git_identity.txt— exact fixed/latest source identity.
Key observed facts:
- Vulnerable log reports
variant_reached_internal=true,marker_in_output=true,lfx_version=0.4.6, andhas_redirect_revalidation_method=false. - Fixed/latest log reports
variant_reached_internal=false,has_redirect_revalidation_method=true, and an error blockinghttp://127.0.0.1:9998/markerbecause it resolves to127.0.0.1. - Submitted vulnerable tag
v1.9.3resolves to322e4908b931a3efe2d65c6a7ad5ec373c5a5e1d. - Latest tested source resolves to
315cc41b43c446bfb0e63d420ca55021f6f8987e.
Recommendations / Next Steps
- Do not ship only the API Request redirect fix as a product-wide SSRF fix. Include URLComponent redirect revalidation (
9a868386f2...) or equivalent coverage. - Centralize safe HTTP helpers for all attacker-controlled URL inputs. Components should not call
requests.get,httpxwith automatic redirects,aiohttp, or third-party loaders on user URLs unless redirect handling re-enters Langflow SSRF validation per hop. - Add regression tests for every built-in component field that accepts a URL or base URL, using both direct internal URLs and public-to-internal redirects.
- Prefer deny-by-default helper APIs that reject
follow_redirects=Trueunless the helper owns per-hop validation.
Additional Notes
- The target
SECURITY.mdwas reviewed and does not exclude SSRF. TheRecursiveUrlLoaderdocumentation explicitly warns that crawlers can create SSRF risk; in Langflow this risk crosses a server-side trust boundary because flow authors control component inputs. - The repository checkout was not changed. Fixed/latest testing used a temporary overlay under
bundle/vuln_variant/fixed_overlay. - Idempotency was confirmed:
bundle/vuln_variant/reproduction_steps.shwas run twice; both runs completed and returned the expected non-bypass exit code (1).
CVE-2026-10129 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
cd /data/pruva/project-cache/688af86e-dc4c-4d20-bb02-ccdf8da2c7d0/repo && git log --oneline -15 && echo "---HEAD---" && git rev-parse HEAD && echo "---TAGS---" && git tag | grep -E "1\.9|1\.8" | head -40{"cwd":"/data/pruva/runs/50e1d94c-35c4-431a-b622-d84ef4d2d9ee","duration_ms":5,"exit_code":0,"stderr":"","stdout":"315cc41b43 ci: surface nightly Group 3 stall via 90s pytest thread-timeout (#13938)\nab8508db73 fix(ci): consolidate recent nightly CI fixes\n26dc6fd3bc chore: update test durations (#13888)\na277209fe4 ci: push nightly .devX Docker images to langflowai/langflow and fix db-migration-validation image references (#13836)\n4da60c4b12 fix: keep nightly prerelease wheels explicit (#13817)\n7db38d1abb fix: unblock nightly bundle install resolution\n1a60220497 Merge remote-tracking branch 'origin/release-1.10.1'\na66b75ac26 chore: require bumped sdk for lfx release\nf85901e49d chore: bump sdk release version\n4c8fb6b954 fix: gate release rc setup for stable releases\n7db4bcb890 fix: degrade gracefully when caching unpicklable values in RedisCache (#13781)\n8c98cdf5cc fix(security): block socket/urllib network egress in component code scanner (#13784)\nf58914bc84 fix: release candidate version selection (#13776)\n2302ef9931 fix(component): reconnect stale cached SQL database connections on SQL Database component (#13733)\n408b737980 fix(agents): stop leaking LangChain chain ma… [truncated]Artifacts and Evidence for CVE-2026-10129
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-10129
FAQ: CVE-2026-10129
How does the CVE-2026-10129 SSRF-to-privilege-escalation chain work?
Which Langflow versions are affected by CVE-2026-10129?
langflow==1.9.3, pinned to langflow-base==0.9.3, and confirms the resolved vulnerable component stack is lfx==0.4.6 with no _follow_redirects_with_validation method.How severe is CVE-2026-10129?
How can I reproduce CVE-2026-10129?
References for CVE-2026-10129
Authoritative sources for CVE-2026-10129 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.