{"slug": "badhost-cve-2026-48710-starlette-host-header-auth-bypass", "title": "BadHost – CVE-2026-48710 Starlette Host-Header Auth Bypass", "summary": "A critical vulnerability tracked as CVE-2026-48710 (BadHost) in Starlette versions prior to 1.0.1 allows attackers to bypass path-based authentication middleware by injecting a crafted Host header that manipulates the `request.url.path` value. The flaw affects Python applications built on Starlette or FastAPI that use `request.url` for security decisions, including LLM inference servers like vLLM, proxy servers like LiteLLM, and MCP gateway implementations. X41 D-Sec discovered the vulnerability during an OSTIF-sponsored audit, and exploitation can expose model access, API keys, and internal tooling in AI infrastructure deployments.", "body_md": "Also known as:\n[X41-2026-002](https://x41-dsec.de/lab/advisories/x41-2026-002-starlette/)\n/\n[GHSA-86qp-5c8j-p5mr](https://github.com/Kludex/starlette/security/advisories/GHSA-86qp-5c8j-p5mr)\n/\n[PYSEC-2026-161](https://osv.dev/vulnerability/PYSEC-2026-161)\n\nDiscovered by [X41 D-Sec](https://x41-dsec.de) during an [OSTIF](https://ostif.org)-sponsored audit\n\nScanner & automation by [Nemesis](https://www.persistent-security.net/use-cases)\n\n`request.url`\n\nfrom the\n`Host`\n\nheader without sanitization, letting attackers\nforge a `request.url.path`\n\nthat bypasses path-based\nauth middleware.\nAutomatically discovers MCP endpoints **and** common inference\nAPI paths (vLLM, LiteLLM, OpenAI-compatible). Best for scanning AI\ninfrastructure where the exact stack is unknown.\n\n`Host`\n\nheaders containing invalid characters instead\nof using them for URL construction.`request.url.path`\n\nis inherently\nfragile — auth should be tied to the endpoint itself, not the path\nused to reach it. Prefer Starlette's\n`requires()`\n\n`Depends()`\n\nand `Security()`\n\n`Host`\n\nheader before forwarding, which neutralizes this attack.\nASGI servers pass the raw header through to the framework — a reverse proxy\nprevents that.`scope[\"path\"]`\n\n`request.url.path`\n\nif you must use middleware. The ASGI scope\npath comes from the HTTP request line and cannot be manipulated via the\nHost header.\nStarlette < 1.0.1 builds `request.url`\n\nby concatenating the HTTP\n`Host`\n\nheader with the request path. An attacker can send a crafted\nrequest like `GET /protected`\n\nwith a `Host: example.com/health?x=`\n\nheader. The request will reach the `/proteced`\n\npath, but `request.url`\n\nwould be `https://example.com/health?x=/protected`\n\n, and `request.url.path`\n\nwould return `/health`\n\ninstead of the real request path.\nAny middleware that uses this value to decide whether to enforce authentication can be bypassed.\n\nMore details can be found in the [X41-2026-002](https://x41-dsec.de/lab/advisories/x41-2026-002-starlette/)\nadvisory.\n\nAny Python application built on Starlette or FastAPI that uses\n`starlette < 1.0.1`\n\nand uses `request.url`\n\n(or `starlette.datastructures.URL(scope=...)`\n\n)\nin a middleware to make security decisions based on its `path`\n\n(e.g. allowlists, denylists, CSRF exemptions, rate limiting, payment gates),\nand runs on any ASGI server (Daphne, Granian, Gunicorn, Hypercorn, Anycorn, Uvicorn).\nUse the scanner above, grep your codebase for `request.url.path`\n\nin middleware files, or try the tools from the\n[X41\nopen-source repository](https://github.com/x41sec/poc/tree/master/starlette-host-header).\n\nThis includes LLM inference servers like vLLM, LLM proxy servers like LiteLLM, AI agent frameworks, MCP gateways, and custom APIs. MCP servers are especially at risk because the MCP spec mandates unauthenticated OAuth discovery endpoints, providing a reliable path for exploitation\n\nThis vulnerability is not specific to LLMs, but many LLM inference servers\n(vLLM), LLM proxy servers (LiteLLM), AI agent frameworks, and MCP gateway\nimplementations are built on FastAPI/Starlette\nand use path-based auth to protect API endpoints. A bypass can expose model\naccess, API keys, and internal tooling. Google ADK-Python, Ray Serve, and\nBentoML also use Starlette middleware and are potentially affected when\ncustom auth middleware is added. Any custom MCP server, FastMCP integration,\nor AI agent backend using Starlette routing with auth middleware should be\ntested. Note: FastAPI's built-in `Depends()`\n\nsecurity uses route\nmatching, not `request.url.path`\n\n, so standard dependency-injection\nauth is safe — the risk is in custom `BaseHTTPMiddleware`\n\nor raw ASGI middleware.\n\nYes. RFC-compliant reverse proxies (nginx, Caddy, Traefik, HAProxy) validate\nand reject invalid `Host`\n\nheaders, which neutralizes\nthe injection. However, many deployments — especially dev, staging, and\nself-hosted instances — expose ASGI servers directly without a proxy.\n\nThe scanner first confirms a protected endpoint denies access without credentials. Tier 1 then tests whether the middleware uses a denylist (fail-open) pattern by injecting a random path into the Host header — this catches misconfigured middleware in just a few requests. If Tier 1 fails, Tier 2 discovers known unauthenticated paths and injects those for allowlist-based (fail-closed) middleware. Raw TCP sockets are used because standard HTTP clients normalize the Host header, which would prevent the test.\n\nAnthropic's Claude Mythos found 10,000+ vulnerabilities through Project\nGlasswing — but not this one. The reason is structural: CVE-2026-48710\nis not a bug in one file or one repo. It spans three independent layers\n— ASGI servers pass the raw Host header, Starlette trusts it for URL\nconstruction, and middleware authors assume `request.url.path`\n\nis\nsafe for auth decisions. Each component behaves correctly in isolation.\nThe vulnerability only emerges from the interaction between them, across\nspecifications (HTTP, ASGI, Starlette, MCP). Finding it required manual\nsecurity research — understanding how these layers combine and building\nend-to-end exploit labs to confirm the attack. That is a fundamentally\ndifferent shape of work than pointing an AI agent at a single codebase.\n\nOnce the bug class was understood, measuring its real-world impact was a separate effort: writing custom CodeQL queries and scanning dependent projects at scale — Starlette alone has more than 400k dependents on GitHub. This impact assessment work is valuable but distinct from the discovery itself.\n\nYes. The\n[X41\nopen-source repository](https://github.com/x41sec/poc/tree/master/starlette-host-header) includes a Python PoC exploit, Semgrep rules for\nstatic detection, and CodeQL queries for large-scale scanning. You can use the\nSemgrep rules to check your own codebase for `request.url.path`\n\nusage in middleware, or run the CodeQL queries against any Python project to\nfind vulnerable patterns.\n\nA collaboration between", "url": "https://wpnews.pro/news/badhost-cve-2026-48710-starlette-host-header-auth-bypass", "canonical_source": "https://mcp-scan.nemesis.services/", "published_at": "2026-05-26 09:07:18+00:00", "updated_at": "2026-05-26 09:09:20.782887+00:00", "lang": "en", "topics": ["ai-infrastructure", "ai-safety"], "entities": ["X41 D-Sec", "OSTIF", "Nemesis", "Starlette", "Kludex", "vLLM", "LiteLLM", "OpenAI"], "alternates": {"html": "https://wpnews.pro/news/badhost-cve-2026-48710-starlette-host-header-auth-bypass", "markdown": "https://wpnews.pro/news/badhost-cve-2026-48710-starlette-host-header-auth-bypass.md", "text": "https://wpnews.pro/news/badhost-cve-2026-48710-starlette-host-header-auth-bypass.txt", "jsonld": "https://wpnews.pro/news/badhost-cve-2026-48710-starlette-host-header-auth-bypass.jsonld"}}