Where
-Infinity
0
Severity
8.8
AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

Summary

Two model implementation files hardcode trustremotecode=True when loading sub-components, bypassing the user's explicit --trust-remote-code=False security opt-out. This enables remote code execution via malicious model repositories even when the user has explicitly disabled remote code trust.

### Details

Affected files (latest main branch):

1. vllm/modelexecutor/models/nemotronvl.py:430 python visionmodel = AutoModel.fromconfig(config.visionconfig, trustremotecode=True)

2. vllm/modelexecutor/models/kimik25.py:177 python cachedgetimageprocessor(self.ctx.modelconfig.model, trustremotecode=True)

Both pass a hardcoded trustremotecode=True to HuggingFace API calls, overriding the user's global --trust-remote-code=False setting.

Relation to prior CVEs: - CVE-2025-66448 fixed automap resolution in vllm/transformersutils/config.py (config loading path) - CVE-2026-22807 fixed broader automap at startup - Both fixes are present in the current code. These hardcoded instances in model files survived both patches — different code paths.

Impact

Remote code execution. An attacker can craft a malicious model repository that executes arbitrary Python code when loaded by vLLM, even when the user has explicitly set --trust-remote-code=False. This undermines the security guarantee that trustremotecode=False is intended to provide.

Remediation: Replace hardcoded trustremotecode=True with self.config.modelconfig.trustremotecode in both files. Raise a clear error if the model component requires remote code but the user hasn't opted in.

1 / 2
Source: GitHub
First published (updated )
Severity
8.8
Path Traversal
AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

vllm-project/vllm version 0.14.1 contains a vulnerability where the trustremotecode=True parameter is hardcoded in two model implementation files (vllm/modelexecutor/models/nemotronvl.py and vllm/modelexecutor/models/kimik25.py). This bypasses the user's explicit --trust-remote-code=False setting, enabling remote code execution via malicious HuggingFace model repositories. This issue is an incomplete fix for CVE-2025-66448 and CVE-2026-22807, as it affects separate code paths in model implementation files. Deployments loading NemotronVL or KimiK25 models are particularly impacted.

First published (updated )
Severity
8.8
AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

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 UVINDEXSTRATEGY="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.

First published (updated )
Severity
8.7
Input Validation
AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

vLLM versions >= 0.10.2 and < 0.13.0 are missing sparse tensor validation in multimodal embeddings processing. Because PyTorch disables sparse tensor invariant checks by default, an attacker can submit crafted embedding requests with malformed (negative or out-of-bounds) tensor indices, when the prompt-embeds feature is enabled, to trigger crashes or resource exhaustion (denial of service), with potential for out-of-bounds/write-what-where memory corruption. This continues CVE-2025-62164, whose prior fix only disabled the feature by default rather than addressing the root cause.

First published (updated )
Severity
8.7
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

vLLM from 0.18.0 before 0.31.0 contains a resource exhaustion vulnerability that allows API clients to bypass the video/jpeg frame-count cap by overriding numframes through mediaiokwargs. Attackers can set numframes to -1 with a large inline video so VideoMediaIO.loadbase64 decodes every frame, exhausting memory and crashing the API frontend.

First published (updated )
Severity
7.5
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

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.

First published (updated )
Severity
6.9
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

vllm before 0.29.0 fails to enforce VLLMMAXAUDIOCLIPFILESIZEMB limit in multimodal chat audio decoding, allowing unauthenticated clients to bypass file size restrictions. Attackers can submit oversized audio files through chat endpoints to consume excessive memory and CPU resources during decoding.

First published (updated )
Severity
6.9
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

vLLM 0.30.0 before 0.31.0 contains a resource exhaustion vulnerability in OpenCVDynamicOpenPanguVideoBackend, which uses request-controlled numframes without an effective ceiling. Unauthenticated attackers can send /v1/chat/completions or /tokenize requests selecting the openpangu videobackend with a huge numframes, forcing np.linspace allocations and CPU work that OOM-kill the API server.

First published (updated )
Severity
6.5
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

Summary

The Phi-4 multimodal audio encoder (phi4mmaudio.py / phi4mmutils.py) runs its conformer attention in eager mode by default: the official HF config of microsoft/Phi-4-multimodal-instruct does not set useptscaleddotproductattention, so the default False applies (phi4mmaudio.py:166, :876; phi4mmutils.py:1669). The eager path fully materializes the attention probability matrix of shape [nchunks, 16, 500, 500] per layer — and then stores it on the module: self.attn = attn (phi4mmutils.py:1802, a torch.jit.Attribute declared at :1693), keeping a live reference for every one of the 24 encoder layers.

