CVE-2026-34753
vLLM affected by Server-Side Request Forgery (SSRF) in `download_bytes_from_url `
vLLM is an inference and serving engine for large language models (LLMs). From 0.16.0 to before 0.19.0, a server-side request forgery (SSRF) vulnerability in download_bytes_from_url allows any actor who can control batch input JSON to make the vLLM batch runner issue arbitrary HTTP/HTTPS requests from the server, without any URL validation or domain restrictions. This can be used to target internal services (e.g. cloud metadata endpoints or internal HTTP APIs) reachable from the vLLM host. This vulnerability is fixed in 0.19.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- None
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
5.4
vLLM affected by Server-Side Request Forgery (SSRF) in `download_bytes_from_url `
vLLM is an inference and serving engine for large language models (LLMs). From 0.16.0 to before 0.19.0, a server-side request forgery (SSRF) vulnerability in download_bytes_from_url allows any actor who can control batch input JSON to make the vLLM batch runner issue arbitrary HTTP/HTTPS requests from the server, without any URL validation or domain restrictions. This can be used to target internal services (e.g. cloud metadata endpoints or internal HTTP APIs) reachable from the vLLM host. This vulnerability is fixed in 0.19.0.
- Record
CVE-2026-34753- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L - Weakness
- CWE-918
- Updated
- 2026-11-02
EUVDEUVD-2026-19349
5.4
vLLM is an inference and serving engine for large language models (LLMs). From 0.16.0 to before 0.19.0, a server-side request forgery (SSRF) vulnerability in download_bytes_from_url allows any actor who can control batch input JSON to make the vLLM batch runner issue arbitrary HTTP/HTTPS requests from the server, without any URL validation or domain restrictions. This can be used to target internal services (e.g. cloud metadata endpoints or internal HTTP APIs) reachable from the vLLM host. This vulnerability is fixed in 0.19.0.
- Record
EUVD-2026-19349- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-pf3h-qjgv-vcpr
5.4
vLLM: Server-Side Request Forgery (SSRF) in `download_bytes_from_url `
Summary
A Server Side Request Forgery (SSRF) vulnerability in download_bytes_from_url allows any actor who can control batch input JSON to make the vLLM batch runner issue arbitrary HTTP/HTTPS requests from the server, without any URL validation or domain restrictions.
This can be used to target internal services (e.g. cloud metadata endpoints or internal HTTP APIs) reachable from the vLLM host.
Details
Vulnerable component
The vulnerable logic is in the batch runner entrypoint vllm/entrypoints/openai/run_batch.py, function download_bytes_from_url:
# run_batch.py Lines 442-482
async def download_bytes_from_url(url: str) -> bytes:
"""
Download data from a URL or decode from a data URL.
Args:
url: Either an HTTP/HTTPS URL or a data URL (data:...;base64,...)
Returns:
Data as bytes
"""
parsed = urlparse(url)
# Handle data URLs (base64 encoded)
if parsed.scheme == "data":
# Format: data:...;base64,<base64_data>
if "," in url:
header, data = url.split(",", 1)
if "base64" in header:
return base64.b64decode(data)
else:
raise ValueError(f"Unsupported data URL encoding: {header}")
else:
raise ValueError(f"Invalid data URL format: {url}")
# Handle HTTP/HTTPS URLs
elif parsed.scheme in ("http", "https"):
async with (
aiohttp.ClientSession() as session,
session.get(url) as resp,
):
if resp.status != 200:
raise Exception(
f"Failed to download data from URL: {url}. Status: {resp.status}"
)
return await resp.read()
else:
raise ValueError(
f"Unsupported URL scheme: {parsed.scheme}. "
"Supported schemes: http, https, data"
)
Key properties:
- The function only parses the URL to dispatch on the scheme (
data,http,https). - For
http/https, it directly callssession.get(url)on the provided string. - There is no validation of:
- hostname or IP address,
- whether the target is internal or external,
- port number,
- path, query, or redirect target.
- This is in contrast to the multimodal media path (
MediaConnector), which implements an explicit domain allowlist.download_bytes_from_urldoes not reuse that protection.
URL controllability
The url argument is fully controlled by batch input JSON via the file_url field of BatchTranscriptionRequest / BatchTranslationRequest.
- Batch request body type:
# run_batch.py Line 67-80
class BatchTranscriptionRequest(TranscriptionRequest):
"""
Batch transcription request that uses file_url instead of file.
This class extends TranscriptionRequest but replaces the file field
with file_url to support batch processing from audio files written in JSON format.
"""
file_url: str = Field(
...,
description=(
"Either a URL of the audio or a data URL with base64 encoded audio data. "
),
)
# run_batch.py Line 98-111
class BatchTranslationRequest(TranslationRequest):
"""
Batch translation request that uses file_url instead of file.
This class extends TranslationRequest but replaces the file field
with file_url to support batch processing from audio files written in JSON format.
"""
file_url: str = Field(
...,
description=(
"Either a URL of the audio or a data URL with base64 encoded audio data. "
),
)
There is no restriction on the domain, IP, or port of file_url in these models.
- Batch input is parsed directly from the batch file:
# run_batch.py Line 139-179
class BatchRequestInput(OpenAIBaseModel):
...
url: str
body: BatchRequestInputBody
@field_validator("body", mode="plain")
@classmethod
def check_type_for_url(cls, value: Any, info:…
- Record
GHSA-pf3h-qjgv-vcpr- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L - Weakness
- CWE-918
- Updated
- 2026-11-02
NVD
5.4
vLLM is an inference and serving engine for large language models (LLMs). From 0.16.0 to before 0.19.0, a server-side request forgery (SSRF) vulnerability in download_bytes_from_url allows any actor who can control batch input JSON to make the vLLM batch runner issue arbitrary HTTP/HTTPS requests from the server, without any URL validation or domain restrictions. This can be used to target internal services (e.g. cloud metadata endpoints or internal HTTP APIs) reachable from the vLLM host. This vulnerability is fixed in 0.19.0.
- Record
CVE-2026-34753- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L - Weakness
- CWE-918
- Updated
- 2026-11-02
OSV
5.4
vLLM affected by Server-Side Request Forgery (SSRF) in `download_bytes_from_url `
vLLM is an inference and serving engine for large language models (LLMs). From 0.16.0 to before 0.19.0, a server-side request forgery (SSRF) vulnerability in download_bytes_from_url allows any actor who can control batch input JSON to make the vLLM batch runner issue arbitrary HTTP/HTTPS requests from the server, without any URL validation or domain restrictions. This can be used to target internal services (e.g. cloud metadata endpoints or internal HTTP APIs) reachable from the vLLM host. This vulnerability is fixed in 0.19.0.
- Record
CVE-2026-34753- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L - Weakness
- CWE-918
- Updated
- 2026-11-10
OSVGHSA-pf3h-qjgv-vcpr
5.4
vLLM: Server-Side Request Forgery (SSRF) in `download_bytes_from_url `
Summary
A Server Side Request Forgery (SSRF) vulnerability in download_bytes_from_url allows any actor who can control batch input JSON to make the vLLM batch runner issue arbitrary HTTP/HTTPS requests from the server, without any URL validation or domain restrictions.
This can be used to target internal services (e.g. cloud metadata endpoints or internal HTTP APIs) reachable from the vLLM host.
Details
Vulnerable component
The vulnerable logic is in the batch runner entrypoint vllm/entrypoints/openai/run_batch.py, function download_bytes_from_url:
# run_batch.py Lines 442-482
async def download_bytes_from_url(url: str) -> bytes:
"""
Download data from a URL or decode from a data URL.
Args:
url: Either an HTTP/HTTPS URL or a data URL (data:...;base64,...)
Returns:
Data as bytes
"""
parsed = urlparse(url)
# Handle data URLs (base64 encoded)
if parsed.scheme == "data":
# Format: data:...;base64,<base64_data>
if "," in url:
header, data = url.split(",", 1)
if "base64" in header:
return base64.b64decode(data)
else:
raise ValueError(f"Unsupported data URL encoding: {header}")
else:
raise ValueError(f"Invalid data URL format: {url}")
# Handle HTTP/HTTPS URLs
elif parsed.scheme in ("http", "https"):
async with (
aiohttp.ClientSession() as session,
session.get(url) as resp,
):
if resp.status != 200:
raise Exception(
f"Failed to download data from URL: {url}. Status: {resp.status}"
)
return await resp.read()
else:
raise ValueError(
f"Unsupported URL scheme: {parsed.scheme}. "
"Supported schemes: http, https, data"
)
Key properties:
- The function only parses the URL to dispatch on the scheme (
data,http,https). - For
http/https, it directly callssession.get(url)on the provided string. - There is no validation of:
- hostname or IP address,
- whether the target is internal or external,
- port number,
- path, query, or redirect target.
- This is in contrast to the multimodal media path (
MediaConnector), which implements an explicit domain allowlist.download_bytes_from_urldoes not reuse that protection.
URL controllability
The url argument is fully controlled by batch input JSON via the file_url field of BatchTranscriptionRequest / BatchTranslationRequest.
- Batch request body type:
# run_batch.py Line 67-80
class BatchTranscriptionRequest(TranscriptionRequest):
"""
Batch transcription request that uses file_url instead of file.
This class extends TranscriptionRequest but replaces the file field
with file_url to support batch processing from audio files written in JSON format.
"""
file_url: str = Field(
...,
description=(
"Either a URL of the audio or a data URL with base64 encoded audio data. "
),
)
# run_batch.py Line 98-111
class BatchTranslationRequest(TranslationRequest):
"""
Batch translation request that uses file_url instead of file.
This class extends TranslationRequest but replaces the file field
with file_url to support batch processing from audio files written in JSON format.
"""
file_url: str = Field(
...,
description=(
"Either a URL of the audio or a data URL with base64 encoded audio data. "
),
)
There is no restriction on the domain, IP, or port of file_url in these models.
- Batch input is parsed directly from the batch file:
# run_batch.py Line 139-179
class BatchRequestInput(OpenAIBaseModel):
...
url: str
body: BatchRequestInputBody
@field_validator("body", mode="plain")
@classmethod
def check_type_for_url(cls, value: Any, info:…
- Record
GHSA-pf3h-qjgv-vcpr- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L - Weakness
- CWE-918
- Updated
- 2026-11-02
OSVPYSEC-2026-3410
5.4
vLLM: Server-Side Request Forgery (SSRF) in `download_bytes_from_url `
Summary
A Server Side Request Forgery (SSRF) vulnerability in download_bytes_from_url allows any actor who can control batch input JSON to make the vLLM batch runner issue arbitrary HTTP/HTTPS requests from the server, without any URL validation or domain restrictions.
This can be used to target internal services (e.g. cloud metadata endpoints or internal HTTP APIs) reachable from the vLLM host.
Details
Vulnerable component
The vulnerable logic is in the batch runner entrypoint vllm/entrypoints/openai/run_batch.py, function download_bytes_from_url:
# run_batch.py Lines 442-482
async def download_bytes_from_url(url: str) -> bytes:
"""
Download data from a URL or decode from a data URL.
Args:
url: Either an HTTP/HTTPS URL or a data URL (data:...;base64,...)
Returns:
Data as bytes
"""
parsed = urlparse(url)
# Handle data URLs (base64 encoded)
if parsed.scheme == "data":
# Format: data:...;base64,<base64_data>
if "," in url:
header, data = url.split(",", 1)
if "base64" in header:
return base64.b64decode(data)
else:
raise ValueError(f"Unsupported data URL encoding: {header}")
else:
raise ValueError(f"Invalid data URL format: {url}")
# Handle HTTP/HTTPS URLs
elif parsed.scheme in ("http", "https"):
async with (
aiohttp.ClientSession() as session,
session.get(url) as resp,
):
if resp.status != 200:
raise Exception(
f"Failed to download data from URL: {url}. Status: {resp.status}"
)
return await resp.read()
else:
raise ValueError(
f"Unsupported URL scheme: {parsed.scheme}. "
"Supported schemes: http, https, data"
)
Key properties:
- The function only parses the URL to dispatch on the scheme (
data,http,https). - For
http/https, it directly callssession.get(url)on the provided string. - There is no validation of:
- hostname or IP address,
- whether the target is internal or external,
- port number,
- path, query, or redirect target.
- This is in contrast to the multimodal media path (
MediaConnector), which implements an explicit domain allowlist.download_bytes_from_urldoes not reuse that protection.
URL controllability
The url argument is fully controlled by batch input JSON via the file_url field of BatchTranscriptionRequest / BatchTranslationRequest.
- Batch request body type:
# run_batch.py Line 67-80
class BatchTranscriptionRequest(TranscriptionRequest):
"""
Batch transcription request that uses file_url instead of file.
This class extends TranscriptionRequest but replaces the file field
with file_url to support batch processing from audio files written in JSON format.
"""
file_url: str = Field(
...,
description=(
"Either a URL of the audio or a data URL with base64 encoded audio data. "
),
)
# run_batch.py Line 98-111
class BatchTranslationRequest(TranslationRequest):
"""
Batch translation request that uses file_url instead of file.
This class extends TranslationRequest but replaces the file field
with file_url to support batch processing from audio files written in JSON format.
"""
file_url: str = Field(
...,
description=(
"Either a URL of the audio or a data URL with base64 encoded audio data. "
),
)
There is no restriction on the domain, IP, or port of file_url in these models.
- Batch input is parsed directly from the batch file:
# run_batch.py Line 139-179
class BatchRequestInput(OpenAIBaseModel):
...
url: str
body: BatchRequestInputBody
@field_validator("body", mode="plain")
@classmethod
def check_type_for_url(cls, value: Any, info:…
- Record
PYSEC-2026-3410- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L - Updated
- 2026-11-02
Affected products
Affected packages
Public exploits
Links only. Every CVE stores no exploit code.
| Source | Link | Date |
|---|---|---|
| PoC in GitHub | Dhiaelhak-Rached/CVE-2026-34753 | 2026-05-03 |
History
| Recorded | Changed | Sources |
|---|---|---|
| facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV, PoC in GitHub |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-34753 is a medium vulnerability (CVSS 5.4) in Vllm, published April 3, 2026. Public exploit code exists. EPSS puts the chance of exploitation in the next 30 days at 0.26%, the 17th percentile. Fixed in vllm 0.19.0.
References
github.com/vllm-project/vllm/security/advisories/GHSA-pf3h-qjgv-vcpr
github.com/vllm-project/vllm/pull/38482
github.com/vllm-project/vllm/commit/57861ae48d3493fa48b4d7d830b7ec9f995783e7
nvd.nist.gov/vuln/detail/CVE-2026-34753
github.com/advisories/GHSA-pf3h-qjgv-vcpr
github.com/pypa/advisory-database/tree/main/vulns/vllm/PYSEC-2026-3410.yaml
github.com/vllm-project/vllm
pypi.org/project/vllm
github.com/CVEProject/cvelistV5/tree/main/cves/2026/34xxx/CVE-2026-34753.json
Left out here: the rest of 3 source descriptions. The JSON record has them.