An incomplete patch: memory-address leaks return in vLLM's newer API routes
The fix for vLLM's critical image-parsing flaw sanitized the OpenAI router — but routes added weeks later re-echo raw exception text, leaking heap addresses and reopening an ASLR-bypass primitive.
What is this?
On June 11, 2026, the vLLM project published a security advisory (GHSA-hgg8-fqqc-vfmw) reported by researcher Kai Aizen (SnailSploit). It documents an incomplete fix: the patch that closed an earlier critical image-parsing flaw in vLLM’s OpenAI-compatible router did not extend to routes added shortly afterward, so those newer endpoints still leak internal memory addresses to remote callers.
The earlier flaw was severe — a critical (CVSS 9.8) vulnerability that chained a memory-address leak with an image-library heap overflow to reach remote code execution. Its fix introduced a sanitizer that strips object-representation addresses out of error messages before they reach clients. This follow-up finding is scored medium (CVSS 3.1 base 5.3), with low confidentiality impact and no integrity or availability impact. The weakness class is CWE-532, insertion of sensitive information into an error message — the same class as the parent issue. The affected code is present in vLLM versions up to and including 0.22.0.
How it works
When vLLM parses a malformed image, the imaging library raises an error whose text contains the in-memory representation of the buffer object — something like cannot identify image file <_io.BytesIO object at 0x7a95e299e750>. That trailing hex value is a live heap address. If it reaches the client verbatim, an attacker learns where objects sit in the process’s address space, collapsing ASLR entropy from roughly four billion possibilities to a handful — exactly the reconnaissance step the earlier critical chain relied on.
The parent fix added a sanitize_message helper and wired it into the OpenAI router’s exception handlers, rewriting <_io.BytesIO object at 0x...> down to <_io.BytesIO object>. The problem is that several response paths added at or after the same time never call it. The advisory lists five such sites: the Anthropic-compatible messages endpoint, its token-counting endpoint, the server-sent-events streaming converter, and two error paths in the realtime speech-to-text WebSocket. Each returns str(exception) directly to the caller.
A natural question is why vLLM’s global, sanitizing exception handler doesn’t catch these. The answer is a subtle framework detail worth internalizing: a global exception handler only fires on unhandled exceptions that propagate out of a route. Each affected HTTP route instead catches the exception inside the route function and builds its own response, so the sanitizing handler is never invoked. The WebSocket paths bypass it for a different reason — WebSocket frames don’t traverse the HTTP exception-handler chain at all. The same malformed-image trigger that fed the parent issue reaches all of these newer routes unchanged.
The advisory is explicit that this is not stale legacy code but a series of scope misses: the sanitizer landed on January 9, 2026; the Anthropic router was added six days later without it, the token-counting endpoint about two months after that, and the speech-to-text paths in May — each replicating the unsanitized pattern.
Why it matters
On its own, an address leak changes nothing a user can see. Its value is as a building block. The parent chain needed exactly this primitive to defeat ASLR before triggering memory corruption. That second stage — a heap overflow in an older image codec — is fixed in current library versions, so on a fully updated stack this finding is an information-disclosure primitive rather than a path to code execution. But vLLM is frequently shipped inside custom Docker images, downstream rebuilds, and long-lived LTS distributions that pin older system libraries. On any deployment still carrying a vulnerable image codec, these newer endpoints quietly re-enable the full leak-then-corrupt chain the original patch was meant to close.
The broader lesson is about how fixes decay. A patch applied at specific call sites protects only those call sites. As new routes, transports, and endpoints are added, they reintroduce the very pattern the fix was meant to eliminate — unless the mitigation lives at a chokepoint every response must pass through.
Defenses
The definitive fix is to upgrade to a vLLM build that includes the remediation merged in the project’s fix pull request. Beyond upgrading, the advisory’s guidance generalizes well and aligns with OWASP’s Sensitive Information Disclosure guidance:
- Sanitize error output symmetrically. Every path that returns exception text to a client — HTTP routes, streaming converters, and WebSocket handlers alike — must scrub object reprs and raw addresses. A fix on one router is not a fix everywhere.
- Move the mitigation to a chokepoint. Route-local
try/exceptblocks and WebSocket handlers bypass framework-level exception handlers. A response middleware that scrubs every outgoing error body prevents this whole class of regression, so a newly added route can’t silently reopen the leak. - Broaden the scrubbing pattern. A regex that matches only the exact lowercase CPython address suffix is brittle; future runtimes, C extensions, or custom
__repr__methods can produce non-matching formats. Strip any standalone hex address rather than one specific shape. - Never return raw internal errors to untrusted callers. Log the detailed exception server-side; return a generic, opaque error to the client. Address leaks, stack traces, and file paths are all reconnaissance.
- Treat incomplete-fix follow-ups as first-class. When a critical bug is patched, audit every sibling and newly added path for the same sink before closing the book on it.
Status
| Item | Reference | Date | Notes |
|---|---|---|---|
| Follow-up advisory published | GHSA-hgg8-fqqc-vfmw | 2026-06-11 | Info disclosure (CWE-532); CVSS 5.3 medium; no CVE assigned |
| Parent vulnerability | CVE-2026-22778 / GHSA-4r2x-xpjr-7cvv | 2026 | Critical (CVSS 9.8); leak chained to heap overflow for RCE |
| Sanitizer introduced | vLLM PR #31987 | 2026-01-09 | Applied only to OpenAI router exception handlers |
| Affected versions | vLLM ≤ 0.22.0 | — | Anthropic router, count-tokens, SSE converter, speech-to-text WebSocket |
| Fix | vLLM PR #45119 | 2026 | Applies sanitization to the missed sites |
The takeaway is an old maxim in a new setting: a patch is only as complete as the surface it covers. Sanitize error output at a single point every response flows through, keep raw internal state out of client-facing messages, and when you fix a critical bug, hunt down every route that shares its sink before declaring it closed.
Details here are drawn from the vLLM security advisory and the referenced pull requests. No proof-of-concept payload is reproduced; defenders should consult the linked advisory for exposure assessment.
Sources
- → https://github.com/vllm-project/vllm/security/advisories/GHSA-hgg8-fqqc-vfmw
- → https://github.com/vllm-project/vllm/security/advisories/GHSA-4r2x-xpjr-7cvv
- → https://nvd.nist.gov/vuln/detail/CVE-2026-22778
- → https://github.com/vllm-project/vllm/pull/45119
- → https://genai.owasp.org/llmrisk/llm022025-sensitive-information-disclosure/