CVE-2026-48710 - Starlette BadHost request.url path bypass

Starlette before 1.0.1 did not validate the HTTP Host header before using it to reconstruct request.url. Because ASGI routing uses the raw request path while application code may read request.url.path, a malformed host value can make those two paths disagree. Middleware or endpoints that protect sensitive routes by checking request.url.path can therefore apply the wrong policy.

This recipe is especially relevant for FastAPI, Starlette, MCP servers, LLM gateways, model-serving control planes, and internal agent APIs that use Starlette directly or transitively.

When to use it

Use this recipe when a Starlette, FastAPI, MCP server, LLM gateway, model-serving control plane, or internal agent API makes security decisions from request.url.path, reconstructed URLs, or Host-header-derived request objects. It is built for source-code remediation, host-header validation, route identity review, and evidence that malformed hosts cannot bypass path-based security checks.

Inputs

  • Starlette version, framework dependency tree, host validation middleware, proxy/header config, route inventory, and deployment ingress.
  • Source paths that use request.url, request.url.path, url_for, host headers, path-based auth, middleware gates, or route identity checks.
  • Regression fixtures for malformed Host headers, raw ASGI paths, sensitive routes, denied unauthenticated users, and allowed valid requests.
  • Boundary evidence: protected routes, proxy trust chain, tenant/admin/API paths, logs, and rollout owner.

Affected versions

  • Vulnerable: starlette <=1.0.0
  • Fixed: starlette 1.0.1+
  • Affected pattern: security-sensitive code that bases authorization, tenant routing, callback validation, request signing, webhook gating, or admin-route blocking on request.url or request.url.path
  • Mitigated pattern: a trusted proxy rejects malformed Host values before forwarding and application authorization uses raw ASGI scope["path"], route identity, or framework route metadata instead of reconstructed URLs.

Indicator-of-exposure

  • The repository depends on Starlette directly or through FastAPI, MCP server frameworks, LLM gateway packages, ASGI middleware, or model-serving APIs.
  • The resolved starlette version is <=1.0.0.
  • Middleware or route code uses request.url, request.url.path, str(request.url), request.base_url, url_for, or reconstructed URL text for security-sensitive decisions.
  • Proxy, ingress, WAF, or load-balancer config does not reject malformed Host header values before forwarding to the ASGI app.
  • Agent tools, MCP endpoints, admin APIs, callback routes, OAuth redirects, or model-provider proxy routes are reachable from untrusted networks.

Quick checks:

rg -n "starlette|fastapi|request\\.url|request\\.base_url|url_for\\(|scope\\[['\"]path['\"]\\]|Host\\(|TrustedHostMiddleware|X-Forwarded-Host|Forwarded" .
python -m pip show starlette fastapi
python -m pip freeze | rg '^(starlette|fastapi)=='

Windows:

rg -n "starlette|fastapi|request\\.url|request\\.base_url|url_for\\(|scope\\[['\"]path['\"]\\]|Host\\(|TrustedHostMiddleware|X-Forwarded-Host|Forwarded" .
python -m pip show starlette fastapi
python -m pip freeze | rg '^(starlette|fastapi)=='

Do not run public scanners against production services or send malformed Host headers to live systems during repository triage.

Remediation strategy

  • Upgrade every repository-controlled Starlette dependency, lockfile, image, and transitive FastAPI/ASGI runtime to 1.0.1+ where compatible.
  • Add a dependency guard or scanner assertion so affected Starlette versions do not re-enter generated lockfiles or runtime images.
  • Review security-sensitive uses of request.url and request.url.path. Replace path authorization checks with route identity, raw ASGI scope["path"], framework route metadata, or explicit normalized path input.
  • Add or verify strict Host validation at the trusted edge. In Starlette apps, use TrustedHostMiddleware when the app itself must reject unexpected hosts.
  • For MCP, LLM gateway, model-serving, and agent-control-plane APIs, treat public or LAN-exposed endpoints as higher priority because path mistakes can expose tool execution, provider keys, tenant data, or admin operations.

The prompt

You are remediating CVE-2026-48710 / GHSA-86qp-5c8j-p5mr, the Starlette
BadHost issue where malformed Host headers can poison request.url.path and
bypass path-based security checks. Produce exactly one output:

- A reviewer-ready PR/change request that upgrades Starlette to 1.0.1+, fixes
  unsafe path-based security checks, adds safe regression tests, refreshes
  generated artifacts, and documents proxy/operator requirements, or
- TRIAGE.md if this repository does not own an affected Starlette/FastAPI/ASGI
  runtime or cannot safely patch the affected service.

## Rules

- Scope only CVE-2026-48710 / GHSA-86qp-5c8j-p5mr and directly related
  Starlette request URL trust boundaries.
- Treat cookies, bearer tokens, API keys, MCP tool credentials, model-provider
  keys, tenant data, prompts, callbacks, request logs, and admin routes as
  sensitive.
- Do not run public scanners against production, send malformed Host headers to
  live systems, log credentials, or capture customer traffic.
