GHSA-542M-9234-8GVF

Vulnerability from github – Published: 2026-10-28 21:14 – Updated: 2026-10-28 21:14
VLAI
Summary
vLLM: DoS via unbounded chat_template Jinja2 rendering exhausts the renderer thread pool
Details

Summary

vLLM renders chat templates by passing the resolved Jinja2 source to tokenizer.apply_chat_template(), which compiles and .render()s it in an ImmutableSandboxedEnvironment. The sandbox prevents code-execution escapes but imposes no wall-clock timeout, no output-size cap, and no nested-loop or binop limit. The render runs in a ThreadPoolExecutor whose max_workers defaults to 1, and CPython worker threads cannot be interrupted. An authenticated API client (or a malicious model repo loaded with trust_remote_code=False) can therefore submit a single short template and permanently wedge all chat-style endpoints (/v1/chat/completions, /v1/responses, /tokenize, /pooling-chat, /invocations-chat) for every tenant until the process is restarted. A string-multiplication variant instead OOM-kills the API-server process. Because of a separately-reported (GHSA-jmjw-q4x3-hmc2) gate omission on /v1/responses, the remote authenticated attacker vector works in default vllm serve configuration with no operator opt-in.

Impact

A single authenticated request of <100 bytes permanently denies all chat-style inference (/v1/chat/completions, /v1/responses, /tokenize, /pooling-chat, /invocations-chat) to every tenant of the API-server replica until the operator restarts the process. The string-multiplication variant OOM-kills the process. In a multi-tenant deployment this is a cross-tenant denial-of-service from any one tenant. From the malicious-model angle, a model repo whose tokenizer_config.json carries the hostile template wedges every replica that loads it on the first legitimate chat request, with trust_remote_code=False.

Preconditions: any non-harmony model (model_type != gpt_oss); renderer_num_workers at its default of 1; for the default-config authenticated API attacker vector, --chat-template must be unset (the default because most HF models ship their own). Blast radius: API-server process, per replica. Engine/worker processes unaffected by the CPU variant (event loop survives); affected by the memory variant (process OOM). Persistence: until process restart. Survives client disconnect.

This advisory was fixed in MR50300.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "vllm"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.19.0"
            },
            {
              "fixed": "0.32.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-115911"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400",
      "CWE-770",
      "CWE-834"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-28T21:14:52Z",
    "nvd_published_at": "2026-10-26T17:17:18Z",
    "severity": "MODERATE"
  },
  "details": "### Summary\nvLLM renders chat templates by passing the resolved Jinja2 source to `tokenizer.apply_chat_template()`, which compiles and `.render()`s it in an `ImmutableSandboxedEnvironment`. The sandbox prevents code-execution escapes but imposes **no wall-clock timeout, no output-size cap, and no nested-loop or binop limit**. The render runs in a `ThreadPoolExecutor` whose `max_workers` defaults to **1**, and CPython worker threads cannot be interrupted. An authenticated API client (or a malicious model repo loaded with `trust_remote_code=False`) can therefore submit a single short template and permanently wedge **all** chat-style endpoints (`/v1/chat/completions`, `/v1/responses`, `/tokenize`, `/pooling`-chat, `/invocations`-chat) for every tenant until the process is restarted. A string-multiplication variant instead OOM-kills the API-server process. Because of a separately-reported (GHSA-jmjw-q4x3-hmc2) gate omission on `/v1/responses`, the remote authenticated attacker vector works in **default `vllm serve` configuration** with no operator opt-in.\n\n### Impact\nA single authenticated request of \u003c100 bytes permanently denies all chat-style inference (`/v1/chat/completions`, `/v1/responses`, `/tokenize`, `/pooling`-chat, `/invocations`-chat) to **every tenant** of the API-server replica until the operator restarts the process. The string-multiplication variant OOM-kills the process. In a multi-tenant deployment this is a cross-tenant denial-of-service from any one tenant. From the malicious-model angle, a model repo whose `tokenizer_config.json` carries the hostile template wedges every replica that loads it on the first legitimate chat request, with `trust_remote_code=False`.\n\n**Preconditions:** any non-harmony model (`model_type != gpt_oss`); `renderer_num_workers` at its default of 1; for the default-config authenticated API attacker vector, `--chat-template` must be unset (the default because most HF models ship their own).\n**Blast radius:** API-server process, per replica. Engine/worker processes unaffected by the CPU variant (event loop survives); affected by the memory variant (process OOM).\n**Persistence:** until process restart. Survives client disconnect.\n\nThis advisory was fixed in [MR50300](https://github.com/vllm-project/vllm/pull/50300).",
  "id": "GHSA-542m-9234-8gvf",
  "modified": "2026-10-28T21:14:52Z",
  "published": "2026-10-28T21:14:52Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/vllm-project/vllm/security/advisories/GHSA-542m-9234-8gvf"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-115911"
    },
    {
      "type": "WEB",
      "url": "https://github.com/vllm-project/vllm/pull/50300"
    },
    {
      "type": "WEB",
      "url": "https://github.com/vllm-project/vllm/commit/cff08b461e086523cee8bba5bd3c66d302625134"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/vllm-project/vllm"
    },
    {
      "type": "WEB",
      "url": "https://github.com/vllm-project/vllm/releases/tag/v0.32.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "vLLM: DoS via unbounded chat_template Jinja2 rendering exhausts the renderer thread pool"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.