Impacto

Una vulnerabilidad de bypass de trust_remote_code en DiffusionPipeline.from_pretrained permite la ejecución remota de código arbitrario a pesar de que el usuario pase trust_remote_code=False (o lo omita, que es el valor por defecto). La vulnerabilidad tiene tres variantes, todas compartiendo la misma causa raíz: la puerta de trust_remote_code fue implementada dentro de DiffusionPipeline.download() en lugar de en el sitio real de carga del módulo dinámico, por lo que cualquier ruta de código que evitara o cortocircuitara download() también evitaba la verificación de seguridad:

  1. custom_pipeline entre repositorios. DiffusionPipeline.from_pretrained('repoA', custom_pipeline='atacante/repoB', trust_remote_code=False): la puerta evaluaba contra la lista de archivos de repoA en lugar de la de repoB, por lo que el pipeline.py de repoB se cargaba y ejecutaba.

  2. Snapshot local + custom_pipeline de Hub. DiffusionPipeline.from_pretrained('/snapshot/local', custom_pipeline='atacante/repoB', trust_remote_code=False): la rama de ruta local nunca invocaba download(), por lo que nunca se alcanzaba la puerta y se ejecutaba código remoto de repoB.

  3. Snapshot local con componentes personalizados. DiffusionPipeline.from_pretrained('/snapshot/local', trust_remote_code=False) donde el snapshot contiene archivos de componentes personalizados (ej. unet/my_unet_model.py) referenciados desde model_index.json: misma causa raíz; la ruta local omitía download() y se ejecutaba código de componente personalizado.

Ejecución silenciosa de código remoto en la máquina de la víctima. Cualquiera que llame DiffusionPipeline.from_pretrained con pipelines personalizados se ve afectado.

Parches

Sí. Corregido en diffusers 0.38.0 vía PR #13448. Todos los usuarios en versiones < 0.38.0 deben actualizar:

bash pip install --upgrade "diffusers>=0.38.0"

La corrección mueve la puerta de trust_remote_code fuera de DiffusionPipeline.download() y la coloca en get_cached_module_file en src/diffusers/utils/dynamic_modules_utils.py, que es el punto de control real para cada carga de módulo dinámico (local, Hub, o mirror de comunidad). Las tres variantes ahora lanzan ValueError en lugar de ejecutar código no confiable.

Soluciones temporales

Si no es posible actualizar inmediatamente:

  • Solo llame from_pretrained con pretrained_model_name_or_path, custom_pipeline, y directorios de snapshot locales de fuentes completamente confiables que hayan sido auditadas.
  • No pase custom_pipeline= apuntando a un repositorio de Hub diferente del pretrained_model_name_or_path primario antes de leer su pipeline.py.
  • Antes de llamar from_pretrained en un snapshot local, inspeccione el snapshot en busca de archivos *.py inesperados, especialmente bajo subdirectorios de componentes (unet/, scheduler/, etc.) y en la raíz del snapshot.

Estas son mitigaciones, no correcciones: la única remediación completa es actualizar a 0.38.0.

Recursos

  • Corrección: https://github.com/huggingface/diffusers/pull/13448
  • Issue original: https://github.com/huggingface/diffusers/issues/13446
  • Notas de lanzamiento: https://github.com/huggingface/diffusers/releases/tag/v0.38.0
  • CWE-94: https://cwe.mitre.org/data/definitions/94.html