CVSS 8.1 HIGH RCE

vLLM: Request-controlled mm_processor_kwargs.code_revision allows remote code execution

Mã khác
GHSA-h3rc-6mm3-gc2m
Công bố
Cập nhật
Lần đầu thấy
Nguồn
GitHub Advisory, OSV.dev

Mô tả

Summary

An untrusted multimodal request can set mm_processor_kwargs.code_revision. When vLLM serves a model whose Hugging Face processor uses dynamic auto_map code and the operator enabled --trust-remote-code, this request value reaches AutoProcessor.from_pretrained and selects the Python revision imported by Transformers.

This lets a client replace the operator-reviewed processor module with code from another revision of the same model repository. The operator-selected model/data revision remains pinned; only the executed processor code changes.

Importing a Python module is arbitrary code execution in the vLLM API/renderer process. The PoC below demonstrates this with an import-time filesystem write. It is fully offline and does not require a GPU, model weights, or changes to a real Hub repository.

Affected snapshot
Affected configuration

The vulnerable path exists when all of the following are true:

  1. The served model's processor uses dynamic auto_map.AutoProcessor code.
  2. The operator enabled trust_remote_code.
  3. The server can fetch the request-selected revision, or it is already cached.
  4. The attacker can create or otherwise control a revision in the served model repository. An example is a Hugging Face community pull-request ref when that repository permits them.
  5. A multimodal request reaches the processor path.

The default trust_remote_code=False configuration is not affected.

Attack surface

mm_processor_kwargs is accepted directly by public request models:

/tokenize is particularly relevant because vLLM's authentication middleware guards only /v1, /v2, /inference, and /cohere prefixes:

Consequently, /tokenize remains unauthenticated even when --api-key is configured, unless an external proxy protects it. The vLLM Security Guide documents /tokenize as an unprotected endpoint.

Root cause

The request value follows this path:

  1. OnlineRenderer.preprocess_chat places request mm_processor_kwargs in prompt extras.
  2. Multimodal rendering forwards those kwargs into processor construction through MMProcessorInputs and _process_multimodal_async.
  3. MultiModalConfig.merge_mm_processor_kwargs overlays inference values on startup values, so the request wins.
  4. cached_get_processor_without_dynamic_kwargs filters only recognized processor-call keys. code_revision is retained as a processor-construction kwarg.
  5. cached_processor_from_config pins revision and trust_remote_code, but forwards the remaining kwargs without reserving code_revision.
  6. get_processor calls AutoProcessor.from_pretrained(..., revision=revision, trust_remote_code=trust_remote_code, **kwargs).
  7. Transformers AutoProcessor.from_pretrained uses code_revision to retrieve and import the dynamic module through get_class_from_dynamic_module, then removes it before loading processor data. This is why code comes from the attacker revision while configuration/data remain operator-pinned.

Request-time processor arguments are not separated from processor-construction arguments, and code_revision is not reserved.

Suggested remediation
  1. Separate processor-construction arguments from untrusted processor-call arguments. An allowlist of supported request-time preprocessing controls is safest.
  2. Reject code_revision and other loader/source controls in request mm_processor_kwargs, and pass model_config.code_revision explicitly as the only permitted processor-code revision.
  3. Add a regression test proving a request cannot change the loaded module revision while operator pins remain effective.
  4. Protect /tokenize with the configured authentication policy as defense in depth.

Expected safe behavior is either a 4xx response for reserved request keys or silently ignoring them before processor construction. Rejection is preferable because it makes attempted misuse visible.

A patch for this was merged here: https://github.com/vllm-project/vllm/pull/58830

Điểm và phân loại

CVSS
8.1 HIGH v3.1
Nguồn điểm
GitHub Advisory
Mức độ (theo nguồn)
HIGH
EPSS
0.46%

Vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

Ảnh hưởng

Package Bản bị ảnh hưởng Bản đã sửa
pip vllm >= 0.7.3, < 0.31.0 0.31.0

Vì sao được giữ

  • CVSS 8.1 >= 8.0

Loại tác động

RCE
CWE-94; từ khoá "remote code execution"; từ khoá "arbitrary code execution"

Dữ liệu riêng của nguồn

OSV.dev · ID
GHSA-h3rc-6mm3-gc2m

Tham khảo