VLLM · GHSA-894j-wg8m-63h8 · AI agents & MCP
FIX → 0.31.0
vLLM's OpenCV video backend uses a request-supplied num_frames value with no upper limit, so the frame-index allocation grows with whatever a client sends. An unauthenticated request to the chat completions endpoint that selects this backend can exhaust memory and CPU in the API server process until it is killed.
first public Oct 27, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Any vLLM deployment on a version from 0.30.0 up to but not including 0.31.0 that accepts video input is exposed, because the request can select the video backend without any model opting into it. The advisory says no specific model or non-default flag is required, and no authentication is needed. Deployments that are not video-capable, or that are already on 0.31.0 or later, are not covered by this advisory.
Not affected if on-vllm-0.31.0-or-later
Who cares multimodal, openai-compatible-api, self-hosted, vllm
pip show vllm; versions >= 0.30.0 and < 0.31.0 are affected.--trust-request-mm-kwargs; the advisory says to keep it disabled for untrusted clients.OpenCVDynamicOpenPanguVideoBackend (vllm/multimodal/video.py:1222-1260) drives its frame-index computation from the request-controlled num_frames with no ceiling. The backend is registered without a video_processor binding, so no model selects it by default — but VideoMediaIO honors request-level media_io_kwargs.video.video_backend for any registered CPU loader (merge_kwargs, vllm/multimodal/media/video.py:42-90, strips only hw_decoders/pool_size/device/unconfigured-GPU backends and clamps none of the sampling knobs). One unauthenticated POST /v1/chat/completions (or /tokenize) with routes any video through this sampler on — no GLM/OpenPangu model required, no non-default flags, no auth.
Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
Upgrade to 0.31.0
0.31.0 or later.--trust-request-mm-kwargs disabled for untrusted clients."video_backend": "openpangu"num_frames = target.num_frames # request-controlled, unclamped
fps = target.fps # request-controlled
if fps > 0:
if num_frames >= int(total_duration * fps) + 1:
num_frames = int(total_duration * fps) + 1 # clamp only fires when ABOVE duration*fps
...
sample_frame_timestamps = np.linspace(0, total_duration, num_frames, dtype=float)
frames_indices = [min(total_frames_num - 1, round(t * original_fps))
for t in sample_frame_timestamps]
The only clamp fires when num_frames >= int(duration*fps)+1. Choosing num_frames just below that bound — or fps=-1, which skips the branch entirely — leaves the request value untouched: np.linspace(0, d, num_frames) allocates 8 × num_frames bytes and the Python comprehension walks every element, inside the API-server process.
Measured in-process (official CPU image, vllm/vllm-openai-cpu:latest v0.30.0):
num_frames=1e7 → 462 MB peak, 118 s CPUnum_frames=1e9 → ~46 GB / hours (linear extrapolation) → OOM-killThis is an instance of the published unclamped-num_frames family (GHSA-vxqj-p4gw-9h4c; central clamp PR #51969 subsequently superseded by #58830), with two aggravating differences: the sink is a distinct np.linspace + list-comprehension allocation, and the backend is reachable via request-level backend selection without any model opting into it.
num_frames before np.linspace (e.g. min(num_frames, total_frames_num) or a class-level cap) and treat fps=-1 the same.num_frames clamp in VideoMediaIO.merge_kwargs (where PR #51969 is adding it) so per-backend audits stop missing siblings, and consider gating request-level video_backend selection to an allowlist.vllm/multimodal/media/video.py:42-90 (merge_kwargs: no clamp on num_frames/fps; GPU-only gating for video_backend); sink at vllm/multimodal/video.py:1222-1260.
vllm (PyPI).>= 0.30.0, < 0.31.0.0.31.0.PR #58830 blocks untrusted per-request mm_processor_kwargs and media_io_kwargs by default before preprocessing. Keep --trust-request-mm-kwargs disabled for untrusted clients. Explicitly enabling it restores trusted override behavior; the underlying processor/sampler is not independently bounded by this fix.
The lower bound records the verified affected v0.30.0 release. The backend predates that release; earlier request-path exposure has not been comprehensively assessed.
Advisory fixed in #58830.