The only gates on audio length are the server-side limits VLLMMAXAUDIOCLIPFILESIZEMB=25 and VLLMMAXAUDIODECODEDURATIONS=600 (envs.py:83-84) — i.e. a 10-minute clip is a legal input by default. A 600 s clip becomes ~60,000 mel frames, which the encoder unfolds into 500-frame chunks (phi4mmaudio.py:996, maxseqlen = 500), giving nchunks ≈ 120. Each layer therefore materializes a 120×16×500×500 matrix (~1–2 GiB depending on dtype), and the module attribute keeps all completed layers' matrices alive, so GPU memory climbs monotonically within a single request until an allocation fails.

Verified end-to-end on the official vllm/vllm-openai:v0.31.0 image: one 19.2 MB silent 600 s WAV → worker torch.OutOfMemoryError: CUDA out of memory. Tried to allocate 2.29 GiB ... 501.75 MiB free ... 22.09 GiB allocated by PyTorch inside getaudiofeatures (phi4mmaudio.py:1279 → :1332 → phi4mmutils.py:1386) → EngineCore encountered a fatal error → API EngineDeadError → whole server down; /health refuses connections. Total time from request to dead service: ~6 seconds.

A secondary effect: because self.attn persists on the module after the request ends, the matrices of the last audio request stay resident indefinitely (observed +50 MiB pinned after a single 5 s control request); they are only overwritten by the next audio request, so the resident footprint equals the largest audio processed since startup.

Details

1. Root cause. MultiHeadedAttention.forwardattention in eager mode computes attn = maskedsoftmax(scores, mask) and unconditionally executes self.attn = attn (phi4mmutils.py:1795-1802). The attribute is a leftover inference/debug hook (used by torch.jit.Attribute(None, Tensor | None) at :1693); in serving it serves no purpose but pins the full [batch·chunks, heads, T, T] tensor per layer past both the layer's forward and the request's lifetime. The SDP attention branch (useptscaleddotproductattention=True) never materializes this matrix — but the HF config does not enable it and the code default is False.

2. Why one request suffices. The conformer chunks long audio to maxseqlen = 500 frames (phi4mmaudio.py:996). Duration is bounded only by VLLMMAXAUDIODECODEDURATIONS=600, so nchunks reaches ~120 for a maximal clip. With 16 heads and fp32 scores, one layer's attention tensor is ~1.8 GiB (the observed failing allocation was 2.29 GiB, consistent with the scores+bias materialization). The encoder has numblocks=24, attentionheads=16, attentiondim=1024, timereduction=8 (HF config). Weights plus a handful of retained per-layer matrices exhaust the ~2.3 GiB headroom that --gpu-memory-utilization 0.9 leaves on a 24 GB card — mid-forward, on the first request.

4. Deployment reality. --trust-remote-code is the documented, standard way to serve this model (the HF model card instructs it), so the finding applies to default deployments. The crash is deterministic, not load-dependent: scheduler stats at death show a single running request and near-zero KV cache usage.

Impact

Any unauthenticated client that can reach the chat/completions API of a default deployment serving Phi-4-multimodal-instruct (or any model reusing this audio tower) can kill the entire engine with one request carrying a perfectly legal 10-minute audio clip (silent noise suffices — no crafted content needed). Full denial of service, requiring a process restart. On GPUs with more headroom (e.g. 80 GB at default utilization) a single request may survive, but the eager path still materializes GiB-scale per-layer matrices and retains the last request's tensors indefinitely, so a few sequential max-length requests — or normal traffic following one — achieve the same result.

Relation to prior art: the only public Phi-4-mm advisory we found, GHSA-vc6m-hm49-g9qg, concerns a CPU-side quadratic-cost path — different subsystem, different mechanism. GitHub search for "phi4mm audio OOM/memory" (31 results, 2026-10-08) shows no report of this attention-retention issue; main (2026-10-08) is unchanged.

Suggested remediation (any one breaks the chain; 1+2 recommended):

1. Remove self.attn = attn from the serving path (or gate it behind an explicit debug/outputattentions flag) so attention matrices are freed when the layer returns. 2. Default useptscaleddotproductattention to True (flash/SDPA kernels never materialize the [B, H, T, T] matrix); keep eager only as an opt-in. 3. Additionally bound the encoder input (frames or duration) for this model so the eager path cannot reach GiB-scale single-layer allocations even if enabled.

