Summary
The vLLM Dockerfile is vulnerable to a dependency confusion attack through the flashinfer-jit-cache package. The package is installed from a custom index (flashinfer.ai/whl/) using --extra-index-url, but the package name was not registered on PyPI, and UV_INDEX_STRATEGY="unsafe-best-match" is set globally. An attacker who registers flashinfer-jit-cache on PyPI with version 0.6.11.post2 can execute arbitrary code as root during the Docker build and backdoor every resulting container image, enabling exfiltration of all user prompts, API credentials, and model data from production vLLM deployments.
After looking into this issue, I noticed that another individual already claimed the flashinfer-jit-cache package on PyPi and published a "sec-test" PoC to https://pypi.org/project/flashinfer-jit-cache/ on March 5th. The package does not appear overtly malicious and has been quarantined by PyPi. However, if this individual tries to remove the package from the quarantine list and publish a malicious version, they could backdoor the vLLM Docker images. Additionally, if the name becomes available again in the future, it exposes vLLM Docker images to a supply chain compromise.
Details
The vulnerable code is in docker/Dockerfile, lines 760-763:
ARG FLASHINFER_VERSION=0.6.11.post2
RUN --mount=type=cache,target=/opt/uv/cache \
uv pip install --system flashinfer-jit-cache==${FLASHINFER_VERSION} \
--extra-index-url https://flashinfer.ai/whl/cu$(echo $CUDA_VERSION | cut -d. -f1,2 | tr -d '.')
Three conditions combine to make this exploitable:
-
flashinfer-jit-cache was not registered on PyPI. A third party did register it at version 0.1.0, but PyPI has quarantined that registration — the name may become available again. As of this report, there is no legitimate registration protecting the namespace.
-
UV_INDEX_STRATEGY="unsafe-best-match" is set as a global ENV at Dockerfile line 118 (inherited by vllm-base at line 693). This strategy searches all configured indexes and picks the "best" version across all of them. When the same version exists on both PyPI and a custom index, PyPI is preferred as the primary index.
-
--extra-index-url adds flashinfer.ai as a secondary index alongside PyPI, rather than replacing it. uv searches both indexes.
The version pin ==0.6.11.post2 does not mitigate this — an attacker publishes the exact same version on PyPI and uv prefers the primary (PyPI) index.
After installation, the Dockerfile executes the compromised package's code at line 850:
RUN flashinfer show-config && flashinfer download-cubin
This runs import flashinfer as root, giving the attacker's payload full filesystem access during the build. The backdoor is baked into the final image layer, which ships as the production vllm/vllm-openai container.
Impact
Successful exploitation of this vulnerability gives an attacker full, root-level remote code execution during the vLLM Docker image build, resulting in a persistent backdoor embedded in every container produced from the official Dockerfile. Because the affected component is loaded automatically on every server startup, the compromise activates silently in production with no reliable way for operators to avoid it.
The attacker can then capture all sensitive data flowing through the deployment, including every user prompt, system message, and authentication token sent to the API, as well as stored cloud and service credentials, and exfiltrate it covertly by disguising the traffic as normal telemetry. Given that this affects the widely distributed official images, the blast radius extends to any organization that builds or pulls them.
Fixes
Summary
The vLLM Dockerfile is vulnerable to a dependency confusion attack through the
flashinfer-jit-cachepackage. The package is installed from a custom index (flashinfer.ai/whl/) using--extra-index-url, but the package name was not registered on PyPI, andUV_INDEX_STRATEGY="unsafe-best-match"is set globally. An attacker who registersflashinfer-jit-cacheon PyPI with version0.6.11.post2can execute arbitrary code as root during the Docker build and backdoor every resulting container image, enabling exfiltration of all user prompts, API credentials, and model data from production vLLM deployments.After looking into this issue, I noticed that another individual already claimed the
flashinfer-jit-cachepackage on PyPi and published a "sec-test" PoC to https://pypi.org/project/flashinfer-jit-cache/ on March 5th. The package does not appear overtly malicious and has been quarantined by PyPi. However, if this individual tries to remove the package from the quarantine list and publish a malicious version, they could backdoor the vLLM Docker images. Additionally, if the name becomes available again in the future, it exposes vLLM Docker images to a supply chain compromise.Details
The vulnerable code is in
docker/Dockerfile, lines 760-763:Three conditions combine to make this exploitable:
flashinfer-jit-cachewas not registered on PyPI. A third party did register it at version0.1.0, but PyPI has quarantined that registration — the name may become available again. As of this report, there is no legitimate registration protecting the namespace.UV_INDEX_STRATEGY="unsafe-best-match"is set as a globalENVat Dockerfile line 118 (inherited byvllm-baseat line 693). This strategy searches all configured indexes and picks the "best" version across all of them. When the same version exists on both PyPI and a custom index, PyPI is preferred as the primary index.--extra-index-urladds flashinfer.ai as a secondary index alongside PyPI, rather than replacing it. uv searches both indexes.The version pin
==0.6.11.post2does not mitigate this — an attacker publishes the exact same version on PyPI and uv prefers the primary (PyPI) index.After installation, the Dockerfile executes the compromised package's code at line 850:
RUN flashinfer show-config && flashinfer download-cubinThis runs
import flashinferas root, giving the attacker's payload full filesystem access during the build. The backdoor is baked into the final image layer, which ships as the productionvllm/vllm-openaicontainer.Impact
Successful exploitation of this vulnerability gives an attacker full, root-level remote code execution during the vLLM Docker image build, resulting in a persistent backdoor embedded in every container produced from the official Dockerfile. Because the affected component is loaded automatically on every server startup, the compromise activates silently in production with no reliable way for operators to avoid it.
The attacker can then capture all sensitive data flowing through the deployment, including every user prompt, system message, and authentication token sent to the API, as well as stored cloud and service credentials, and exfiltrate it covertly by disguising the traffic as normal telemetry. Given that this affects the widely distributed official images, the blast radius extends to any organization that builds or pulls them.
Fixes