BadHost: CVE-2026-48710
A Critical Authentication Bypass in Starlette Threatening Every AI Agent Deployment
Executive Summary
CVE-2026-48710, dubbed "BadHost," is a critical authentication bypass vulnerability in Starlette -- the ASGI framework powering FastAPI, vLLM, LiteLLM, and virtually every MCP gateway in production. Discovered by X41 D-Sec during an OSTIF-sponsored audit, the vulnerability allows attackers to bypass path-based authentication middleware by manipulating the HTTP Host header. Because Starlette constructs request.url from the unsanitized Host header, a crafted request can make the application see a different path than the one actually requested, sidestepping access controls entirely.
What Is BadHost?
Starlette constructs the full request URL by concatenating the HTTP Host header with the request path. For example, a request to GET /admin with Host: example.com produces request.url as http://example.com/admin.
The problem: Starlette does not sanitize the Host header before this concatenation. An attacker can inject path segments directly into the Host header, and Starlette will parse them as part of the URL. The application's middleware then acts on the attacker-supplied URL rather than the actual request path.
This is not a theoretical concern. The vulnerability is present in every version of Starlette prior to 1.0.1 -- and therefore present in every FastAPI application, every vLLM server, every LiteLLM proxy, and every MCP gateway running unpatched versions.
The attack does not require authentication, does not require a valid session, and does not generate meaningful log entries. It is a clean, silent bypass.
How the Exploit Works
The mechanics are straightforward. Here is the step-by-step:
1. The target application has path-based authentication middleware.
A common pattern in FastAPI and ASGI applications:
@app.middleware("http")
async def auth_middleware(request, call_next):
if request.url.path == "/admin" and not is_authenticated(request):
return JSONResponse({"error": "Unauthorized"}, status_code=401)
return await call_next(request)The middleware checks request.url.path to decide whether authentication is required.
2. Starlette builds request.url from the Host header.
Internally, Starlette concatenates the Host header with the path to build the full URL. If the Host header contains a path segment, that segment becomes part of the constructed URL.
3. The attacker crafts a malicious Host header.
Instead of sending:
GET /admin HTTP/1.1
Host: example.comThe attacker sends:
GET /admin HTTP/1.1
Host: example.com/health?x=4. Starlette parses the manipulated URL.
The resulting request.url becomes something like http://example.com/health?x=/admin. The request.url.path is now /health instead of /admin.
5. The middleware grants access.
The auth middleware sees request.url.path == "/health", concludes the request does not target a protected route, and passes it through. The application serves the /admin endpoint to an unauthenticated attacker.
The path in scope["path"] -- the actual ASGI scope, set by the server from the raw request line -- still correctly contains /admin. But Starlette-based middleware that checks request.url.path instead of scope["path"] never sees it.
Why MCP Gateways Are the Worst Hit
MCP (Model Context Protocol) servers and gateways are disproportionately exposed to BadHost for two reasons.
First, MCP gateways expose unauthenticated OAuth discovery endpoints by design. The MCP specification requires servers to publish their OAuth metadata at well-known URIs -- publicly accessible, no authentication required. This gives attackers a predictable, reliable entry point. They can probe the discovery endpoint, confirm the server is running, and then test BadHost against every protected endpoint the gateway exposes.
Second, MCP gateways sit at the boundary between the open internet and internal tooling. A compromised MCP gateway does not just expose LLM endpoints. It exposes tool execution endpoints -- the ability to invoke internal APIs, access databases, read files, send messages, and execute arbitrary actions on behalf of the agent. Bypassing auth on an MCP gateway is not data theft. It is remote code execution through a trusted intermediary.
The affected infrastructure includes:
- vLLM servers -- open-source LLM inference engines used across the industry
- LiteLLM proxies -- the most common proxy layer for multi-model LLM routing
- MCP servers and gateways -- the protocol layer connecting AI agents to tools and data
- Ray Serve -- distributed model serving infrastructure
- BentoML -- model packaging and deployment
- Google ADK-Python -- Google's agent development kit, when used with custom Starlette middleware
Full Impact Assessment
A successful BadHost exploit yields the following, depending on what sits behind the bypassed middleware:
| Impact | Description |
|---|---|
| Unrestricted LLM access | Attacker uses the victim's LLM endpoints at will, burning tokens and potentially extracting model behavior |
| API key extraction | Environment variables, config files, and runtime state exposed through agent tool calls |
| Internal tool execution | Through compromised MCP gateways, attackers invoke tools the agent was authorized to use |
| Compute resource abuse | GPU clusters and inference servers hijacked for cryptocurrency mining or model theft |
| Data exfiltration | Agent-accessible databases, file systems, and API responses extracted silently |
| Supply chain poisoning | If the compromised system generates outputs consumed by downstream agents, those outputs become injection vectors |
The exploit is particularly dangerous because it leaves no obvious forensic trail. The server logs show a request to /admin that succeeded -- the middleware was bypassed, but the actual handler processed what appeared to be an authenticated request. Without Host-header-level logging, the attack is indistinguishable from legitimate traffic.
Remediation Steps
Ordered by priority:
1. Upgrade Starlette to 1.0.1 or Later (Immediate)
This is the definitive fix. Starlette 1.0.1 sanitizes the Host header and no longer allows path segments to influence request.url.path.
pip install --upgrade starlette>=1.0.1Every FastAPI application, vLLM deployment, LiteLLM proxy, and MCP gateway should be upgraded immediately. Check dependencies -- some packages pin Starlette versions and may require explicit upgrades.
2. Replace request.url.path with scope["path"] (Immediate, If Upgrade Is Blocked)
The ASGI scope["path"] is set by the server from the raw HTTP request line. It cannot be influenced by the Host header. If you cannot upgrade Starlette immediately, audit every middleware function and replace:
# Vulnerable
if request.url.path == "/admin":
# Fixed
if request.scope["path"] == "/admin":This is not a complete fix (other parts of the application may still use request.url unsafely), but it closes the primary auth bypass vector.
3. Deploy a Reverse Proxy That Validates Host Headers (Within 24 Hours)
Nginx, Caddy, and HAProxy can reject requests with malformed Host headers before they reach the application:
Nginx:
server {
listen 80;
server_name example.com;
if ($host !~ ^example\.com$) {
return 444;
}
}Caddy:
example.com {
@badhost header_regexp Host .*\/.*
respond @badhost 421
}This is defense in depth. Even if the application is vulnerable, the proxy rejects the request before it arrives.
4. Use FastAPI's Depends() or Security() for Authentication (Ongoing)
FastAPI's dependency injection system resolves authentication before route handlers execute, and it does not rely on request.url.path:
from fastapi import Depends, Security
@app.get("/admin")
async def admin_endpoint(user = Security(get_current_user)):
# Only reached if get_current_user succeedsMoving authentication from path-based middleware to dependency injection eliminates the entire class of path-matching bypass vulnerabilities.
5. Audit All ASGI Middleware for Host Header Reliance (Within 1 Week)
Any middleware that inspects request.url, request.url.path, or request.url.hostname is potentially vulnerable. Audit the full middleware stack -- including third-party packages -- and verify that no access control decision is based on the Host-header-derived URL.
What This Means for AI Agent Deployments
BadHost is not a vulnerability in AI models. It is a vulnerability in the infrastructure that serves them. And that is precisely the point.
The industry has spent two years debating prompt injection, jailbreaking, and model alignment. Meanwhile, the actual attack surface has expanded through the infrastructure layer -- MCP gateways, ASGI servers, inference proxies -- with security practices that lag years behind web application standards.
CVE-2026-48710 is a textbook web security vulnerability. Host header manipulation has been a known attack vector since the early 2000s. The fact that it resurfaced in the AI stack, in 2026, in a framework used by virtually every major inference server, tells you everything you need to know about the state of AI infrastructure security.
The attack surface for AI agents is not the model. It is the stack around it.
At AgentVet, we designed our harness to test the entire deployment surface -- the Runtime, Middleware, Connectors, Storage, Orchestration, and Gateway components (R,M,C,S,O,G). BadHost validates that approach. It is not a vulnerability you find by red-teaming the model. It is a vulnerability you find by inspecting the HTTP layer, the framework version, the middleware configuration, and the reverse proxy setup.
Vet the stack. Not just the model.
References
- Cryptika, "BadHost: Critical Authentication Bypass in Starlette (CVE-2026-48710)," May 2026.
- OSTIF, "Security Audit of Starlette by X41 D-Sec," May 2026.
- X41 D-Sec, "Starlette Security Assessment," OSTIF-sponsored audit, 2026.
- Starlette GitHub, Release 1.0.1 changelog.
- OWASP, "Host Header Injection," Web Security Testing Guide.
- AgentVet, "The MCP Security Crisis: 9,400 Servers, 150M Downloads, Zero Guardrails," May 2026.
Published by AgentVet • May 2026