Disclosing the Badhost Vulnerability in Starlette

arunbahl1 pts0 comments

Disclosing the BADHOST Vulnerability in Starlette – OSTIF.org

Skip to content

Post published:May 26, 2026

Post category:AWS / News / Open Source / X41-Dsec

BADHOST

OSTIF is disclosing the expanded details of the BadHost vulnerability in Starlette as slow uptake of updated versions of Starlette and discovery of more vulnerable live services has caused us serious concerns.

I’d like to open by saying that the maintainer of Starlette is having a bad few weeks. This disclosure + patch process has been long and a lot of parties have been contacting them about this while they are simultaneously dealing with a large pile of other security reports that every open source project is dealing with in 2026. This bug is a classic “responsibility gap” where if this maintainer didn’t patch, thousands of exposed projects would have to individually secure their projects. In doing this work, they’ve voluntarily taken on the responsibility to protect the ecosystem from long-term systemic harm. As with all open source projects, they owed us nothing and could have left this to be everyone else’s problem and took the extraordinary steps of helping the ecosystem. Please consider donating to Kludex: https://github.com/sponsors/Kludex

What is BadHost? https://www.secwest.net/starlette

A lack of input sanitization on host header paths in Starlette leads to bypassing auth with a single character across a huge swath of Python LLM infrastructure. This hits very large and prominent projects such as FastAPI, LiteLLM, vLLM, text generation inference projects, most OpenAI shim proxies, MCP servers, Agent harnesses, eval dashboards and model-management UIs.

Identified as CVE-2026-48710 information is still propagating about this bug.

https://security-tracker.debian.org/tracker/CVE-2026-48710

https://osv.dev/vulnerability/DEBIAN-CVE-2026-48710

https://github.com/Kludex/starlette/security/advisories/GHSA-86qp-5c8j-p5mr (rating severely understates the severity of the bug downstream)

Starlette reconstructs request.url by concatenating the HTTP Host header with the request path and re-parsing the result. The Host value is not validated against the RFC 9112 / RFC 3986 grammar before reconstruction. A Host header containing /, ?, or # shifts the path, query, and fragment boundaries during re-parse, so request.url.path no longer matches the path the ASGI server actually received and routed against.

The router dispatches on the real wire path. Middleware sees the poisoned, re-parsed path. Any path-based security decision made in middleware can be bypassed while the underlying route still executes.

How bad is this?

A minimal POC:

curl -i -H ‘Host: foo’  http://target/admin    # 403, blocked

curl -i -H ‘Host: foo?’ http://target/admin    # 200, served

Where Starlette-based middleware (including FastAPI middleware) enforces authorization or routing restrictions using request.url or request.url.path, the following should be assumed reachable by an unauthenticated remote attacker:

Bypass of path-prefix authentication (/admin, /v1/models, /internal, /metrics, /shutdown, tool-execution endpoints)

Bypass of tenant or workspace scoping enforced in middleware

Smuggling of requests into endpoints intended to be reachable only from authenticated sessions or internal hops

SSRF against cloud metadata services and internal hosts where the gated endpoint performs outbound fetches

RCE where the gated endpoint exposes tool execution, plugin loading, arbitrary model loading from URL, file upload, or code-eval style functionality

For LLM gateways specifically, the admin and key-management surface of services like LiteLLM, and the model and runtime control surface of services like vLLM, must be treated as exposed if the deployment is direct-to-ASGI.

How widespread is this?

This affects vLLM, LiteLLM, and FastAPI and many many more. These projects collectively make up the vast majority of all Python LLM infrastructure today.

Test for this Vulnerability

BadHost.org has tooling to examine your infrastructure and determine if it is vulnerable. The BadHost project, run jointly by X41 D-Sec, Persistent Security Industries, and Bintech, offers a free remote scanner for any reachable HTTP endpoint at badhost.org. Suitable for quick triage of a few services.

X41 has also published a scanner, Semgrep rules, and CodeQL queries at  Github.com/x41sec/poc/tree/master/starlette-host-header. Run these across any Python codebase that touches Starlette or FastAPI to find affected middleware patterns. The repository also includes a runtime PoC for confirming exposure on a deployed instance.

If you don’t want to use tooling, you are likely exposed if ANY of the following are true:

You run any FastAPI or Starlette application directly on uvicorn, hypercorn, daphne, or granian without an HTTP/1.1-compliant reverse proxy in front.

You run LiteLLM, vLLM, or similar LLM proxies and servers as the directly-reachable HTTP endpoint.

You terminate HTTP/3 or QUIC...

starlette path badhost host http projects

Related Articles