# Variant Patch Analysis — CVE-2026-10129

## Scope and threat model

- Target: `langflow/langflow` / `lfx` components reachable from Langflow flows.
- Security policy reviewed: `SECURITY.md` in repository HEAD. It directs vulnerability reports to IBM HackerOne and does not exclude SSRF or flow-component network access from scope.
- LangChain's `RecursiveUrlLoader` security note was also considered because the variant path used that loader in vulnerable `URLComponent`: it warns crawlers can cause SSRF and that `prevent_outside` mitigates but does not eliminate the risk. In Langflow, the trust boundary is different from a local user intentionally crawling a site: an authenticated flow author supplies component inputs to a server-side Langflow runtime with SSRF protection enabled, so reaching loopback/internal services is in scope.

## Parent fix: API Request redirect re-validation

Primary patch commit identified in the repository: `44d43dbeaf9ce76e7ddf8371317232d07e3f6336` (`fix: re-validate redirects against SSRF protection in API Request component (#13394)`). It changes `src/lfx/src/lfx/components/data_source/api_request.py`.

The fix changes the API Request component from this vulnerable pattern:

1. Normalize and validate only the original user URL.
2. Resolve and pin the original hostname's IPs.
3. Call `httpx` with `follow_redirects=follow_redirects`.

Into this fixed pattern:

1. Validate and DNS-pin the original URL.
2. If SSRF protection and `follow_redirects` are enabled, disable automatic redirect following.
3. Add `_follow_redirects_with_validation()` and related helpers.
4. Resolve relative `Location` headers with `urljoin`.
5. Re-run `validate_and_resolve_url()` for each redirect hop.
6. Build a new SSRF-protected client for each validated redirect target.
7. Strip sensitive headers when the redirect crosses origins.

The fix assumption for the parent ticket is that the API Request component is the SSRF sink. That assumption is correct for the disclosed proof path, but too narrow for Langflow's component ecosystem: other components also accept server-side URLs and can perform HTTP fetches.

## Variant candidate found: URLComponent redirect path

A distinct candidate exists in `src/lfx/src/lfx/components/data_source/url.py` (`URLComponent`, displayed as the `URL` data source component). In affected `lfx==0.4.6` installed by the original reproduction, this component:

1. Exposes attacker-controlled `urls` as a flow input.
2. Runs `ensure_url()` which calls `validate_url_for_ssrf()` only for the initial URL.
3. Creates `RecursiveUrlLoader(url=..., use_async=..., prevent_outside=...)`.
4. Calls `loader.load()`.
5. `RecursiveUrlLoader` then calls `requests.get(...)` in the synchronous path and `aiohttp.ClientSession.get(...)` in the async path. Both follow redirects by default, and neither re-enters Langflow's SSRF validator for redirect destinations.

This is the same underlying redirect-SSRF root cause as the parent: validating only the original public URL while a downstream HTTP client automatically follows a redirect to a private/loopback/link-local target.

Runtime evidence in this run confirms the synchronous URLComponent path on the vulnerable stack:

- `bundle/logs/vuln_variant/url_component_vulnerable.json`
- `variant_reached_internal=true`
- Component source: installed `.../site-packages/lfx/components/data_source/url.py`
- `has_redirect_revalidation_method=false`
- `lfx_version=0.4.6`
- Returned data contains `INTERNAL_ADMIN_TOKEN_CVE_2026_10129` from `127.0.0.1:9998/marker` after starting from a public `postman-echo.com/redirect-to` URL.

This is not merely a renamed API Request trigger. It is a different built-in component and implementation stack (`URLComponent` + `RecursiveUrlLoader` + `requests/aiohttp`) from the parent (`APIRequestComponent` + `httpx`).

## Fixed/latest behavior for the candidate

The repository later added URLComponent-specific redirect validation. Relevant commits:

- `183cdd82cf...` — `fix: add ssrf protection to url component (#13488)`, adding DNS pinning/SSRF protection to `URLComponent`.
- `9a868386f2e35ad78041867b22e161665408a8d2` — `fix(components): follow HTTP redirects in URL component with per-hop SSRF revalidation (#13572)`, specifically addressing redirects in `src/lfx/src/lfx/components/data_source/url.py`.
- HEAD tested in this run: `315cc41b43c446bfb0e63d420ca55021f6f8987e`.

The fixed/latest `URLComponent` no longer delegates redirect following to `RecursiveUrlLoader`. It uses its own HTTP fetching logic with `httpx`, `_build_http_client()`, `_fetch_with_revalidated_redirects()`, and per-hop calls back to `ensure_url()` / `validate_and_resolve_url()`.

Runtime evidence in this run confirms fixed/latest behavior:

- `bundle/logs/vuln_variant/url_component_fixed_latest.json`
- Source: `bundle/vuln_variant/fixed_overlay/lfx/components/data_source/url.py`, copied from repository HEAD without changing the repro checkout.
- `has_redirect_revalidation_method=true`
- `fetch_url_contents_is_async=true`
- `variant_reached_internal=false`
- Error: `SSRF Protection: blocked redirect to http://127.0.0.1:9998/marker: Hostname 127.0.0.1 resolves to blocked IP address(es): 127.0.0.1`.

Therefore, the URLComponent path is a confirmed alternate same-root-cause trigger in the vulnerable release, but it is not a bypass of repository HEAD/latest. It was closed by a separate URLComponent fix after the parent API Request fix.

## Code paths and inputs not covered by only the parent patch

The parent `api_request.py` patch does not change `URLComponent`, `RecursiveUrlLoader`, or other components that make their own HTTP requests. If a release cherry-picked only commit `44d43dbeaf...` and omitted the later URLComponent redirect fix `9a868386f2...`, then the API Request exploit would be blocked but the URLComponent redirect path would remain exploitable.

Other reviewed HTTP call sites include data-source/search/tool components using `requests.get`, `httpx.Client`, or provider SDKs. Many are fixed to constant provider endpoints or later moved through shared SSRF helpers (`ssrf_httpx.py`, `ssrf_requests.py`). No additional runtime-confirmed bypass of HEAD was found in this bounded pass.

## Completeness assessment

- Vulnerable 1.9.3 / `lfx==0.4.6`: incomplete SSRF coverage; both API Request and URLComponent redirect paths can reach loopback/internal endpoints.
- Parent API Request fix alone (`44d43dbeaf...`): complete for the tested API Request redirect path, but insufficient as a product-wide SSRF fix because URLComponent is a distinct network-fetching entry point.
- Latest HEAD (`315cc41b...`): covers both the parent API Request redirect path and the URLComponent redirect path tested here. No fixed/latest bypass was confirmed.

Recommendation: the Coding agent should ensure any shipped fix includes component-wide redirect SSRF protections, not only the API Request patch. At minimum, include the URLComponent per-hop revalidation from `9a868386f2...` and shared guard rails for `requests`/`httpx` helpers so future components cannot opt into automatic redirects on attacker-controlled URLs without per-hop SSRF validation.
