VLLM · GHSA-m9fg-w9qh-67pc · AI agents & MCP
FIX → 0.31.0
vLLM's error-message scrubber only removes lowercase hexadecimal memory addresses, but Pillow's image repr prints them in uppercase, so a crafted small PNG sent to an unauthenticated endpoint returns a live heap address of the server process. The attacker gets an address, not memory contents, which weakens ASLR protection for a later exploit chain.
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.
Teams running vLLM 0.14.0rc1 up to but not including 0.31.0 with multimodal (image) inputs enabled. The advisory states a default vllm serve has no authentication, and /tokenize stays reachable even with --api-key set, so exposure on a network-reachable server is the main concern. Teams on 0.31.0 or later, or on versions below 0.14.0rc1, are not affected.
Not affected if no-multimodal-inputs, not-network-exposed, version-0.31.0-or-later
Who cares multimodal, python, self-hosted, vllm
pip show vllm and treat versions >= 0.14.0rc1 and < 0.31.0 as affected.--api-key is set; the advisory says stays unauthenticated even when it is.sanitize_message() scrubs heap addresses from error messages with the regex r" at 0x[0-9a-f]+>" - lowercase only, no IGNORECASE. PIL.Image.Image.__repr__ formats its address as 0x{id(self):X} - uppercase. The scrubber structurally cannot match the one object class both parent advisories are about.
A 564-byte PNG sent to an unauthenticated endpoint returns a live heap address of the running server process.
This is not a new hardening proposal. The CVE-2026-54236 advisory explicitly recommended widening this exact regex to [0-9a-fA-F]; three months on it is byte-identical.
# the scrubber
r" at 0x[0-9a-f]+>"
# what PIL actually emits
# PIL/Image.py — Image.__repr__
"<%s.%s image mode=%s size=%dx%d at 0x%X>" % (..., id(self))
The parent CVE's own lowercase BytesIO shape is scrubbed correctly today. PIL's uppercase form is not.
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.
/tokenizeUpgrade to 0.31.0
vllm: upgrade to 0.31.0 or later.vllm/multimodal/processing/context.py:347 f-strings the PIL objects into any HF-processor failure message, which is returned to the client.
test_error_sanitization.py already contains a case with the id pil-image-repr, asserting that the PIL form is scrubbed. Its input is a hand-written lowercase literal that PIL never emits. I ran both halves against the same object class: the test passes, and a real repr() leaks.
That is why a documented, accepted recommendation looked already-covered and was never implemented. Any fix must include a test built from a real repr(), not from a literal.
sanitize_message to a new Responses-API WebSocket path, continuing the CVE-2026-54236 remediation - but does not widen the regex, and its new test also uses a lowercase literal.serve/utils/api_utils.py) and only touches the path regex's backtracking.api_key defaults to None, and AuthenticationMiddleware is installed only when a key is configured - a default vllm serve is entirely unauthenticated.--api-key set, GUARDED_PREFIX = ("/v1", "/v2", "/inference", "/cohere"), so /tokenize remains unauthenticated.Information disclosure: a live heap address of the API-server process, to an unauthenticated remote client. CWE-532.
Scope, stated plainly. This is information disclosure, not memory corruption. It is Stage 1 of the chain CVE-2026-22778 was rated 9.8 for - an ASLR defeat that made the second stage reliable. Stage 2 is patched at the current OpenCV floor, so I am not claiming RCE. The value of the fix is that the disclosure primitive the chain depended on is still live, and the advisory that recommended closing it was never acted on.
Proposed CVSS v3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N (5.3, Medium). Severity is proposed, not insisted on.
[0-9a-fA-F] and add re.IGNORECASE, as CVE-2026-54236's advisory recommended.pil-image-repr test case's hand-written literal with a string produced by calling repr() on a real PIL.Image.Image, so the case cannot pass while the production path leaks. Apply the same to PR #35492's new test.Item 2 matters as much as item 1 here: the test is the reason the first recommendation was lost.
vllm launch render), which runs the real frontend, the real request model and the real /tokenize route. Media processing happens entirely in the frontend, so I do not believe the engine's presence changes the result - but I have not confirmed it under a full vllm serve.Prepared with AI assistance (Claude), per the repository's contributing guidance on disclosing AI-assisted contributions. All findings were verified by executing vLLM's own code at the commits cited; the analysis and the claims are my own.
Reported by Eva Crystal / 0xiviel (XSource Security).
vllm (PyPI).>= 0.14.0rc1, < 0.31.0.0.31.0.Advisory fixed in #58832.