vLLM: OpenAI auth bypass
Description
CVE-2026-48746: ASGI/starlette Host header injection in vLLM's OpenAI API allows authentication bypass via crafted Host header overriding the URL path check.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
CVE-2026-48746: ASGI/starlette Host header injection in vLLM's OpenAI API allows authentication bypass via crafted Host header overriding the URL path check.
Vulnerability
In vLLM versions before v0.14.0, the AuthenticationMiddleware in vllm/entrypoints/openai/api_server.py (lines 689-692) extracts the url_path from a starlette URL object reconstructed from the request scope. The reconstruction uses the Host header value without validation, as f"{scheme}://{host_header}{path}" [1][3]. By including characters such as / or ? in the Host: header, an attacker can manipulate the reconstructed URL's .path attribute to avoid starting with /v1, thereby circumventing the token verification check (verify_token) that protects the OpenAI API endpoints. Affected environments are those that expose the API directly (not behind an RFC-conforming reverse proxy like nginx) and have configured an API key via VLLM_API_KEY or --api-key [1][3]. Starlette versions >= 0.8.3 (up to 1.0.1) are affected; vLLM depends on these versions [2].
Exploitation
An attacker needs network access to a vulnerable vLLM instance that is directly exposed (not behind nginx or similar) and has API key authentication enabled [1][3]. The exploit requires no authentication and no user interaction. The attacker sends an HTTP request where the Host: header contains path-delimiting characters, for example: a request line GET /v1/chat/completions HTTP/1.1 with Host: target.com/skip. The reconstructed URL becomes http://target.com/skip/v1/chat/completions, so url_path (after removeprefix(root_path)) no longer starts with /v1. The authentication check in AuthenticationMiddleware is then skipped, and the request is passed to the underlying application, which routes based on the actual HTTP path (from the request line) and processes the request as a valid API call [2][3].
Impact
Successful exploitation allows an attacker to call any OpenAI-compatible API endpoint without providing the required API key [1][3]. This results in unauthorized access to vLLM features such as model inference, potentially leading to information disclosure, resource abuse, or denial of service. The attacker gains the ability to use the API at the same privilege level as an authenticated user, with no restriction on the actions performed [3].
Mitigation
The vulnerability is fixed in vLLM by pull request #43426, which changes the path extraction to use the request's original path from the ASGI scope instead of the reconstructed URL [1][3]. Users should update vLLM to a version that includes this fix (committed but not yet released as a tag in the referenced PR). Deploying vLLM behind an RFC-conforming reverse proxy such as nginx (which normalizes or rejects malformed Host headers) fully mitigates the attack [1][3]. Until patched, ensure the vLLM API is not directly exposed to untrusted networks. Neither vLLM nor the upstream starlette (fixed in 1.0.1) are listed in CISA's Known Exploited Vulnerabilities catalog [2].
AI Insight generated on Jun 16, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
12b94d1c0caf6[Frontend] Simplify AuthenticationMiddleware path extraction (#43426)
1 file changed · +2 −2
vllm/entrypoints/openai/server_utils.py+2 −2 modified@@ -15,7 +15,7 @@ from fastapi.exceptions import RequestValidationError from fastapi.responses import JSONResponse from starlette.concurrency import iterate_in_threadpool -from starlette.datastructures import URL, Headers, MutableHeaders +from starlette.datastructures import Headers, MutableHeaders from starlette.types import ASGIApp, Message, Receive, Scope, Send from vllm import envs @@ -80,7 +80,7 @@ def __call__(self, scope: Scope, receive: Receive, send: Send) -> Awaitable[None # in which case we don't need to do anything return self.app(scope, receive, send) root_path = scope.get("root_path", "") - url_path = URL(scope=scope).path.removeprefix(root_path) + url_path = scope["path"].removeprefix(root_path) headers = Headers(scope=scope) # Type narrow to satisfy mypy. if url_path.startswith(GUARDED_PREFIX) and not self.verify_token(headers):
Vulnerability mechanics
Root cause
"The AuthenticationMiddleware uses starlette's URL(scope=scope).path, which reconstructs the URL from the Host header, instead of using the raw ASGI scope['path'] that reflects the actual HTTP request path."
Attack vector
An attacker sends an HTTP request to a vLLM instance that has `VLLM_API_KEY` or `--api-key` configured, but sets a crafted `Host:` header containing special URL characters such as `/` or `?`. The ASGI server (uvicorn) passes the raw `Host:` header into the request `scope`, and starlette's `URL(scope=scope).path` reconstruction uses that header, allowing the attacker to make the `.path` attribute differ from the actual HTTP path used by FastAPI/starlette routing. This causes the `AuthenticationMiddleware` to skip the token verification for paths that start with `/v1`, enabling unauthenticated access to the OpenAI-compatible API endpoints. Instances behind an RFC-conforming reverse proxy (e.g., nginx) are not affected because the proxy strips or normalizes the `Host:` header. [CWE-287]
Affected code
The vulnerability resides in `vllm/entrypoints/openai/api_server.py` (lines 689–692 in v0.14.0) and the `AuthenticationMiddleware.__call__` method in `vllm/entrypoints/openai/server_utils.py`. The middleware constructs a `URL` object from the ASGI `scope` via `URL(scope=scope).path` and uses that `.path` to decide whether to enforce API-key authentication. Because neither starlette nor the ASGI server (uvicorn) sanitizes the `Host:` header, an attacker can embed `/` or `?` characters in the `Host:` header to control the reconstructed URL's `.path` attribute, bypassing the authentication check.
What the fix does
The patch in commit `2b94d1c0caf69d4108d720986f4e792960b02cf7` replaces `URL(scope=scope).path` with `scope["path"]` in `vllm/entrypoints/openai/server_utils.py`. The ASGI `scope["path"]` is set directly by the ASGI server from the raw HTTP request line and is not influenced by the `Host:` header, unlike starlette's `URL` reconstruction which concatenates the host header into the URL. By reading the path directly from the scope, the middleware now correctly compares the actual request path against the guarded prefix, closing the Host-header injection bypass.
Preconditions
- configvLLM instance must be configured with an API key (VLLM_API_KEY or --api-key)
- networkvLLM must be directly exposed to attackers (not behind an RFC-conforming reverse proxy like nginx)
- inputAttacker must be able to send HTTP requests with a crafted Host header
Generated on Jun 16, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.