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