A remote-code-execution flaw in vLLM's Qwen3-Coder tool parser let text generated by a language model execute as code on the machine serving it. GitHub's advisory for CVE-2025-9141 says the parser called Python's eval() while handling unknown tool-call parameter types, and the fix landed in vLLM 0.10.1.1. That bug is the concrete anchor under an essay by Boyd Kane that spent this week near the top of Hacker News, arguing that inference engines -- not just models -- belong in the threat model.
Key facts
- The vulnerability is CVE-2025-9141, in vLLM's
qwen3_codertool-call parser, fixed in 0.10.1.1. - The mechanism: the parser ran Python's
eval()on model-produced tool-call parameters. - The essay reached 95 points and 21 comments on Hacker News.
- Primary sources: the GitHub security advisory, the fix commit, and Kane's essay.
Most people picture a language model as something that produces text, and text as something inert. Words come out, a human or a UI reads them, nothing happens on its own. That picture was accurate in 2022 and it is not accurate now.
Here is what changed. Modern serving stacks do not stop at text. When a model emits a tool call, the server has to turn that generated string into a structured action: parse the arguments, coerce the types, dispatch the function. That parsing happens on the serving machine, in the serving process, with the serving process's privileges. Kane's argument is simply that this parsing layer is code, code has bugs, and the entity supplying its input is a language model. If you can influence what the model writes, you can influence what the parser eats.
The vLLM advisory is what turns that from a thought experiment into an incident report. A parser handling Qwen3-Coder's tool-call format hit a parameter type it did not recognize and fell back to eval(), Python's "just run this string as code" escape hatch. That is a decades-old category of mistake, and it is unremarkable except for where it sits: at the exact boundary where model output crosses into host execution. The path is reachable when tool calling is enabled and the server is started with --tool-call-parser qwen3_coder, which is the documented, recommended way to run that model.
The analogy that fits is SQL injection, and it is nearly exact. For years, applications built database queries by pasting user text into a command string, on the assumption that user text was data. It was not; it was code, the moment the parser treated it as such. Model output is now in the same position. It looks like data. In a serving stack with tool calling on, it is partly control flow. Ground Truth's explainers on prompt injection and tool use and function calling cover the two halves of that seam.
Why it matters more this month than last: the industry is racing to make the agent loop itself a product. OpenAI just open-sourced the Codex harness, DeepSeek made its agent loop a plugin, and a proxy that rewires Claude Code's model backend now has 49,000 stars. Every one of those layers adds parsing between a model's tokens and a machine's behavior. The count of places where generated text becomes executed structure is going up fast, and each is written by a different team under release pressure.
The Hacker News reaction was the useful part, because it was neither dismissive nor breathless. One operator described already running vLLM inside a separately sandboxed virtual machine on a firewalled VLAN with logging shipped off-box, which is the correct posture and also an admission that the essay is describing something people already defend against. Another commenter called it "an important gap area" created by parser complexity and feature creep. The strongest pushback reframed the piece precisely: this is about attacking an inference engine through its HTTP interface, not about a model escaping a sandbox of its own volition. That reframing is right, and it makes the risk more mundane and more likely rather than less.
The honest caveat, and it is a significant one: the essay's claim that the same breach path is proven in SGLang does not hold up against SGLang's own record. SGLang's documentation does still expose --tool-call-parser qwen3_coder, so the same class of surface exists there. But its security advisories page currently lists no published advisories matching the claim. The generalizable lesson is real; the second data point is not yet on the board.
The practical takeaway is short. If you self-host, treat the inference server as an internet-facing application with a hostile input source, because it is one -- pin versions, read the advisories, and put it behind a boundary you would be comfortable losing.
Originally published on Ground Truth, where every claim is checked against the primary source.
Top comments (0)