- Do not remove authentication, authorization, tenant isolation, proxy
  validation, audit logging, or tests to silence the finding.
- Do not auto-merge.

## Steps

1. Inventory every Starlette runtime controlled by this repository: direct
   dependencies, FastAPI transitive dependencies, MCP servers, LLM gateways,
   model-serving APIs, ASGI middleware, Dockerfiles, base images, lockfiles,
   notebooks, generated dependency reports, and SBOMs.
2. Determine every resolved `starlette` version. A target is vulnerable if it
   resolves to `1.0.0` or earlier.
3. Search for security-sensitive URL usage:
   `request.url`, `request.url.path`, `request.base_url`, `str(request.url)`,
   path-prefix checks, admin route guards, tenant route gates, OAuth/callback
   validation, webhook allow/deny logic, proxy trust middleware, and
   `X-Forwarded-Host` handling.
4. Classify exposure:
   loopback-only development, trusted internal service, LAN-exposed API,
   internet-facing API, MCP/agent control plane, LLM gateway, model-serving
   control plane, or externally owned platform image.
5. If this repository only calls an externally owned service, stop with
   `TRIAGE.md` listing checked files, the external owner, and the required
   Starlette fixed version.
6. Upgrade all controlled Starlette runtimes to `1.0.1+`. Refresh lockfiles,
   image references, generated manifests, SBOMs, dependency reports, and
   deployment docs.
7. Fix unsafe code patterns:
   - do not authorize sensitive routes by comparing `request.url.path`;
   - prefer route identity, raw ASGI `scope["path"]`, router metadata, or a
     normalized path value from the framework;
   - validate trusted hosts at the edge or with `TrustedHostMiddleware`;
   - avoid trusting attacker-controlled `X-Forwarded-Host` or `Forwarded`
     values unless a trusted proxy strips and sets them.
8. Add safe regression tests that do not target production:
   - dependency resolution rejects Starlette `<=1.0.0`;
   - security checks use route identity or raw scope path;
   - local ASGI test client cases prove protected routes stay protected when
     host input is unusual;
   - logs and test output omit tokens, cookies, prompts, and tenant data.
9. Add a PR body section named `CVE-2026-48710 operator actions` that states:
   - Starlette/FastAPI versions before and after;
   - which services use Starlette directly or transitively;
   - whether any security decision previously used `request.url.path`;
   - which edge proxy, ingress, or middleware validates Host headers;
   - whether MCP, LLM gateway, model-serving, admin, callback, or tenant routes
     were exposed to untrusted clients;
   - which validation commands passed.
10. If immediate upgrade is blocked, add temporary containment where this repo
    controls it:
    - reject malformed Host headers at the edge;
    - remove untrusted network exposure for affected ASGI services;
    - disable or restrict sensitive path-prefix middleware until fixed;
    - document owner, follow-up date, and residual risk.
11. Run available validation: dependency install, lockfile integrity, unit and
    route tests, ASGI middleware tests, lint/typecheck, image build, deployment
    rendering, SBOM refresh, and dependency/security scans.
12. Use PR title:
    `fix(sec): remediate CVE-2026-48710 in Starlette`.

## Stop conditions

- No repository-controlled Starlette, FastAPI, MCP, LLM gateway, or ASGI runtime
  exists.
- A fixed Starlette version cannot be consumed without a broader framework
  migration.
- The only affected runtime is supplied by another platform owner; document the
  owner and required fixed version in TRIAGE.md.
- Verification would require malformed Host probes against production, live
  traffic capture, customer data, or secrets.
- Validation fails for unrelated pre-existing reasons; document those failures
  instead of broadening scope.

Output contract

  • A reviewer-ready PR or change request that upgrades Starlette, moves security decisions to raw ASGI scope or route identity, adds malformed-host regression tests, and documents proxy/host validation.
  • Or a TRIAGE.md file that lists inspected files/config, owner, observed version, path-auth boundary, protected routes, required fix, and residual risk.
  • The output must include exact validation commands and must not probe production admin/tenant routes, expose cookies, or print request secrets.

Verification - what the reviewer looks for

  • No repository-controlled manifest, lockfile, image, SBOM, or generated dependency report resolves Starlette <=1.0.0.
  • Security-sensitive middleware does not rely on request.url.path for route authorization.
  • Host validation is present at a trusted proxy, ingress, WAF, or Starlette middleware boundary.
  • Regression tests exercise local ASGI request handling without hitting live services or logging secrets.
  • Operator notes name any MCP, LLM gateway, model-serving, admin, callback, or tenant routes that need rollout attention.

Watch for

  • Updating FastAPI without refreshing the transitive Starlette lockfile entry.
  • Protecting /admin or /tools by comparing request.url.path in middleware while routing still uses the raw ASGI path.
  • Trusting X-Forwarded-Host from clients because a reverse proxy is assumed but not enforced.
  • Running internet scanners instead of local unit tests and proxy config checks.
  • Treating official “Moderate” severity as low priority for agent or MCP control planes where path confusion can expose powerful tools.

References