vLLM is an inference and serving engine for large language models (LLMs). From 0.3.0 until 0.22.0, a vulnerability in ASGI web servers and starlette's trust on those web servers enables an authentication bypass of the OpenAI API AuthenticationMiddleware. It allows to use the API without providing the configured VLLM_API_KEY or --api-key. This vulnerability is fixed in 0.22.0.
vLLM: OpenAI auth bypass
Problem type
Affected products
vllm-project
>= 0.3.0, < 0.22.0 - AFFECTED
References
https://github.com/vllm-project/vllm/security/advisories/GHSA-94f4-hr76-p5j6
https://github.com/vllm-project/vllm/pull/43426
https://x41-dsec.de/lab/advisories/x41-2026-002-starlette
GitHub Security Advisories
GHSA-94f4-hr76-p5j6
vLLM: OpenAI auth bypass
https://github.com/advisories/GHSA-94f4-hr76-p5j6Summary
A vulnerability in ASGI web servers and starlette's trust on those web servers enables an authentication bypass of the OpenAI API AuthenticationMiddleware, which was discovered during @x41sec's source code audit.
It allows to use the API without providing the configured VLLM_API_KEY or --api-key.
Details
In https://github.com/vllm-project/vllm/blob/v0.14.0/vllm/entrypoints/openai/api_server.py#L689-L692 the url_path is taken from the URL, which is reconstructed by starlette based on the request scope.
from starlette.datastructures import URL, Headers, MutableHeaders, State
# ...
url_path = URL(scope=scope).path.removeprefix(root_path)
headers = Headers(scope=scope)
if url_path.startswith("/v1") and not self.verify_token(headers):
response = JSONResponse(content={"error": "Unauthorized"}, status_code=401)
return response(scope, receive, send)
return self.app(scope, receive, send)
The request scope includes the request's Host: header and reconstructs the URL as shown below:
f"{scheme}://{host_header}{path}"
Neither starlette nor any of the ASGI servers (including uvicorn, which vllm uses) properly filter the Host: header for invalid characters. This allows an attacker to include special URL characters such as / or ? in the Host: header and thereby control the reconstructed URL and it's .path attribute.
FastAPI/starlette's routing uses the HTTP path and does not depend on the parsed url.path attribute, allowing attackers to reach an endpoint via a certain path while providing a different value in the .path.
Impact
- Instances of vllm that use an API Key for the OpenAI API and expose the API to attackers.
- Instances behind an RFC-conforming web server (such as nginx) are not affected.
JSON source
https://cveawg.mitre.org/api/cve/CVE-2026-48746Click to expand
{
"dataType": "CVE_RECORD",
"dataVersion": "5.2",
"cveMetadata": {
"cveId": "CVE-2026-48746",
"assignerOrgId": "a0819718-46f1-4df5-94e2-005712e83aaa",
"assignerShortName": "GitHub_M",
"dateUpdated": "2026-06-22T21:57:28.997Z",
"dateReserved": "2026-05-22T19:10:35.747Z",
"datePublished": "2026-06-22T21:57:28.997Z",
"state": "PUBLISHED"
},
"containers": {
"cna": {
"providerMetadata": {
"orgId": "a0819718-46f1-4df5-94e2-005712e83aaa",
"shortName": "GitHub_M",
"dateUpdated": "2026-06-22T21:57:28.997Z"
},
"title": "vLLM: OpenAI auth bypass",
"descriptions": [
{
"lang": "en",
"value": "vLLM is an inference and serving engine for large language models (LLMs). From 0.3.0 until 0.22.0, a vulnerability in ASGI web servers and starlette's trust on those web servers enables an authentication bypass of the OpenAI API AuthenticationMiddleware. It allows to use the API without providing the configured VLLM_API_KEY or --api-key. This vulnerability is fixed in 0.22.0."
}
],
"affected": [
{
"vendor": "vllm-project",
"product": "vllm",
"versions": [
{
"version": ">= 0.3.0, < 0.22.0",
"status": "affected"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"lang": "en",
"description": "CWE-444: Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')",
"cweId": "CWE-444",
"type": "CWE"
}
]
}
],
"references": [
{
"url": "https://github.com/vllm-project/vllm/security/advisories/GHSA-94f4-hr76-p5j6",
"name": "https://github.com/vllm-project/vllm/security/advisories/GHSA-94f4-hr76-p5j6",
"tags": [
"x_refsource_CONFIRM"
]
},
{
"url": "https://github.com/vllm-project/vllm/pull/43426",
"name": "https://github.com/vllm-project/vllm/pull/43426",
"tags": [
"x_refsource_MISC"
]
},
{
"url": "https://x41-dsec.de/lab/advisories/x41-2026-002-starlette",
"name": "https://x41-dsec.de/lab/advisories/x41-2026-002-starlette",
"tags": [
"x_refsource_MISC"
]
}
],
"metrics": [
{
"cvssV3_1": {
"version": "3.1",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H",
"attackVector": "NETWORK",
"attackComplexity": "LOW",
"privilegesRequired": "NONE",
"userInteraction": "NONE",
"scope": "UNCHANGED",
"confidentialityImpact": "HIGH",
"integrityImpact": "NONE",
"availabilityImpact": "HIGH",
"baseScore": 9.1,
"baseSeverity": "CRITICAL"
}
}
]
}
}
}