# vLLM V0 Multi-Node ZeroMQ Pickle Deserialization RCE Surface

- **Severity:** High
- **Signature ID:** `7b1e4c8a-2d93-4f61-9a0e-5c8d3f27b4e1`
- **CVEs:** CVE-2025-30165

## Summary

vLLM's older V0 engine, when run across multiple machines, sends data between nodes using Python's pickle format over ZeroMQ sockets. Pickle data can execute arbitrary code when loaded, so any host that can reach the ZeroMQ port of a V0 multi-node deployment can potentially run code on it. This detection flags both the risky configuration and command lines that actively use the pickle/ZeroMQ primitives together.

## How the attack works

An operator (or attacker with launch access) starts vLLM with the legacy V0 engine explicitly re-enabled and configures it for multi-node or multi-rank execution — the exact setup where secondary nodes deserialize pickled data received from the primary node's socket. Separately, an attacker with the ability to run commands could invoke a Python or shell interpreter with inline code that both imports a pickle-loading function and a ZeroMQ socket primitive, mirroring the exact receive-and-deserialize pattern the vulnerability abuses. Either shape alone is not enough — the rule only fires when the config markers or the pickle+ZMQ combination appear together on a single command line. This corresponds to the CVE-2025-30165 class of issue in vLLM.

## Why it matters

If exploited, this lets an attacker with network access to the ZeroMQ port execute arbitrary code on a vLLM inference node, potentially giving full control of the machine and any data or models it serves.

## What you can do

- Avoid setting VLLM_USE_V1=0 in multi-node or multi-rank deployments unless a specific feature requires the legacy V0 engine.
- Restrict network access to ZeroMQ ports (and any VLLM_HOST_IP/VLLM_DIST_INIT_ADDR endpoints) to trusted hosts only, never expose them to the open network.
- Review any process launching vLLM with V0 explicitly enabled and confirm it is an intentional, documented deployment rather than an unexpected change.
- Treat repeated alerts from configuration management or restart scripts as expected noise, but verify the underlying launch command is still the one your team approved.

## Known benign look-alikes

- Intentional legacy deployments - teams that pin VLLM_USE_V1=0 with tensor or pipeline parallelism because a required feature (certain quantization kernels, LoRA variants, speculative decoding paths) is not yet supported on the V1 engine. The rule correctly reports the exposure; it is a configuration finding, not proof of exploitation.
- Benchmark and regression harnesses that deliberately launch a V0 multi-node server. Invocations driven by pytest/tox/nox are suppressed, but bespoke shell or Makefile harnesses will still report.
- Configuration management (Ansible, systemd unit re-exec, Kubernetes entrypoint wrappers) replaying a documented V0 launch command line on every restart, producing repeated reports for the same host.
- SRE or ML-platform debugging one-liners that use pyzmq recv_pyobj() against an internal cluster socket to inspect traffic - functionally identical to the vulnerable primitive.
- Security research, advisory reproduction, or purple-team validation of CVE-2025-30165 in a lab environment.
- Migration tooling that A/B launches the same model under V0 and V1 to compare output; the V0 leg will report while the V1 leg will not.

## References

- https://nvd.nist.gov/vuln/detail/CVE-2025-30165
- https://github.com/vllm-project/vllm/security/advisories
- https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/
- https://attack.mitre.org/techniques/T1210/

---
Source: https://www.netzilo.com/threats/vllm-v0-zeromq-pickle-rce