This advisory was fixed in MR60614.

1 / 2
Source: GitHub
First published (updated )
Severity
6.5
Out-of-bounds Read, Input Validation
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

For a model whose vocabulary size is an exact multiple of the embedding padding size (64) — e.g. any Llama-2-family model, vocab 32000 — a single request carrying a pre-tokenized prompt with token id equal to the vocab size (32000) passes vLLM's input-id validation but is one past the last embedding row. At tensor-parallel size 1 the embedding lookup does not mask indices, so the id reaches F.embedding out of range and raises a CUDA device-side assert, which poisons the engine's CUDA context and takes the engine down. Any client that can send pre-tokenized input (/v1/completions with prompt as token ids, /tokenize-fed flows, or the kvtransferparams["prompttokenids"] reuse path) can trigger it.

Root cause vllm/v1/engine/inputprocessor.py accepts a token id when id <= max(tokenizer.maxtokenid, modelconfig.getvocabsize() - 1). vllm/tokenizers/hf.py computes maxtokenid = max(max(vocab.values()), tokenizer.vocabsize). For Llama-2 tokenizers max(vocab.values()) = 31999 but tokenizer.vocabsize = 32000, so maxtokenid = 32000 — one greater than the largest valid id. The engine bound therefore becomes max(32000, 31999) = 32000, and id 32000 is accepted. The model's embedding has padvocabsize(32000, 64) = 32000 rows (no padding), valid indices 0..31999. At VocabParallelEmbedding.forward with tpsize == 1 there is no masking, so index 32000 hits F.embedding out of range.

Affected - tp=1 (single GPU per model — common per-copy layout). tp>1 masks via getmaskedinputandmask, so the id is clamped, not an OOB — likely wrong output rather than a crash. - Models whose vocab is a multiple of 64 with tokenizer.vocabsize one past the max real id (Llama-2 family, vocab 32000, is the clear case). Qwen2.5 is NOT affected (padded headroom).

Suggested fix maxtokenid in vllm/tokenizers/hf.py now uses tokenizer.vocabsize - 1, so an id equal to the vocabulary size fails input validation instead of reaching the embedding. Fixed in MR59491, released in v0.32.0.

Reporter Shijie Lyu (GitHub shijie-lyu lshjhf@gmail.com). Reported privately per SECURITY.

This advisory was fixed in MR59491.

1 / 2
Source: GitHub
First published (updated )
Severity
6.5
SSRF
AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

vLLM is an inference and serving engine for large language models. Prior to 0.26.0, the MiMoV2OmniMultiModalProcessor in vllm/transformersutils/processors/mimov2omni.py passes attacker-controlled image and audio strings through fetchimage, requests.get, and Image.open instead of MediaConnector, bypassing allowedmediadomains and allowedlocalmediapath protections and allowing server-side requests and reads of arbitrary files accessible to the vLLM process. This issue is fixed in version 0.26.0.

First published (updated )
Severity
6.5
Incorrect Type Cast
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

vLLM is an inference and serving engine for large language models (LLMs). From 0.18.0 to before 0.20.0, 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. This vulnerability is fixed in 0.20.0.

First published (updated )
Severity
5.9
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H

vLLM is an inference and serving engine for large language models. Prior to 0.30.0, the Rust frontend's trackhttpmetrics middleware records the raw HTTP method token as a Prometheus label for requests reaching registered routes. An unauthenticated attacker can send unique arbitrary method tokens to unguarded routes such as /tokenize, causing Prometheus's Family::getorcreate function to permanently create counter and histogram label sets. Those label sets increase process memory usage and enlarge the /metrics response until the service or monitoring path is exhausted. This issue is fixed in version 0.30.0.

First published (updated )
Severity
5.5
EPSS
0.72%
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L/E:P/RL:X/RC:R

A vulnerability was identified in vllm-project vllm 0.19.0. This issue affects some unknown processing of the component OpenAI-compatible Serving Path. Such manipulation leads to denial of service. It is possible to launch the attack remotely. The exploit is publicly available and might be used. The pull request to fix this issue awaits acceptance.

First published (updated )
Severity
5.3
AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

vLLM versions >= 0.6.3 and < 0.9.0 contain multiple regular expression denial of service (ReDoS) vulnerabilities. Several regex patterns — in vllm/lora/utils.py, the phi4mini tool parser, and the OpenAI-compatible serving chat endpoint — are susceptible to catastrophic backtracking. An attacker submitting crafted input with nested or repeated structures can trigger severe CPU consumption and performance degradation, resulting in denial of service.

