@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / ad87ba927a
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 14, 05:30 UTC

[Small] Prevent bypassing media domain restriction via HTTP redirects (#26035)

Signed-off-by: Chenheli Hua <huachenheli@outlook.com>

Chenheli Hua committed Oct 2, 2025 at 10:27 UTC ad87ba927ad83249fe7c40032290438b38b3f2f9
5 files changed +40 -8
docs/features/multimodal_inputs.md
+3
@@ -8,6 +8,9 @@ This page teaches you how to pass multi-modal inputs to [multi-modal models][sup
8
9 !!! tip
10 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`
11 +
12 + Also, consider setting `VLLM_MEDIA_URL_ALLOW_REDIRECTS=0` to prevent HTTP redirects from being followed to bypass domain restrictions.
13 +
14 This restriction is especially important if you run vLLM in a containerized environment where the vLLM pods may have unrestricted access to internal networks.
15
16 ## Offline Inference
docs/usage/security.md
+3
@@ -66,6 +66,9 @@ Restrict domains that vLLM can access for media URLs by setting
66 `--allowed-media-domains` to prevent Server-Side Request Forgery (SSRF) attacks.
67 (e.g. `--allowed-media-domains upload.wikimedia.org github.com www.bogotobogo.com`)
68
69 +Also, consider setting `VLLM_MEDIA_URL_ALLOW_REDIRECTS=0` to prevent HTTP
70 +redirects from being followed to bypass domain restrictions.
71 +
72 ## Security and Firewalls: Protecting Exposed vLLM Systems
73
74 While vLLM is designed to allow unsafe network services to be isolated to
vllm/connections.py
+18 -6
@@ -54,6 +54,7 @@ class HTTPConnection:
54 stream: bool = False,
55 timeout: Optional[float] = None,
56 extra_headers: Optional[Mapping[str, str]] = None,
57 + allow_redirects: bool = True,
58 ):
59 self._validate_http_url(url)
60
@@ -63,7 +64,8 @@ class HTTPConnection:
64 return client.get(url,
65 headers=self._headers(**extra_headers),
66 stream=stream,
66 - timeout=timeout)
67 + timeout=timeout,
68 + allow_redirects=allow_redirects)
69
70 async def get_async_response(
71 self,
@@ -71,6 +73,7 @@ class HTTPConnection:
73 *,
74 timeout: Optional[float] = None,
75 extra_headers: Optional[Mapping[str, str]] = None,
76 + allow_redirects: bool = True,
77 ):
78 self._validate_http_url(url)
79
@@ -79,10 +82,17 @@ class HTTPConnection:
82
83 return client.get(url,
84 headers=self._headers(**extra_headers),
82 - timeout=timeout)
83 -
84 - def get_bytes(self, url: str, *, timeout: Optional[float] = None) -> bytes:
85 - with self.get_response(url, timeout=timeout) as r:
85 + timeout=timeout,
86 + allow_redirects=allow_redirects)
87 +
88 + def get_bytes(self,
89 + url: str,
90 + *,
91 + timeout: Optional[float] = None,
92 + allow_redirects: bool = True) -> bytes:
93 + with self.get_response(url,
94 + timeout=timeout,
95 + allow_redirects=allow_redirects) as r:
96 r.raise_for_status()
97
98 return r.content
@@ -92,8 +102,10 @@ class HTTPConnection:
102 url: str,
103 *,
104 timeout: Optional[float] = None,
105 + allow_redirects: bool = True,
106 ) -> bytes:
96 - async with await self.get_async_response(url, timeout=timeout) as r:
107 + async with await self.get_async_response(
108 + url, timeout=timeout, allow_redirects=allow_redirects) as r:
109 r.raise_for_status()
110
111 return await r.read()
vllm/envs.py
+6
@@ -68,6 +68,7 @@ if TYPE_CHECKING:
68 VLLM_IMAGE_FETCH_TIMEOUT: int = 5
69 VLLM_VIDEO_FETCH_TIMEOUT: int = 30
70 VLLM_AUDIO_FETCH_TIMEOUT: int = 10
71 + VLLM_MEDIA_URL_ALLOW_REDIRECTS: bool = True
72 VLLM_MEDIA_LOADING_THREAD_COUNT: int = 8
73 VLLM_MAX_AUDIO_CLIP_FILESIZE_MB: int = 25
74 VLLM_VIDEO_LOADER_BACKEND: str = "opencv"
@@ -733,6 +734,11 @@ environment_variables: dict[str, Callable[[], Any]] = {
734 "VLLM_AUDIO_FETCH_TIMEOUT":
735 lambda: int(os.getenv("VLLM_AUDIO_FETCH_TIMEOUT", "10")),
736
737 + # Whether to allow HTTP redirects when fetching from media URLs.
738 + # Default to True
739 + "VLLM_MEDIA_URL_ALLOW_REDIRECTS":
740 + lambda: bool(int(os.getenv("VLLM_MEDIA_URL_ALLOW_REDIRECTS", "1"))),
741 +
742 # Max number of workers for the thread pool handling
743 # media bytes loading. Set to 1 to disable parallel processing.
744 # Default is 8
vllm/multimodal/utils.py
+10 -2
@@ -140,7 +140,11 @@ class MediaConnector:
140 self._assert_url_in_allowed_media_domains(url_spec)
141
142 connection = self.connection
143 - data = connection.get_bytes(url, timeout=fetch_timeout)
143 + data = connection.get_bytes(
144 + url,
145 + timeout=fetch_timeout,
146 + allow_redirects=envs.VLLM_MEDIA_URL_ALLOW_REDIRECTS,
147 + )
148
149 return media_io.load_bytes(data)
150
@@ -167,7 +171,11 @@ class MediaConnector:
171 self._assert_url_in_allowed_media_domains(url_spec)
172
173 connection = self.connection
170 - data = await connection.async_get_bytes(url, timeout=fetch_timeout)
174 + data = await connection.async_get_bytes(
175 + url,
176 + timeout=fetch_timeout,
177 + allow_redirects=envs.VLLM_MEDIA_URL_ALLOW_REDIRECTS,
178 + )
179 future = loop.run_in_executor(global_thread_pool,
180 media_io.load_bytes, data)
181 return await future