GHSA-542m-9234-8gvf: Medium severity pip/vllm vulnerability
Summary vLLM renders chat templates by passing the resolved Jinja2 source to tokenizer.applychattemplate(), 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 maxworkers defaults to 1, and CPython worker threads cannot be interrupted. An authenticated API client (or a malicious model repo loaded with trustremotecode=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 tokenizerconfig.json carries the hostile template wedges every replica that loads it on the first legitimate chat request, with trustremotecode=False.
Preconditions: any non-harmony model (modeltype != gptoss); renderernumworkers 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.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/vllmto a version that resolves this vulnerability.Fixed in 0.32.0 - Upgrade
Upgrade
vllmto a version that resolves this vulnerability.Patch MR50300 - Operational
Restart the affected API-server process to restore chat-style inference after exploitation.
Event History
Frequently Asked Questions
Are default vLLM server deployments exposed?
Yes. The remotely authenticated attack path is available in the default vLLM serve configuration because the /v1/responses gate omission does not require operator opt-in.
What level of access does an attacker need?
An attacker needs to be an authenticated API client. A malicious model repository can also introduce the issue even when trust_remote_code=False.
Which services are disrupted by a successful request?
A single request can wedge all chat-style endpoints for every tenant: /v1/chat/completions, /v1/responses, /tokenize, chat-mode /pooling, and chat-mode /invocations. The default single-worker executor means one uninterruptible render can block subsequent chat-template work.
What happens if the template exhausts memory instead of CPU time?
A string-multiplication variant can OOM-kill the API server process rather than leave its chat-style endpoints wedged.
What restores service after a worker is permanently wedged?
The affected process must be restarted. CPython worker threads cannot be interrupted, so the blocked render does not recover on its own.