VLLM · GHSA-5r3c-5x4v-8gjh · AI agents & MCP
FIX → 0.33.0
vLLM downloads and decodes every image in a request without a request-wide size or memory budget, so one compact request with many remote image URLs can consume API-frontend memory, decoder CPU and outbound connections before prompt length is checked. An attacker can degrade or crash the API process for other clients.
first public Nov 2, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Teams that run vLLM as an API server for multimodal models that accept multiple images per request, especially where the endpoint is reachable from untrusted clients. Authentication is optional by default, and the affected endpoints include /v1/messages, non-Harmony /v1/responses and equivalent chat-rendering paths. Deployments that only serve text models or sit behind strict access control are less exposed.
Not affected if auth-required, internal-only-network, text-only-models
Who cares llm-inference, multimodal, self-hosted, vllm
pip show vllm and confirm whether it is at least 0.33.0.Upgrade to 0.33.0
A remote inference client can submit one request containing many individually valid remote images. vLLM validates only the image count and per-item limits before scheduling every image for download and decoding. It does not enforce a request-wide encoded-byte, decoded-byte, or memory budget.
For models permitting multiple images, one compact request can therefore consume outbound connections, decoder CPU, and API-frontend memory before prompt-length admission. API authentication is optional by default; when enabled, ordinary inference access is sufficient.
Affected entry points include /v1/messages, non-Harmony /v1/responses, and equivalent chat-rendering paths.
The verified flow is:
parse_image() registers a deferred fetch after count validation.
AsyncMultiModalItemTracker.resolve_items() starts all registered media operations in one asyncio.gather() and materializes every result.
MediaConnector.load_from_url_async() downloads and decodes each response independently.
The HTTP size limit is per response, not per request.
ImageMediaIO.load_bytes() eagerly decodes each image into a MediaWithBytes, retaining both the decoded raster and original bytes.
_resolve_items() retains the complete result list.
Fetching precedes downstream template/token-length admission in the HF renderer and Responses renderer.
MultiModalConfig defaults an unspecified modality count to 999. Representative LLaVA processing information supplies no lower model-specific limit.
The aiohttp connection-pool limit of 100 and vLLM’s eight-worker decode pool constrain instantaneous concurrency, but do not constrain aggregate request memory. Completed images accumulate until gathering and later preprocessing finish.
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.
0.33.0A complete fix should enforce a request-wide media resource budget, including aggregate encoded/decoded-byte accounting, bounded request/process concurrency, and cancellation/release after validation failure or budget exhaustion.
A remote client can cause disproportionate frontend memory, CPU, network, and connection-pool consumption with one syntactically small request containing many compressed-image URLs. This work occurs before prompt-length rejection, so even an over-context request can incur the full media cost.
Possible consequences include API-process termination, decoder saturation, outbound-connection occupation, and degraded availability for other clients.
The bounded PoC demonstrates the resource-allocation and retention primitive, not an actual out-of-memory crash.
A fix for this was introduced in https://github.com/vllm-project/vllm/pull/61226.