Security Digest · May 21, 2026 · Vulnerability · Web framework
Starlette BadHost: Host Header Auth Bypass in CISA KEV
A malformed Host header makes Starlette's request.url.path lie to auth middleware. In KEV. Fixed in starlette 1.0.1; FastAPI before 0.133.0 blocks the fix.
Our verdict
Patch this week
Bump starlette to 1.0.1 or later in every Python service this week; it is urgent where an ASGI server faces untrusted clients directly and middleware makes security decisions from request.url.
Who must act: Teams running Starlette or FastAPI apps, or Python AI infrastructure built on them (LiteLLM, vLLM, MCP servers), whose middleware checks request.url or request.url.path, especially with uvicorn, hypercorn, granian or daphne exposed without a reverse proxy.
Who can relax: Apps that enforce auth per route with FastAPI Depends()/Security() or Starlette requires() and sit behind an RFC-compliant reverse proxy; they should still upgrade on a normal cycle.
- Affected
- starlette before 1.0.1 (X41 traces it back to 0.8.3)
FastAPI apps on FastAPI before 0.133.0, whose starlette<1.0.0 pin blocks the fix
LiteLLM Proxy 1.74.2 through 1.83.6 on starlette 1.0.0 or earlier (chain with CVE-2026-42271) - Fixed in
- starlette 1.0.1 (May 21, 2026) and later; 1.9.0 is current
FastAPI 0.133.0 and later (allows starlette 1.x)
LiteLLM 1.83.7 and later for CVE-2026-42271 - CVSS
- 6.5 (v3.1, CNA)
- EPSS
- 7.1% (percentile 94)
- CISA KEV
- Yes, listed as known exploited
- Exploitation
- Exploited in the wild
- Severity
- High
What to do
- Find every installed Starlette: pip show starlette in each service and image, or search lockfiles for starlette.
- Upgrade to starlette 1.0.1 or later; on FastAPI older than 0.133.0, upgrade FastAPI too, then rebuild and redeploy images.
- Grep middleware for request.url and URL(scope=...) and move security checks to request.scope["path"] or per-route dependencies.
- Put an RFC-compliant reverse proxy (nginx, Caddy, Traefik, HAProxy) in front of every ASGI server, and do not trust client-supplied X-Forwarded-Host.
- If you run LiteLLM Proxy, upgrade it to 1.83.7 or later alongside starlette 1.0.1.
- Test a protected path with a malformed Host header (curl -H 'Host: foo?') and confirm it is still denied.
How to check if you are affected or compromised
- Search reverse-proxy and WAF logs for Host header values containing /, ? or #, and for 400s from the proxy rejecting them.
- Remember uvicorn's access log records client, method, path and status but not Host; look for 200 responses on protected paths from clients that never authenticated.
- For LiteLLM, review POSTs to /mcp-rest/test/connection and /mcp-rest/test/tools/list and any unexpected child processes of the proxy.
- Run X41's published proof of concept, Semgrep and CodeQL rules against your own services to find vulnerable middleware.
What happened#
On May 21, 2026, Starlette 1.0.1 shipped a fix for GHSA-86qp-5c8j-p5mr, later assigned CVE-2026-48710 and nicknamed BadHost. Starlette is the ASGI toolkit underneath FastAPI. It rebuilt request.url by gluing the unvalidated Host header onto the request path and re-parsing the result. Characters such as /, ? and # in Host shift where the path starts. The router still dispatches on the real path, but any code that reads request.url.path sees an attacker-chosen one. The advisory's example sends /foo with Host: example.com/abc?bar=. The route for /foo runs while middleware sees /abc.
X41 D-Sec found the bug during an OSTIF-managed audit of vLLM. Its advisory shows a guard on /admin returning 403 for Host: foo and 200 for Host: foo?. The CNA score is CVSS 3.1 6.5. X41 rates it High, and OSTIF argues the score badly understates downstream impact. CISA added it to the KEV catalog on September 2, 2026, with a September 16 federal deadline, and notes it can be chained with LiteLLM's CVE-2026-42271. Horizon3.ai showed that chain. LiteLLM's MCP test endpoints spawn a caller-supplied command and were supposed to require an API key, but BadHost lets the auth middleware wave the request through, which yields unauthenticated code execution on the proxy. CISA has not said who exploited CVE-2026-48710 or how.
Who is affected#
Every starlette release before 1.0.1 is affected. You are exploitable only if code makes a security decision from request.url, request.url.path or URL(scope=...). The usual culprit is a BaseHTTPMiddleware or raw ASGI middleware that allowlists or blocks path prefixes. The BadHost site says FastAPI Depends() checks are safe because they hang off route matching. It names vLLM, LiteLLM, MCP and FastMCP servers and agent frameworks as affected, and says custom auth middleware can put tools like Ray Serve or BentoML at risk.
FastAPI has a trap: releases before 0.133.0 pin starlette<1.0.0, and no 0.x backport exists, so those apps cannot get the fix without a FastAPI upgrade. FastAPI 0.133.0 dropped the cap, and current releases require starlette>=0.46.0. The X41 proof of concept worked on uvicorn, hypercorn, granian and daphne.
Do you really need to act?#
Upgrade either way, because it is a dependency bump. How urgent depends on two questions.
- Does anything check
request.urlfor auth, tenancy, rate limits or audit? If yes, and an ASGI server is reachable directly, treat this as act-now. The researchers single out AI gateways and model servers, and LiteLLM before 1.83.7 turns the bypass into code execution. - Is a compliant proxy in front? OSTIF says nginx, Apache httpd and Cloudflare reject the PoC by default, and BadHost lists Caddy, Traefik and HAProxy as rejecting invalid Host values. The GHSA warns this protection fails if the app trusts an attacker-controlled
X-Forwarded-Host. BadHost notes that dev, staging and self-hosted instances often expose the ASGI server directly. - Per-route dependencies only? Your exposure is low. Patch on a normal cycle.
What to do now#
- Inventory:
pip show starlette fastapiin each service and image, orgrep -i starlette uv.lock poetry.lock requirements*.txt. - Upgrade:
pip install -U "starlette>=1.0.1" "fastapi>=0.133.0"(or the lockfile equivalent). Then rebuild and redeploy containers, because vendored copies stay vulnerable. - Fix the pattern:
grep -rn "request.url" --include=*.pyin middleware. Switch checks torequest.scope["path"], or better, to per-routeDepends()/Security()or Starlette'srequires(). - Front every ASGI server with a reverse proxy and verify that it rejects malformed Host headers.
- LiteLLM Proxy operators: upgrade to 1.83.7 or later as well, as Horizon3 and the CSA note advise.
- Verify:
curl -i -H 'Host: foo?' https://your-service/protectedshould still return 401 or 403.
How to tell if you were hit#
The evidence lives in the Host header, which many logs drop. Uvicorn's access log records client, method, path and status, not Host. Check proxy, load balancer and WAF logs instead (log $http_host in nginx) for Host values containing /, ? or #. Look for 200 responses on protected endpoints from clients that never authenticated. On LiteLLM, review POSTs to /mcp-rest/test/connection and /mcp-rest/test/tools/list and unexpected processes spawned by the proxy. If you find a hit, rotate the provider keys and secrets the service held. X41 has published a proof of concept, Semgrep rules and CodeQL queries for scanning your own code.
Timeline#
- — X41 finds the issue during an audit.
- — X41 builds a PoC and contacts the maintainer.
- — Starlette 1.0.1 and the GHSA are published.
- — The CVE is published, and OSTIF publishes its BadHost disclosure.
- — Horizon3.ai validates the chain with LiteLLM CVE-2026-42271, which entered KEV on June 8.
- — CISA adds CVE-2026-48710 to KEV, with a federal due date of September 16.
Vulnerability records
- CVE-2026-48710 · KEV 2026-09-02 · Starlette is a lightweight ASGI framework/toolkit.
Sources
Original sources first: vendor and project advisories, CVE and government records, the discoverers’ write-ups. Every claim above links to one of these. See how the Security Desk works.
Original and primary sources
- Starlette / GitHub — GHSA-86qp-5c8j-p5mr: Missing Host header validation poisons request.url.path github.com
- CVE record — CVE-2026-48710 cve.org
- CISA — Known Exploited Vulnerabilities: CVE-2026-48710 cisa.gov
- X41 D-Sec — X41-2026-002: Starlette Host header validation x41-dsec.de
- OSTIF — Disclosing the BadHost vulnerability in Starlette ostif.org
- BadHost — CVE-2026-48710 project site badhost.org
- Horizon3.ai — CVE-2026-42271: LiteLLM unauthenticated RCE via Starlette Host header bypass horizon3.ai
- CVE record — CVE-2026-42271 (LiteLLM MCP stdio test endpoints) cve.org
- PyPI — starlette release history pypi.org
- PyPI — fastapi 0.133.0 pypi.org
- Uvicorn — h11_impl.py access log format github.com
- Cloud Security Alliance — LiteLLM AI gateway attack chain research note labs.cloudsecurityalliance.org