Sep 5, 2026·6 min read·43 visits
Authenticated attackers can cause a Denial of Service (DoS) or Out of Memory (OOM) crash in vLLM servers by submitting oversized, deeply nested arrays of token IDs or choices to the `/v1/completions/derender` or `/v1/chat/completions/derender` endpoints, which the server detokenized without enforcing structure bounds.
CVE-2026-71486 (GHSA-8737-qx52-hjff) is an uncontrolled resource consumption vulnerability in vLLM's derender endpoints before version 0.26.0. An authenticated attacker can supply crafted, deeply nested token structures to exhaust CPU and memory resources, resulting in server denial of service (DoS) or Out of Memory (OOM) crashes. This vulnerability stems from missing input-bounds validation before passing user-supplied structures to computationally intensive decoding routines.
In distributed large language model serving, vLLM utilizes a token-in-token-out (TITO) architecture to optimize throughput and memory management. Within this framework, vLLM exposes specialized 'derender' endpoints located at /v1/completions/derender and /v1/chat/completions/derender. These endpoints perform the inverse operations of standard generation, taking complex serialized structures such as raw token lists, logprobs, and choice selections and translating them back into cohesive, OpenAI-compatible text blocks.\n\nPrior to version 0.26.0, the scale-out derendering architecture allowed authenticated clients to submit unvalidated GenerateResponse data structures directly to internal post-processing modules. The system lacked initial validation rules to check if the incoming structures conformed to physical constraints, exposing a significant attack surface for remote resource exhaustion. An attacker could issue a single post request with excessively long arrays to deplete system resources.\n\nThe absence of early-stage boundary verification meant that any input sequence, regardless of length, was immediately accepted into memory. The framework proceeded to execute heavy detokenization on these structures before checking if they violated model-level configuration limits. This architecture fundamentally failed to safeguard the primary serving host from processing malicious or corrupted input layouts.
The root cause of CVE-2026-71486 lies in the omission of structural input bounds validation in the OnlineDerenderer class and associated route handlers. When the server ingested a request, FastAPI deserialized the JSON body into a Pydantic structure without evaluating the cardinality of nested arrays. This deserialized structure was subsequently passed directly to the tokenizer.decode() function and associated internal parser loops.\n\nSpecifically, the application failed to validate several distinct fields within the GenerateResponse object. The token_ids array under each choice index could be populated with an arbitrary quantity of integers, completely ignoring the model's configured maximum sequence length (max_model_len). Similarly, the choices array itself and the nested logprobs.content structures could be inflated to include thousands of simulated inputs without triggering any early rejection logic.\n\nAdditionally, the system did not validate whether the integers supplied within the token_ids array represented valid non-negative token indices matching the model's vocabulary. This omission allowed negative integers to enter the internal C++ bindings of tokenizers, leading to unexpected behavior or crash states inside the low-level processing code. Once the high-level Python engine attempted to construct and detokenize these structures, the host CPU utilization would reach maximum capacity and exhaust the system's memory allocation, forcing an Out of Memory (OOM) crash.
The vulnerability was resolved in commit 8e61b646e2d157f9b93451fa048f9c8530c8a67b by introducing strict boundary-checking logic prior to detokenization. The implementation adds a new private method, _validate_derender_bounds, inside the derender serving class in vllm/entrypoints/scale_out/derender/serving.py. This validation runs immediately after request deserialization and blocks downstream processing if limits are exceeded.\n\nBelow is the validated logic added to intercept requests and enforce bounds:\n\npython\ndef _validate_derender_bounds(\n self,\n generate_responses: list[GenerateResponse],\n) -> ErrorResponse | None:\n # Fetch server maximums and model-specific limits\n max_n = envs.VLLM_MAX_N_SEQUENCES\n max_model_len = self.model_config.max_model_len\n\n if len(generate_responses) > max_n:\n return self.create_error_response(\n f"generate_responses count ({len(generate_responses)}) exceeds limit.\"\n )\n\n for gen in generate_responses:\n if len(gen.choices) > max_n:\n return self.create_error_response(\n f"choices count ({len(gen.choices)}) exceeds limit.\"\n )\n\n for choice in gen.choices:\n # Ensure token_ids do not exceed the model's max sequence length\n if choice.token_ids and len(choice.token_ids) > max_model_len:\n return self.create_error_response(\n f"token_ids length ({len(choice.token_ids)}) exceeds max_model_len ({max_model_len}).\"\n )\n # Validate logprobs content size\n if choice.logprobs and choice.logprobs.content:\n if len(choice.logprobs.content) > max_model_len:\n return self.create_error_response(\n f"logprobs.content length ({len(choice.logprobs.content)}) exceeds limit.\"\n )\n\n\nAdditionally, to prevent token-ID index manipulation and negative value errors in the low-level C++ tokenizer layer, a Pydantic field validator was implemented in vllm/entrypoints/scale_out/token_in_token_out/protocol.py:\n\npython\n@field_validator(\"token_ids\")\n@classmethod\ndef validate_token_ids(cls, v: list[int] | None) -> list[int] | None:\n if v is not None and any(t < 0 for t in v):\n raise ValueError(\"token_ids must not contain negative values\")\n return v\n\n\nThese defensive layers ensure that oversized structures and malformed values are rejected at the edge of the service before consuming CPU execution time or memory buffers.
Exploiting CVE-2026-71486 requires an attacker to possess network access to the vLLM serving port (default 8000) and valid API credentials if authentication is configured. The attack is executed by constructing a highly nested, oversized JSON payload matching the schema of the derender endpoints and transmitting it via a single HTTP POST request.\n\nIn a typical scenario, the attacker generates an array of a million mock token IDs and submits it to /v1/chat/completions/derender. Because the server does not check the size of the array, it immediately allocates memory for the list and spawns execution threads to parse and decode the tokens, blocking the event loop and exhausting the CPU.\n\nAnother variation of the attack involves sending thousands of simulated choices within a single choices object. The server's attempt to dynamically map and format each index leads to memory accumulation on the heap, triggering an Out of Memory condition that forces the operating system to terminate the vLLM process.
The impact of CVE-2026-71486 is classified as a low-severity Denial of Service (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L, base score 4.3). While exploitation does not result in remote code execution or data exposure, it directly affects the availability of the LLM serving infrastructure. A single API client can take down the engine, impacting all users and services relying on that vLLM instance.\n\nWhile the introduced bounds-checking mitigates simple, large-array attacks, a residual risk of multiplicative scale exploitation remains. The validator checks each array independently against the configuration limits instead of verifying the total cumulative size of the request. An attacker could construct a payload containing multiple responses, each with a count of choices and token IDs sitting just below their individual thresholds, still causing significant processing overhead.\n\nFurthermore, because request validation occurs at the application layer, the server must completely deserialize the incoming JSON using Pydantic before executing the check. If an attacker sends a very large JSON request (such as hundreds of megabytes), the server may run out of memory during the parsing and object initialization phase. This limitation highlights the need for secondary, network-level controls.
The primary remediation path for CVE-2026-71486 is to upgrade the vLLM installation to version 0.26.0 or later. This introduces the input validation changes and prevents resource-exhaustion vectors through the derender paths. Administrators can verify their version using pip show vllm and upgrade using pip.\n\nIf upgrading immediately is not possible, several compensating controls should be applied at the network or reverse-proxy layer. If your applications do not use scale-out or derendering capabilities, block all incoming traffic to /v1/completions/derender and /v1/chat/completions/derender using a reverse proxy such as NGINX or Envoy.\n\nAdditionally, enforce a strict maximum request body size (such as 50 KB) at the proxy level for all API endpoints. Because legitimate derendering requests contain standard text completions and are small, restricting the body size blocks the transmission of oversized payloads before they are parsed by the Python ASGI server.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
vLLM vllm-project | < 0.26.0 | 0.26.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 |
| Attack Vector | Network (AV:N) |
| CVSS Score | 4.3 (Medium) |
| EPSS Score | 0.00341 (27.00% Percentile) |
| Impact | Denial of Service (DoS) / OOM Crash |
| Exploit Status | Proof-of-Concept |
| KEV Status | Not Listed |
The product does not properly control the allocation and maintenance of a limited resource, enabling an actor to influence the amount of resources consumed, leading to exhaustion.
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.
CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.