vLLM Qwen3-Coder Tool Parser eval() RCE Payload Execution
vLLM's parser for Qwen3-Coder tool calls passes unrecognized parameter types straight into Python's eval(). Any authenticated user who can send a tool call to the inference server can use this to run arbitrary code, including spawning reverse shells or downloading and executing malware.
How the attack works
An attacker with API access sends a tool call whose parameter has a type the parser doesn't recognize. Instead of rejecting or safely handling it, vLLM feeds the raw parameter string to Python's eval(), executing it as code. The attacker's eval() payload then spawns a child process - a reverse shell, a shell-to-shell pipe, or a downloader that fetches and runs a second-stage script. Because the eval() call itself isn't visible as a distinct event, detection relies on catching the resulting process execution: either a clear code-injection/reverse-shell command line, or an inline Python interpreter call combined with a way to execute processes (os.system, subprocess with shell=True, pty.spawn, etc.).
Netzilo detection
Netzilo reports this behaviour when it is observed.
- Signature ID
- 7f3c1e42-9b5a-4d18-8c0f-2a6e5b41d9c7
- Severity
- High
Why it matters
An attacker who can already call the model's tool interface gains full code execution on the inference server, which can lead to data theft, lateral movement, or persistent backdoors on infrastructure that hosts the model.
What you can do
- →Restrict who can send tool calls to vLLM deployments running the qwen3_coder parser; treat tool-call access as equivalent to shell access.
- →Validate and constrain tool-call parameter types at the application layer before they reach vLLM, rejecting anything with an unrecognized type.
- →Run inference servers with minimal privileges and no direct outbound network access to reduce the value of a resulting reverse shell or downloader.
- →Review process-execution logs on inference hosts for inline Python one-liners that shell out or open sockets, especially those following a tool-call request.
Known benign look-alikes
- Developer or agent shell sessions running an inline Python one-liner that shells out, e.g. python -c "import os; os.system('make test')".
- CI/container wait-for-service and health-check helpers written as inline Python that open a socket and then spawn a subprocess (only matches when both a socket and dup2/pty appear, so plain connect-and-exit probes are already excluded).
- Security tooling, CTF material, or deliberate CVE reproduction executed on a lab host - the payload is genuinely executed, so this is a true positive on the host even when the intent is benign.
- Package build backends invoking the interpreter with -c and a shell=True subprocess call; the common sysconfig/distutils/setuptools probe shapes are suppressed by filter_interpreter_probe.
- Internal mirrors serving installer scripts over plaintext HTTP that are piped to a shell.