GHSA-48JH-3GJ7-FG8V
Vulnerability from github – Published: 2026-09-04 21:37 – Updated: 2026-09-04 21:37Summary
The fix for GHSA-rwxx-mrjm-wc2m ("ReDoS via structured_outputs.regex compiled without timeout") wrapped the regex compile in the xgrammar and outlines backends with compile_regex_with_timeout (and, for outlines, validate_regex_is_buildable). The lm-format-enforcer backend was left unguarded: it compiles the attacker-supplied regex with no timeout and no buildability check. A single request with a catastrophic regex hangs the structured-output compile step and stalls the engine worker (denial of service).
Affected code (HEAD d6d39c1)
vllm/v1/structured_output/backend_lm_format_enforcer.py:
- line 110: character_level_parser = lmformatenforcer.RegexParser(grammar_spec) — builds an interegular FSM from the attacker regex synchronously, no timeout.
- line 155: validate_structured_output_request_lm_format_enforcer returns immediately on if so_params.regex: — no validation.
Sibling backends that WERE patched by GHSA-rwxx:
- backend_xgrammar.py:92 → compile_regex_with_timeout(...).
- backend_outlines.py:65 → compile_regex_with_timeout(...) (plus validate_regex_is_buildable).
lm-format-enforcer uses the same interegular DFA-construction primitive the advisory cites for the outlines backend.
Reproduction (runtime-verified against the sink)
The sink lmformatenforcer.RegexParser(<regex>) was exercised directly (this is exactly what the backend calls):
baseline '[0-9]{3}' -> 0.0002 s
attacker '(a{1,300}){300}' -> DID NOT COMPLETE in 20 s (one core pegged at 100% in interegular FSM construction)
End-to-end: start vllm serve <model> --structured-outputs-config '{"backend":"lm-format-enforcer"}', then POST /v1/completions with {"structured_outputs":{"regex":"(a{1,300}){300}"}, ...}. The request never returns; because grammar compile runs in the engine's structured-output path, concurrent requests stall = worker-level DoS. The identical request against the outlines backend is bounded by compile_regex_with_timeout and returns a clean error.
Impact
Unauthenticated denial of service (vLLM ships with no authentication by default). One request pegs a CPU core and blocks the structured-output engine path.
Reachability precondition: the operator must have selected backend=lm-format-enforcer via --structured-outputs-config (the default is auto → xgrammar). This is the same opt-in tier as the outlines backend that GHSA-rwxx already covered.
Suggested remediation
Route the lm-format-enforcer regex compile (backend_lm_format_enforcer.py:110) through the same compile_regex_with_timeout guard already applied to the xgrammar and outlines backends, and reject un-buildable / oversized patterns in validate_structured_output_request_lm_format_enforcer.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "vllm"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.26.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-73556"
],
"database_specific": {
"cwe_ids": [
"CWE-1333",
"CWE-400"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-04T21:37:00Z",
"nvd_published_at": "2026-08-13T15:20:17Z",
"severity": "MODERATE"
},
"details": "### Summary\n\nThe fix for `GHSA-rwxx-mrjm-wc2m` (\"ReDoS via `structured_outputs.regex` compiled without timeout\") wrapped the regex compile in the **xgrammar** and **outlines** backends with `compile_regex_with_timeout` (and, for outlines, `validate_regex_is_buildable`). The **lm-format-enforcer** backend was left unguarded: it compiles the attacker-supplied regex with no timeout and no buildability check. A single request with a catastrophic regex hangs the structured-output compile step and stalls the engine worker (denial of service).\n\n### Affected code (HEAD d6d39c1)\n\n`vllm/v1/structured_output/backend_lm_format_enforcer.py`:\n- line 110: `character_level_parser = lmformatenforcer.RegexParser(grammar_spec)` \u2014 builds an `interegular` FSM from the attacker regex synchronously, **no timeout**.\n- line 155: `validate_structured_output_request_lm_format_enforcer` returns immediately on `if so_params.regex:` \u2014 **no validation**.\n\nSibling backends that WERE patched by GHSA-rwxx:\n- `backend_xgrammar.py:92` \u2192 `compile_regex_with_timeout(...)`.\n- `backend_outlines.py:65` \u2192 `compile_regex_with_timeout(...)` (plus `validate_regex_is_buildable`).\n\nlm-format-enforcer uses the same `interegular` DFA-construction primitive the advisory cites for the outlines backend.\n\n### Reproduction (runtime-verified against the sink)\n\nThe sink `lmformatenforcer.RegexParser(\u003cregex\u003e)` was exercised directly (this is exactly what the backend calls):\n\n```\nbaseline \u0027[0-9]{3}\u0027 -\u003e 0.0002 s\nattacker \u0027(a{1,300}){300}\u0027 -\u003e DID NOT COMPLETE in 20 s (one core pegged at 100% in interegular FSM construction)\n```\n\nEnd-to-end: start `vllm serve \u003cmodel\u003e --structured-outputs-config \u0027{\"backend\":\"lm-format-enforcer\"}\u0027`, then `POST /v1/completions` with `{\"structured_outputs\":{\"regex\":\"(a{1,300}){300}\"}, ...}`. The request never returns; because grammar compile runs in the engine\u0027s structured-output path, concurrent requests stall = worker-level DoS. The identical request against the outlines backend is bounded by `compile_regex_with_timeout` and returns a clean error.\n\n### Impact\n\nUnauthenticated denial of service (vLLM ships with no authentication by default). One request pegs a CPU core and blocks the structured-output engine path.\n\n**Reachability precondition:** the operator must have selected `backend=lm-format-enforcer` via `--structured-outputs-config` (the default is `auto` \u2192 xgrammar). This is the same opt-in tier as the outlines backend that GHSA-rwxx already covered.\n\n### Suggested remediation\n\nRoute the lm-format-enforcer regex compile (`backend_lm_format_enforcer.py:110`) through the same `compile_regex_with_timeout` guard already applied to the xgrammar and outlines backends, and reject un-buildable / oversized patterns in `validate_structured_output_request_lm_format_enforcer`.",
"id": "GHSA-48jh-3gj7-fg8v",
"modified": "2026-09-04T21:37:00Z",
"published": "2026-09-04T21:37:00Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/vllm-project/vllm/security/advisories/GHSA-48jh-3gj7-fg8v"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-73556"
},
{
"type": "WEB",
"url": "https://github.com/vllm-project/vllm/pull/47595"
},
{
"type": "WEB",
"url": "https://github.com/vllm-project/vllm/commit/c9a788eedc412acceaa5112e0d44624b49841577"
},
{
"type": "PACKAGE",
"url": "https://github.com/vllm-project/vllm"
},
{
"type": "WEB",
"url": "https://github.com/vllm-project/vllm/releases/tag/v0.26.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "vLLM: ReDoS via structured_outputs.regex in the lm-format-enforcer backend (no compile timeout) \u2014 missed sibling of GHSA-rwxx-mrjm-wc2m"
}
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.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.