# vLLM PyNcclPipe Deserialization RCE - Suspicious Process Spawn

- **Severity:** Critical
- **Signature ID:** `7c4a3f2e-9d61-4b8a-9e2f-1c6d8a4b7f30`
- **OWASP:** LLM03 (Supply Chain)

## Summary

vLLM, a popular library for serving large language models, has a component (PyNcclPipe) that unpickles data it receives over the network without checking it first. An attacker who can send data to this component can make it run arbitrary operating system commands.

## How the attack works

vLLM's PyNcclPipe listens for data sent via a StatelessProcessGroup connection, commonly on port 18888. When it receives an object, it calls pickle.loads() on it directly. An attacker sends a crafted pickle object whose __reduce__ method calls something like os.system() or subprocess.Popen(). The moment vLLM unpickles the object, that command runs with vLLM's own privileges. On Linux/macOS this typically shows up as a shell (/bin/sh -c or /bin/bash -c) being launched directly by the vLLM/python process; on Windows it shows up as cmd.exe /c or powershell.exe, often carrying commands that download and run further code, open a reverse shell, or decode and execute base64 payloads.

## Why it matters

Successful exploitation gives an attacker arbitrary command execution on the host running vLLM, at whatever privilege level the vLLM process has — a foothold that can be used for data theft, lateral movement, or further compromise.

## What you can do

- Do not expose the PyNcclPipe/StatelessProcessGroup port (default 18888) to untrusted networks; restrict it to trusted hosts only, ideally over a private network or with authentication in front of it.
- Upgrade vLLM to a version that validates or restricts deserialization on this channel, if available, or disable the feature if you don't need distributed pipe communication.
- Monitor for shells or command interpreters (/bin/sh, /bin/bash, cmd.exe, powershell.exe) spawned directly by the vLLM/python process, and correlate with network connections to the PyNcclPipe port to confirm exploitation.
- Review process lineage and outbound network activity from vLLM hosts, since this behavior alone cannot distinguish an attack from legitimate scripts that also spawn shells (e.g. install scripts piping curl into bash).

## Known benign look-alikes

- Legitimate install/bootstrap scripts that pipe curl or wget output directly into bash or sh (e.g. "curl https://get.docker.com | bash")
- Administrative or CI/CD automation that spawns /bin/sh -c or cmd.exe /c with an inline one-off command
- Health-check or network-diagnostic scripts that write to /dev/tcp/<host>/<port> from bash purely to test port connectivity
- Build or packaging tooling that creates named pipes with mkfifo for legitimate inter-process communication
- Deployment or glue-code Python invoked as `python -c "..."` that legitimately calls os.system(), subprocess.Popen()/call()/run(), or socket.socket() for operational (non-malicious) purposes

## References

- https://attack.mitre.org/techniques/T1190/
- https://attack.mitre.org/techniques/T1059/
- https://owasp.org/www-project-top-10-for-large-language-model-applications/
- https://github.com/vllm-project/vllm/security/advisories

---
Source: https://www.netzilo.com/threats/vllm-pynccl-deserialization-rce
