High severity7.1GHSA Advisory· Published Oct 7, 2025· Updated Apr 15, 2026
CVE-2025-6242
CVE-2025-6242
Description
A Server-Side Request Forgery (SSRF) vulnerability exists in the MediaConnector class within the vLLM project's multimodal feature set. The load_from_url and load_from_url_async methods fetch and process media from user-provided URLs without adequate restrictions on the target hosts. This allows an attacker to coerce the vLLM server into making arbitrary requests to internal network resources.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
vllmPyPI | >= 0.5.0, < 0.11.0 | 0.11.0 |
Affected products
1Patches
19d9a2b77f19f[Small] Prevent bypassing media domain restriction via HTTP redirects (#26035)
5 files changed · +40 −8
docs/features/multimodal_inputs.md+3 −0 modified@@ -8,6 +8,9 @@ This page teaches you how to pass multi-modal inputs to [multi-modal models][sup !!! tip When serving multi-modal models, consider setting `--allowed-media-domains` to restrict domain that vLLM can access to prevent it from accessing arbitrary endpoints that can potentially be vulnerable to Server-Side Request Forgery (SSRF) attacks. You can provide a list of domains for this arg. For example: `--allowed-media-domains upload.wikimedia.org github.com www.bogotobogo.com` + + Also, consider setting `VLLM_MEDIA_URL_ALLOW_REDIRECTS=0` to prevent HTTP redirects from being followed to bypass domain restrictions. + This restriction is especially important if you run vLLM in a containerized environment where the vLLM pods may have unrestricted access to internal networks. ## Offline Inference
docs/usage/security.md+3 −0 modified@@ -66,6 +66,9 @@ Restrict domains that vLLM can access for media URLs by setting `--allowed-media-domains` to prevent Server-Side Request Forgery (SSRF) attacks. (e.g. `--allowed-media-domains upload.wikimedia.org github.com www.bogotobogo.com`) +Also, consider setting `VLLM_MEDIA_URL_ALLOW_REDIRECTS=0` to prevent HTTP +redirects from being followed to bypass domain restrictions. + ## Security and Firewalls: Protecting Exposed vLLM Systems While vLLM is designed to allow unsafe network services to be isolated to
vllm/connections.py+18 −6 modified@@ -54,6 +54,7 @@ def get_response( stream: bool = False, timeout: Optional[float] = None, extra_headers: Optional[Mapping[str, str]] = None, + allow_redirects: bool = True, ): self._validate_http_url(url) @@ -63,14 +64,16 @@ def get_response( return client.get(url, headers=self._headers(**extra_headers), stream=stream, - timeout=timeout) + timeout=timeout, + allow_redirects=allow_redirects) async def get_async_response( self, url: str, *, timeout: Optional[float] = None, extra_headers: Optional[Mapping[str, str]] = None, + allow_redirects: bool = True, ): self._validate_http_url(url) @@ -79,10 +82,17 @@ async def get_async_response( return client.get(url, headers=self._headers(**extra_headers), - timeout=timeout) - - def get_bytes(self, url: str, *, timeout: Optional[float] = None) -> bytes: - with self.get_response(url, timeout=timeout) as r: + timeout=timeout, + allow_redirects=allow_redirects) + + def get_bytes(self, + url: str, + *, + timeout: Optional[float] = None, + allow_redirects: bool = True) -> bytes: + with self.get_response(url, + timeout=timeout, + allow_redirects=allow_redirects) as r: r.raise_for_status() return r.content @@ -92,8 +102,10 @@ async def async_get_bytes( url: str, *, timeout: Optional[float] = None, + allow_redirects: bool = True, ) -> bytes: - async with await self.get_async_response(url, timeout=timeout) as r: + async with await self.get_async_response( + url, timeout=timeout, allow_redirects=allow_redirects) as r: r.raise_for_status() return await r.read()
vllm/envs.py+6 −0 modified@@ -68,6 +68,7 @@ VLLM_IMAGE_FETCH_TIMEOUT: int = 5 VLLM_VIDEO_FETCH_TIMEOUT: int = 30 VLLM_AUDIO_FETCH_TIMEOUT: int = 10 + VLLM_MEDIA_URL_ALLOW_REDIRECTS: bool = True VLLM_MEDIA_LOADING_THREAD_COUNT: int = 8 VLLM_MAX_AUDIO_CLIP_FILESIZE_MB: int = 25 VLLM_VIDEO_LOADER_BACKEND: str = "opencv" @@ -725,6 +726,11 @@ def get_vllm_port() -> Optional[int]: "VLLM_AUDIO_FETCH_TIMEOUT": lambda: int(os.getenv("VLLM_AUDIO_FETCH_TIMEOUT", "10")), + # Whether to allow HTTP redirects when fetching from media URLs. + # Default to True + "VLLM_MEDIA_URL_ALLOW_REDIRECTS": + lambda: bool(int(os.getenv("VLLM_MEDIA_URL_ALLOW_REDIRECTS", "1"))), + # Max number of workers for the thread pool handling # media bytes loading. Set to 1 to disable parallel processing. # Default is 8
vllm/multimodal/utils.py+10 −2 modified@@ -140,7 +140,11 @@ def load_from_url( self._assert_url_in_allowed_media_domains(url_spec) connection = self.connection - data = connection.get_bytes(url, timeout=fetch_timeout) + data = connection.get_bytes( + url, + timeout=fetch_timeout, + allow_redirects=envs.VLLM_MEDIA_URL_ALLOW_REDIRECTS, + ) return media_io.load_bytes(data) @@ -167,7 +171,11 @@ async def load_from_url_async( self._assert_url_in_allowed_media_domains(url_spec) connection = self.connection - data = await connection.async_get_bytes(url, timeout=fetch_timeout) + data = await connection.async_get_bytes( + url, + timeout=fetch_timeout, + allow_redirects=envs.VLLM_MEDIA_URL_ALLOW_REDIRECTS, + ) future = loop.run_in_executor(global_thread_pool, media_io.load_bytes, data) return await future
Vulnerability mechanics
Synthesis attempt was rejected by the grounding validator. Re-run pending.
References
6- github.com/advisories/GHSA-3f6c-7fw2-ppm4ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-6242ghsaADVISORY
- access.redhat.com/security/cve/CVE-2025-6242nvdWEB
- bugzilla.redhat.com/show_bug.cginvdWEB
- github.com/vllm-project/vllm/commit/9d9a2b77f19f68262d5e469c4e82c0f6365ad72dghsaWEB
- github.com/vllm-project/vllm/security/advisories/GHSA-3f6c-7fw2-ppm4ghsaWEB
News mentions
0No linked articles in our index yet.