Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.
Open advisories
89 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.
The audio decode-duration guard (maxdurations, env VLLMMAXAUDIODECODEDURATIONS, default 600s) that protects against audio decompression-bomb DoS is wired into only the speech-to-text path (/v1/audio/transcriptions). The chat audio path (/v1/chat/completions, inputaudio content parts) calls the same decoder with no limit, so an unauthenticated client can submit a few-KB compressed audio file that expands to multiple GB of float32 PCM at decode time, OOM-killing the worker. This is a distinct sibling of CVE-2026-5497 (video frame-count bomb, VideoMediaIO.loadbase64) and GHSA-pq5c-rjhq-qp7p (image) in the same media subsystem. Verified against main at HEAD d78650c (2026-06-16); applicable to the latest release v0.23.0. Details The guard rejects long audio during decode (before allocation), implemented in vllm/multimodal/media/audio.py: - loadaudiopyav — metadata reject (~82-98) and live sample-count reject (~129-136) - loadaudiosoundfile — frames reject (~165-174) All are gated…
Recommended action: Upgrade to 0.24.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
vllm/transformersutils/processors/mimov2omni.py — the multimodal processor for MiMoV2OmniForCausalLM — issues requests.get(...) directly on user-supplied image and audio URL strings and Image.open(...) on user-supplied local paths, without the SSRF / allowedlocalmediapath checks that vllm.multimodal.utils.MediaConnector was hardened with in GHSA-qh4c-xf7m-gxfc, GHSA-v359-jj2v-j536, and GHSA-pf3h-qjgv-vcpr. This is the same bug class as those three published advisories, in a code path the patches missed. When a user passes a URL or local-file string through multimodaldata (e.g. LLM.generate(multimodaldata={"image": "http://..."})), the processor takes the unsanitized string and dispatches it without any URL-scheme allowlist, network-target allowlist, size cap, or local-path allowlist. Details File: vllm/transformersutils/processors/mimov2omni.py (current main) Sink 1 — image SSRF + local-file read (fetchimage, lines 231–249): Sink 2 — audio SSRF (around line 471):…
Recommended action: Upgrade to 0.26.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
An integer overflow in the actandmulkernel kernel can cause the output of one user request to be incorporated into the response of another request within the same inference batch. Under certain conditions, the last request in a batch can receive a partial or complete copy of the first user's inference result, resulting in cross-user data leakage. Details The root cause is an integer overflow in the expression blockIdx.x 2 d at https://github.com/vllm-project/vllm/blob/ff712f6447093d07747c88680b9d006b119f5890/csrc/activationkernels.cu#L82. As a result, the computation for one user (User A) can incorrectly consume input data from another user (User B). In particular, when 2^32 is divisible by d, the overflow can cause User A's output to contain portions of User B's inference result. In some cases, User B's response may be copied entirely into User A's response. This constitutes a severe cross-user information disclosure vulnerability and is straightforward to trigger. PoC We…
Recommended action: Upgrade to 0.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Executive Summary The follow-up protection for CVE-2025-62164 is incomplete at vLLM revision 26587f9519e22a5c4549ead7595ad9ca3229c4fd. It wraps serialized prompt-embedding reconstruction and dense conversion in torch.sparse.checksparsetensorinvariants(), but PyTorch 2.11.0 implements that context with save/enable/restore operations over process-global state. Two prompt-embedding parts in one /v1/chat/completions request are gathered concurrently on the event loop's default executor. When one context exits before the other loads its tensor, it can restore the global flag to False while the second part remains inside its guard. In a deterministic run against hash-verified source from the affected revision, the actual target loader rejected an invalid sparse payload as a negative control. The frozen chat tracker then scheduled benign and malicious parts on distinct asyncio0 and asyncio1 threads. The benign context exited, the malicious loader observed the invariant flag disabled, and…
Recommended action: Upgrade to 0.26.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The fix for GHSA-rwxx-mrjm-wc2m ("ReDoS via structuredoutputs.regex compiled without timeout") wrapped the regex compile in the xgrammar and outlines backends with compileregexwithtimeout (and, for outlines, validateregexisbuildable). The lm-format-enforcer backend was left unguarded: it compiles the attacker-supplied regex with no timeout and no buildability check. A single request with a catastrophic regex hangs the structured-output compile step and stalls the engine worker (denial of service). Affected code (HEAD d6d39c1) vllm/v1/structuredoutput/backendlmformatenforcer.py: - line 110: characterlevelparser = lmformatenforcer.RegexParser(grammarspec) — builds an interegular FSM from the attacker regex synchronously, no timeout. - line 155: validatestructuredoutputrequestlmformatenforcer returns immediately on if soparams.regex: — no validation. Sibling backends that WERE patched by GHSA-rwxx: - backendxgrammar.py:92 → compileregexwithtimeout(...). - backendoutlines.py:65 →…
Recommended action: Upgrade to 0.26.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
When the vLLM API receives a malformed request (e.g., invalid JSON or missing required fields), FastAPI raises a Pydantic RequestValidationError. The validationexceptionhandler in vllm/entrypoints/openai/serverutils.py converts this exception to a string via str(exc), which includes the internal file path and line number of the handler function. The existing sanitizemessage() function in vllm/entrypoints/utils.py strips memory addresses (e.g., 0x7f...) but does not strip File "...", line X patterns. The result is a user-facing HTTP response that leaks internal system information. Impact An unauthenticated attacker can extract the following with a single malformed request: - OS username running the vLLM process (e.g., ubuntu) - Home directory path (e.g., /home/ubuntu/) - Virtual environment path (e.g., vllm-env/) - Python version (e.g., 3.12) - Internal package structure and line numbers (e.g., vllm/entrypoints/openai/chatcompletion/apirouter.py) - Handler function names per…
Recommended action: Upgrade to 0.26.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The /v1/completions/derender and /v1/chat/completions/derender endpoints accept caller-supplied GenerateResponse objects and postprocess every nested choices[].tokenids list directly. Unlike the normal render/generate path, derender does not enforce model context length, resolved maxtokens, maxnumseqs, choice-count, or response-size bounds before detokenizing and returning the supplied token IDs. An authenticated API client can therefore make the CPU-only render frontend, or any server exposing these /v1 derender routes, spend CPU and memory proportional to attacker-chosen generated-output-shaped JSON rather than to a bounded generation result. Technical Details The render router registers /v1/chat/completions/derender and /v1/completions/derender in vllm/entrypoints/serve/render/apirouter.py, and the OpenAI API server attaches this router whenever "generate" or "render" is in supportedtasks (vllm/entrypoints/openai/apiserver.py). The routes are under /v1, so they are part of…
Recommended action: Upgrade to 0.26.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The /v1/completions request model accepts prompt as a list of text prompts or a list of token-id prompts without any outer prompt-count bound. The serving path turns each element into a separate engine input, creates one engine generator per element, merges all generators, and allocates a response slot per prompt. An authenticated API client can therefore turn one request into an attacker-chosen number of backend subrequests before any aggregate request-count budget is enforced. Technical Details CompletionRequest.prompt allows both list-shaped prompt inputs and scalar prompts: The validator only requires some prompt-like input to be present: The renderer then expands list-shaped prompts as a sequence. prompttoseq() wraps a scalar string or a single token-id list, but returns a list[str] or list[list[int]] unchanged: OnlineRenderer.preprocesscompletion() appends that whole sequence, and the renderer processes every element: Finally, completion serving creates one backend…
Recommended action: Upgrade to 0.26.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Short summary of the problem. Make the impact and severity as clear as possible. For example: An unsafe deserialization vulnerability allows any unauthenticated user to execute arbitrary code on the server. Sending a pure prompt embeds payload in a /v1/completions request with a model using M-RoPE causes the EngineCore to fail an assertion and fatally crash, shutting down the entire server application. Any remote user who is authorized to make a /v1/completions endpoint can trivially make such a request and induce a crash. Details Give all details on the vulnerability. Pointing to the incriminated source code is very helpful for the maintainer. In commit 56669c1, a simple assert intended to be a type-narrowing assert was added to the initmropepositions method in GPUModelRunner (the offending line on main at the time of writing: https://github.com/vllm-project/vllm/blob/2d481f8a946ee0521872af0f098674a8ee01ce4a/vllm/v1/worker/gpumodelrunner.py#L1588-L1607). This type narrowing…
Recommended action: Upgrade to 0.24.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Current-head vLLM documents VLLMMAXAUDIOCLIPFILESIZEMB as the maximum audio file size accepted by the speech-to-text APIs. The default is 25 MB. vllm/envs.py also describes files larger than this value as rejected. The /v1/audio/transcriptions and /v1/audio/translations routes call await request.file.read() before vLLM checks that limit. In FastAPI and Starlette, UploadFile.read() returns bytes from the uploaded file object; when called without a size argument, the route materializes the remaining file contents. vLLM then performs the compressed file-size check later in preprocessspeechtotext() against the already-created bytes object. As a result, the documented compressed audio file-size limit does not bound the memory allocated by vLLM endpoint code before validation. An oversized multipart upload can cause vLLM to allocate memory proportional to the uploaded file size before rejecting the request as too large. This is distinct from GHSA-6pr9-rp53-2pmc, which covered…
Recommended action: Upgrade to 0.24.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The structuredoutputs.regex API parameter passes a user-supplied regex string directly to grammar compiler backends with no compilation timeout. In the xgrammar backend, the string reaches compileregex() with no guard. In the outlines backend, validateregexisbuildable() blocks structural issues (lookarounds, backreferences) but provides zero protection against exponential DFA state-space explosion. Patterns like (a+)+b pass all checks and hang the inference worker. Root Cause backendxgrammar.py:91 — no timeout: backendoutlines.py:299–330 — structural checks only, no complexity analysis: backendoutlines.py:64 — no timeout: Impact Denial of service — one request with an adversarial regex pattern hangs an inference worker indefinitely. Remediation Wrap compileregex() and oc.Index() calls in a thread with a deadline (e.g., 5 seconds). Add complexity analysis to validateregexisbuildable() to detect nested quantifier patterns before compilation.
Recommended action: Upgrade to 0.24.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
A frontend-legal multi-request speculative workload can make vLLM produce an out-of-vocabulary recovered token equal to vocabsize, convert that value to -1 when choosing the next live token for a request, and then feed that -1 back into the next drafter input ids. On Qwen3 GPTQ this reaches the worker-side drafting / attention path and crashes the engine with a GPU device-side assert. The same issue is reachable through the public gRPC request surface by sending a specific overlapping Generate / Abort sequence. Impact - A remote client that can send public gRPC generation requests can crash the shared vLLM engine worker - The triggering request sequence aborts concurrent requests and prevents later requests from completing until the worker is restarted - In shared deployments, this is a service-wide denial of service for other clients, not just a failure isolated to the attacking requests - The failure is reproducible, so repeated request sequences can sustain the outage…
Recommended action: Upgrade to 0.24.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Issue Description Librosa defaults to using numpy.mean for mono downmixing (tomono), while the international standard ITU-R BS.775-4 specifies a weighted downmixing algorithm. This discrepancy results in: - Inconsistency between audio heard by humans (e.g., through headphones/regular speakers) and audio processed by AI models (Which infra via Librosa, such as vllm, transformer). https://github.com/librosa/librosa/blob/af8c839fb15317fa2712ea66e7a22da6a9267b32/librosa/core/audio.py#L478 Attack Scenario and Impact LFE (Low-Frequency Effects) Channel Exploit Attackers can craft special multichannel audio files containing: 1. Normal content in front channels (L/R) 2. Either interference signals or hidden content in the LFE channel Notice: It is worth noting that not only the LFE channel is excluded, but in fact, channels beyond the 6th (such as rear surround channels, overhead channels, height speakers, etc.) are also not supported. Attack Methodology: Attackers can create specially…
Recommended action: Upgrade to 0.18.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
vLLM is an inference and serving engine for large language models (LLMs). Prior to 0.22.1, the vLLM Dockerfile is vulnerable to a dependency confusion attack through the flashinfer-jit-cache package. The package is installed from a custom index (flashinfer.ai/whl/) using --extra-index-url, but the package name was not registered on PyPI, and UV_INDEX_STRATEGY="unsafe-best-match" is set globally. An attacker who registers flashinfer-jit-cache on PyPI with version 0.6.11.post2 can execute arbitrary code as root during the Docker build and backdoor every resulting container image, enabling exfiltration of all user prompts, API credentials, and model data from production vLLM deployments This vulnerability is fixed in 0.22.1.
Recommended action: Upgrade to 0.22.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
vLLM's /v1/audio/transcriptions endpoint limits compressed upload size but not decoded PCM output. A 25MB OPUS file expands to ~14.9GB of float32 PCM at decode time. Tested on vLLM v0.19.0. Details SpeechToTextProcessor rejects uploads over VLLMMAXAUDIOCLIPFILESIZEMB (default 25MB) based on compressed byte length, but the audio decoder in audio.py accumulates all decoded frames into memory with no size limit before returning: A 25MB OPUS file at 6kbps encodes ~8.7 hours of audio. Decoding produces ~5.7GB of float32 PCM (232x amplification), and np.concatenate then allocates a second contiguous array, bringing peak RSS to ~14.9GB from a single request. SpeechToTextConfig.maxaudioclips (default 30s) applies only after the full decode and does not prevent the allocation. Impact An unauthenticated attacker can exhaust server memory with a small number of concurrent requests, each a valid upload within the documented size limit. Severity was assessed with reference to prior OOM…
Recommended action: Upgrade to 0.24.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
vLLM: incomplete CVE-2026-22778 fix leaks PIL repr addresses via the Anthropic API router Researcher: Kai Aizen — SnailSploit (@SnailSploit), Adversarial & Offensive Security Research Severity: CVSS 3.1 5.3 (Medium) AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N Target: https://github.com/vllm-project/vllm --- Summary The fix for CVE-2026-22778 / GHSA-4r2x-xpjr-7cvv (PRs #31987 and #32319) introduced sanitizemessage and applied it at four FastAPI exception-handling sites in the OpenAI router. The sanitizer strips object-repr memory addresses (<io.BytesIO object at 0x7a95e299e750 → <io.BytesIO object) before error messages reach the client, defeating the ASLR-bypass primitive that CVE-2026-22778 chained with a libopenjp2 heap overflow for RCE. The fix is incomplete: response paths added to vLLM at or after the same time as the fix continue to echo str(exc) directly to clients without sanitizemessage. The original Stage 1 primitive — sending malformed image bytes so PIL raises…
Recommended action: Upgrade to 0.24.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Integer truncation of tensor dimensions in vLLM's GGUF dequantize kernels (csrc/quantization/gguf/ggufkernel.cu) causes partial tensor processing. The output tensor is allocated at full size via torch::empty (uninitialized memory), but the dequantize CUDA kernel processes only a truncated number of elements. The unfilled portion of the output tensor retains whatever was previously in GPU memory. In multi-tenant inference deployments, this residual GPU memory may contain tensor data from other users' inference requests, constituting information disclosure. Root Cause The tocudaggmlt function pointer type at ggml-common.h:1067 declares its element count parameter as int (32-bit): All dequantize kernel functions (dequantizeblockcuda, dequantizerowq2Kcuda, etc. in dequantize.cuh) inherit this int k parameter and use it as the kernel launch grid size: In ggmldequantize() at ggufkernel.cu:85, the caller passes m n (an int64t product) to this int k parameter: When m n INTMAX, the…
Recommended action: Upgrade to 0.24.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Issue 1: EXIF orientation not normalized → The image orientation processed by the model differs from how humans view it, introducing interpretation bias. Issue 2: PNG tRNS not explicitly flattened before converting to RGB → After conversion, transparent/semi-transparent pixels are rendered unexpectedly, making otherwise subtle overlay elements visible and distorting the input content. (This attack is similar to AlphaDog: RGBA handling is already correct in vLLM, but since tRNS permits RGB images, the correct processing path isn’t taken.) Issue 3 : Pillow only loads the first frame when loading APNG or GIF files. --- Root Cause Rotation: After opening an image, ImageOps.exiftranspose is not called to normalize EXIF orientation. Transparency: Only RGBA→RGB is flattened with a background; PNGs carrying tRNS in P/L/RGB + tRNS and other non-RGBA modes take the image.convert("RGB") path, which implicitly discards/remaps transparency semantics. --- Affected Code…
Recommended action: Upgrade to 0.24.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
All temperature validation gates use comparison operators (<, ), which silently evaluate to False for NaN and for positive Infinity in Python's IEEE 754 float semantics. Both values pass every guard and propagate to GPU sampling kernels, where they produce undefined behavior or CUDA errors that can crash the inference worker. Note: -Infinity is correctly caught. Root Cause samplingparams.py:384: samplingparams.py:462: No math.isnan() or math.isinf() check exists anywhere in samplingparams.py. Python semantics (verified): float('nan') < 0.0 → False, float('inf') < 0.0 → False. Impact Crash of inference worker on GPU kernel execution with NaN/Inf softmax input, degrading service for all concurrent users. Remediation Add math.isfinite(self.temperature) check in verifyargs(). Reject non-finite float values with a 400 error. Fix A fix for this vulnerability was merged here: https://github.com/vllm-project/vllm/pull/45116
Recommended action: Upgrade to 0.24.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
A vulnerability in ASGI web servers and starlette's trust on those web servers enables an authentication bypass of the OpenAI API AuthenticationMiddleware, which was discovered during @x41sec's source code audit. It allows to use the API without providing the configured VLLMAPIKEY or --api-key. Details In https://github.com/vllm-project/vllm/blob/v0.14.0/vllm/entrypoints/openai/apiserver.py#L689-L692 the urlpath is taken from the URL, which is reconstructed by starlette based on the request scope. The request scope includes the request's Host: header and reconstructs the URL as shown below: Neither starlette nor any of the ASGI servers (including uvicorn, which vllm uses) properly filter the Host: header for invalid characters. This allows an attacker to include special URL characters such as / or ? in the Host: header and thereby control the reconstructed URL and it's .path attribute. FastAPI/starlette's routing uses the HTTP path and does not depend on the parsed url.path…
Recommended action: Upgrade to 0.22.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
An assert-based security check in vLLM's activation function loading allows any unauthenticated attacker to achieve arbitrary code execution on the server by publishing a malicious HuggingFace model, when vLLM runs in Python optimized mode (python -O or PYTHONOPTIMIZE=1). Details vLLM uses an assert statement at vllm/modelexecutor/layers/pooler/activations.py:48 as its sole security control to restrict which activation functions can be loaded from a HuggingFace model's config.json: Python's assert statements are stripped at compile time when running in optimized mode (python -O or PYTHONOPTIMIZE=1). When the assert is absent, the attacker-controlled functionname from the model's config.json is passed directly to resolveobjbyqualname() — an unrestricted import gadget: This is the same vulnerability class as CVE-2017-1000433 (pysaml2 assert-based auth bypass), flagged by Bandit B101 and Ruff S101, and the reason Django proactively replaced all assert-based security checks…
Recommended action: Upgrade to 0.22.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
vLLM versions 0.8.0 and later are vulnerable to an Out-of-Memory (OOM) Denial of Service (DoS) attack due to unbounded frame count processing in the VideoMediaIO.loadbase64() method. When processing video/jpeg data URLs, the method splits the base64 data string on commas to extract individual JPEG frames without enforcing a frame count limit. An attacker can exploit this by crafting a single API request containing thousands of comma-separated base64-encoded JPEG frames in a data URL, causing the server to decode all frames into memory and crash due to excessive memory consumption. This vulnerability is reachable via the OpenAI-compatible chat completions API and does not require authentication.
Recommended action: Upgrade to 0.19.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
vLLM's revision pinning controls do not consistently apply to all artifacts loaded for a model. A deployment that supplies --revision or --code-revision can still load dynamic code, GGUF files, image processors, retrieval side weights, or same-repository subfolder weights/config from an unpinned/default revision. This is a supply-chain integrity issue for pinned vLLM deployments. Operators can believe they are serving a reviewed model revision while vLLM resolves behavior-affecting nested or sibling artifacts outside that reviewed revision. Details The expected invariant is: When a vLLM operator supplies a model or code revision pin, every code, config, processor, weight file, side weight, and same-repository subfolder artifact loaded as part of that model should resolve under that pin unless vLLM exposes and enforces a separate explicit pin for that artifact. Current main was verified affected at commit 3795d7acf431980e62e738493f437ae2a51549da. Affected source boundaries: -…
Recommended action: Upgrade to 0.22.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The extracthiddenstates speculative decoding proposer in vLLM returns a tensor with an incorrect shape after the first decode step, causing a RuntimeError that crashes the EngineCore process. The crash is triggered when any request in the batch uses sampling penalty parameters (repetitionpenalty, frequencypenalty, or presencepenalty). A single request with a penalty parameter (e.g., "repetitionpenalty": 1.1) is sufficient to crash the server. The crash is deterministic and immediate — no concurrency, race condition, or special workload is required. Details In vLLM v0.17.0, the extracthiddenstates proposer's propose() method returned sampledtokenids.unsqueeze(-1), producing a tensor of shape (batchsize, 1). In PR #37013 (first released in v0.18.0), the KV connector interface was refactored out of propose(). The return type changed from tuple[Tensor, KVConnectorOutput | None] to Tensor, and the .unsqueeze(-1) call was removed along with the KV connector output: The refactor…
Recommended action: Upgrade to 0.20.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
This report explains a Token Injection vulnerability in vLLM’s multimodal processing. Unauthenticated, text-only prompts that spell special tokens are interpreted as control. Image and video placeholder sequences supplied without matching data cause vLLM to index into empty grids during input-position computation, raising an unhandled IndexError and terminating the worker or degrading availability. Multimodal paths that rely on imagegridthw/videogridthw are affected. Severity: High (remote DoS). Reproduced on vLLM 0.10.0 with Qwen2.5-VL. Details - Affected component: multimodal input position computation. - File/functions (paths are indicative): - vllm/modelexecutor/layers/rotaryembedding.py - getinputpositionstensor(...) - vlgetinputpositionstensor(...) - Failure mechanism: - The code counts detected vision tokens and then indexes videogridthw/imagegridthw accordingly. - When user input carries placeholder tokens but no actual multimodal payload, these grids are empty. The…
Recommended action: Upgrade to 0.20.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.