
OpenMed < 1.5.2 RCE no autenticado a través de la carga del modelo del filtro de privacidad PII y trust_remote_code=True
Severidad: Crítica, CVSS 4.0 9.3, CVSS 3.1 9.8 (asignado por VulnCheck, la CNA)
Vector (v4.0): CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Vector (v3.1): CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Afectados: OpenMed < 1.5.2
Corregido en: 1.5.2
CWE: CWE-94 (Control Inadecuado de la Generación de Código, Inyección de Código)
Reportado por: Sai Teja Erukude
CNA: VulnCheck
Publicado: 2 de junio de 2026
OpenMed anterior a 1.5.2 contiene una vulnerabilidad de ejecución remota de código no autenticada en la ruta de carga del modelo de filtro de privacidad PII.
Los endpoints de la API REST POST /pii/extract y POST /pii/deidentify aceptan un valor model_name del cuerpo de la solicitud. En las versiones vulnerables, el despachador del filtro de privacidad utilizaba una coincidencia amplia de subcadenas sobre este valor controlado por el atacante. Un nombre de modelo como attacker/foo-privacy-filter-bar podía, por tanto, enrutarse al backend del filtro de privacidad.
En implementaciones que no son MLX/Torch, ese backend cargaba los artefactos de modelos de Hugging Face a través de Transformers con trust_remote_code=True. Si el repositorio de modelos controlado por el atacante contenía código personalizado de Transformers referenciado mediante auto_map en config.json o tokenizer_config.json, Transformers importaba y ejecutaba ese código Python durante la carga del modelo o del tokenizador.
El código importado se ejecutaba con los privilegios del proceso de servicio de OpenMed.
Un atacante remoto no autenticado que pueda alcanzar la API REST de OpenMed puede ejecutar código Python arbitrario en el servidor proporcionando un identificador de modelo malicioso de estilo Hugging Face en model_name.
Dependiendo del despliegue del servicio, esto puede permitir:
El problema es alcanzable a través de ambos endpoints PII porque ambos aceptan model_name y usan la misma ruta de extracción/carga de modelos PII:
POST /pii/extract
Content-Type: application/json
{
"text": "John Doe called 555-1212",
"model_name": "attacker/foo-privacy-filter-bar",
"confidence_threshold": 0.0
}
POST /pii/deidentify
Content-Type: application/json
{
"text": "John Doe called 555-1212",
"model_name": "attacker/foo-privacy-filter-bar",
"confidence_threshold": 0.0
}
El flujo de control vulnerable tiene dos fallos de límite de confianza:
model_name proporcionado por el usuario al seleccionar el backend del filtro de privacidad.trust_remote_code=True.El despachador trataba cualquier identificador de modelo que contuviera privacy-filter como parte de la familia del filtro de privacidad. Esto permitía que identificadores controlados por el atacante, por ejemplo attacker/foo-privacy-filter-bar, alcanzaran una ruta de código destinada a los modelos de filtro de privacidad de primera parte confiables.
Una vez enrutado allí, Transformers podía cargar código personalizado controlado por el atacante mediante auto_map. Esta importación ocurre durante la carga del modelo/tokenizador, antes de que tenga que tener éxito ninguna inferencia útil. Por tanto, una carga útil de prueba puede ser tan pequeña como:
from pathlib import Path
Path("marker.txt").write_text(
"custom Transformers code executed via trust_remote_code\n",
encoding="utf-8",
)
poc_exploit.py construye un directorio local inofensivo de modelo de estilo Hugging Face cuyo nombre contiene privacy-filter. Los módulos personalizados de Transformers generados escriben un archivo marcador cuando se importan. El script envía entonces una solicitud a una instancia de prueba de la API de OpenMed con ese directorio como model_name.
El comportamiento esperado en versiones vulnerables de OpenMed es:
model_name controlado por el atacante.trust_remote_code=True.Ejecutar solo contra una instancia local de prueba:
pip install -r requirements.txt
python poc_exploit.py --target http://127.0.0.1:8000 --endpoint /pii/extract
Si el servicio OpenMed se ejecuta en algún lugar que no puede acceder al directorio local generado, publique un modelo de prueba equivalente en un repositorio de Hugging Face controlado y pase ese identificador explícitamente:
python poc_exploit.py \
--target http://127.0.0.1:8000 \
--model-name your-org/foo-privacy-filter-bar \
--marker marker.txt
Actualice a OpenMed 1.5.2 o posterior.
OpenMed 1.5.2 separa el enrutamiento de la confianza:
privacy-filter ya no se enrutan a través de la ruta confiable del filtro de privacidad.PrivacyFilterTorchPipeline establece trust_remote_code en False de forma predeterminada.OPENMED_TRUSTED_REMOTE_CODE_MODELS.Si la actualización inmediata no es posible:
model_name controlados por el usuario a Transformers con trust_remote_code=True.Descubierta y reportada por Sai Teja Erukude, coordinada a través de VulnCheck.
| Fecha | Evento |
|---|
| 18 de mayo de 2026 | Vulnerabilidad enviada a VulnCheck |
| 20 de mayo de 2026 | VulnCheck inició el proceso de divulgación coordinada |
| 22 de mayo de 2026 | CVE-2026-47117 asignado provisionalmente |
| 1 de junio de 2026 | Corrección de OpenMed 1.5.2 revisada y confirmada |
| 2 de junio de 2026 | CVE-2026-47117 publicado |