First published (updated )
Severity
4.8
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L

Summary

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

https://github.com/vllm-project/vllm/blob/16b37f3119918c1e5a39f303e0d0892c65c07a90/vllm/multimodal/image.py#L77-L84

https://github.com/vllm-project/vllm/blob/16b37f3119918c1e5a39f303e0d0892c65c07a90/vllm/multimodal/image.py#L37-L43

https://github.com/vllm-project/vllm/blob/16b37f3119918c1e5a39f303e0d0892c65c07a90/vllm/multimodal/image.py#L26-L34 Current state: ImageOps.exiftranspose is not used. (Although the rescaleimagesize function (https://github.com/vllm-project/vllm/blob/main/vllm/multimodal/image.py#L14) exists and includes a transpose parameter, I’ve found that it doesn’t seem to be called anywhere outside the test directory.)

Call order: convertimagemode runs first; if the conditions are met, convertimagemode is called. Issue: Only the “RGBA → RGB” path is explicitly flattened. P, L, or RGB with tRNS all fall back to image.convert("RGB"). For PNGs that include tRNS, convert("RGB") directly produces 24-bit RGB, leading to: P mode: The transparent index becomes an actual RGB color (often black, white, or an undefined background), so transparency is lost. L/LA and RGB + tRNS: convert("RGB") doesn’t composite against a chosen background first, so elements that relied on transparency to be hidden or softened become solid.

Impact & Scope

Impact: Pixels the model sees can diverge from operator expectations (due to orientation or transparency handling), potentially altering downstream reasoning. Scope: The image I/O and mode-conversion paths in vllm/multimodal/image.py. The existing RGBA→RGB flattening is correct; the issues center on missing EXIF normalization and non-RGBA tRNS not being explicitly composited.

Case EXIF: http://qiniu.funxingzuo.top/exiforient180.jpg tRNS: http://qiniu.funxingzuo.top/hello.png

Fix

A fix for this vulnerability was merged here: https://github.com/vllm-project/vllm/pull/44974

1 / 3
Source: GitHub
First published (updated )
Severity
4.8
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L

A flaw was found in vLLM, an open-source library for large language model inference. This vulnerability arises from improper handling of image metadata, specifically EXIF orientation and PNG transparency (tRNS) data, during image processing. When images are converted to RGB, transparency information may be implicitly discarded or remapped, leading to unexpected rendering of transparent pixels and distortion of input content. This can result in the model misinterpreting image content, potentially affecting the integrity of processed data.

First published (updated )
Severity
2.9
EPSS
0.07%
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L/E:P/RL:U/RC:R

A vulnerability was found in vLLM up to 0.19.0. The affected element is the function hasmambalayers of the file vllm/v1/kvcacheinterface.py of the component KV Block Handler. Performing a manipulation results in uninitialized resource. It is possible to initiate the attack remotely. The attack is considered to have high complexity. The exploitability is described as difficult. The exploit has been made public and could be used. The existence of this vulnerability is still disputed at present. The proposed patch did not fix the issue. A 3rd party explains: "The divergence could be explained by a benign and expected vLLM behavior where vLLM server could group concurrent requests together resulting in different input shapes based on varying request arrival time. The differences in grouped input shapes could call different kernels with could produce difference results due to rounding and differences in order of operations. There is an environment variable VLLMBATCHINVARIANT=1 for users that desire to have deterministic output with temperature 0.0."

First published (updated )
Severity
2.9
AV:N/AC:H/AT:N/PR:N/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:P

A vulnerability was found in vLLM up to 0.19.0. The affected element is the function hasmambalayers of the file vllm/v1/kvcacheinterface.py of the component KV Block Handler. Performing a manipulation results in uninitialized resource. It is possible to initiate the attack remotely. The attack is considered to have high complexity. The exploitability is described as difficult. The exploit has been made public and could be used. The existence of this vulnerability is still disputed at present. The proposed patch did not fix the issue. A 3rd party explains: "The divergence could be explained by a benign and expected vLLM behavior where vLLM server could group concurrent requests together resulting in different input shapes based on varying request arrival time. The differences in grouped input shapes could call different kernels with could produce difference results due to rounding and differences in order of operations. There is an environment variable VLLMBATCHINVARIANT=1 for users that desire to have deterministic output with temperature 0.0."

First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203