AI AgentsGuide

vLLM security CVEs 2026: auth bypass and trust_remote_code RCE

vLLM shipped CVE-2026-48746 (auth bypass, CVSS 9.1) plus trust_remote_code RCEs CVE-2026-4944 and CVE-2026-5817. Upgrade to 0.22.1+ now and lock these settings.

Editorial note. This article reports on a fast-moving space. Versions, prices and timelines change: check them against the primary sources (CVE database, project repositories, vendor announcements) before you act on them. Send corrections to [email protected].

vLLM is the inference engine a large share of self-hosted stacks run behind their agents. That makes its 2026 CVE run everyone's problem, not just the maintainers'. Two themes carry through the whole cluster: one critical authentication bypass, and a trust_remote_code problem that keeps resurfacing in a new file each release. Here is the honest accounting, with the version you need to be on and the settings to lock down.

The one that matters most: the auth bypass

CVE-2026-48746 is the critical one, CVSS 9.1. The AuthenticationMiddleware on vLLM's OpenAI-compatible API can be bypassed. The mechanism is a trust problem between layers: the middleware trusts data handed to it by the ASGI web server, and starlette in turn trusts those servers, so a caller can reach the API without presenting the configured VLLM_API_KEY. The affected range is wide — 0.3.0 up to 0.22.0 — which is most of the versions in production right now.

The practical failure is blunt. If you set VLLM_API_KEY and assumed that made your endpoint safe to expose, it did not. An unauthenticated caller can drive your model, burn your GPU, read completions, and use the server as an open relay. Fixed in 0.22.1. If you take one thing from this article: get to 0.22.1 or later, and until you have, treat the API as if the key does not exist — because for an attacker who knows this bug, it does not.

The trust_remote_code problem that will not die

vLLM inherits HuggingFace's trust_remote_code mechanism, which lets a model repository ship Python that runs on load. The safe default is --trust-remote-code=False. Three separate CVEs in 2026 undermined that default in three different ways.

CVE-2026-4944 (HIGH, 8.8) is the plainest. Two model files in 0.14.1, nemotron_vl.py and kimi_k25.py, hardcoded trust_remote_code=True. If you loaded either model, your explicit --trust-remote-code=False was silently overridden and the model's code ran anyway. The user's security choice was ignored by the code path itself.

CVE-2026-5817 (HIGH, 8.2) is the same class in a different backend. The vllm-metal backend, as shipped in Docker Model Runner on macOS, unconditionally sets trust_remote_code=True and runs without a sandbox. AutoTokenizer will then execute arbitrary Python from any model pulled from an OCI registry. Pull a poisoned image, tokenise a prompt, and the model author owns your machine. This is the supply-chain attack the security playbook keeps warning about, made concrete: see /guides/self-hosted-ai-security-playbook-2026.

CVE-2026-41523 (HIGH, 7.5) is the subtlest and my favourite kind of bug to point at. A security check in activation-function loading was written as a Python assert. Under Python's optimised mode — -O, which strips every assert from the bytecode — that check simply does not exist. Run vLLM under python -O and an unauthenticated attacker gets arbitrary code execution by publishing a malicious HuggingFace model. It was present prior to 0.22.0. The lesson is general and worth internalising: a security invariant enforced by assert is not enforced in production if anyone ever runs the interpreter optimised.

The build chain and the memory-safety cluster

CVE-2026-54232 (HIGH, 8.8) moves the attack to build time. vLLM's Dockerfile installed flashinfer-jit-cache from a custom index using --extra-index-url without pinning. That is a textbook dependency-confusion setup: pip can resolve the name against the wrong index and pull an attacker's package into your image. Fixed prior to 0.22.1. If you build vLLM images yourself, pin your build dependencies by version and, ideally, by hash — do not let --extra-index-url decide what "latest" means.

The rest are memory-safety and denial-of-service issues that matter most if you accept requests from anyone you do not fully trust.

  • CVE-2026-53923 (HIGH, 7.5): integer truncation of tensor dimensions in the GGUF dequantize kernels leaves output tensors partially processed — uninitialised memory in your results. Affects 0.5.5 up to 0.23.1rc0.
  • CVE-2026-56340 (HIGH, 8.8): missing sparse-tensor validation in the multimodal embeddings path. With prompt-embeds enabled, crafted embedding requests carrying malformed indices reach code that does not check them. Affects 0.10.2 to before 0.13.0.
  • CVE-2026-5497 (HIGH, 7.5): an out-of-memory denial of service via unbounded frame count in VideoMediaIO.load_base64() for video/jpeg data URLs. A single crafted request can exhaust host memory. Affects 0.8.0 and later.

What to do right now

The remediation is boring, which is the point.

  • Upgrade to at least 0.22.1, and prefer the latest release. 0.22.1 clears the auth bypass, the -O RCE, and the dependency-confusion Dockerfile issue in one move.
  • Never run vLLM under python -O. Check your container entrypoints and process managers; -O sometimes gets added for "performance" by people who do not know it strips asserts.
  • Keep --trust-remote-code=False and understand it is not self-enforcing. Some model files and some backends override it. Do not load models you have not vetted, and be especially wary of the vllm-metal / Docker Model Runner path on macOS.
  • Do not expose the OpenAI-compatible API to the internet unauthenticated. Put it behind a reverse proxy, an allowlist, or a mesh VPN. The API key alone was never the boundary you thought it was.
  • Pin build dependencies. If you build your own images, version-pin and hash-pin, and audit every --extra-index-url.
  • If you take untrusted multimodal or prompt-embeds input, the DoS and memory-safety CVEs move from theoretical to real. Patch and rate-limit.

The through-line is the one we keep landing on: a model is code, an inference server is an application with an attack surface, and a config default only protects you if the code respects it. vLLM's 2026 run is a case study in all three. Get to 0.22.1 or later, drop -O, and stop trusting model repositories you have not read. If you want to track vLLM disclosures as they land rather than reading advisories one at a time, the free tracker is at /cves, and /scanner will check a requirements.txt or docker-compose.yml against this list for you.