Resumen
En backpropagate >= 1.1.0, la interfaz web opcional basada en Reflex (instalable con pip install backpropagate[ui] y lanzada mediante backprop ui) expone un plano de control de entrenamiento completo: carga de datasets, carga de modelos, inicio y parada de entrenamientos, orquestación de múltiples ejecuciones, exportación GGUF y publicación en HuggingFace Hub.
La CLI acepta dos flags orientados al operador, documentados como controles de seguridad:
--auth user:pass: documentado como "requerir autenticación HTTP Basic en cada petición a la UI".--share: documentado como "exponer la UI en una dirección pública; requiere--auth".
Cuando se pasa --auth user:pass, la CLI imprime Auth: enabled (user: <username>) para confirmar al operador que la autenticación está activa, y exporta BACKPROPAGATE_UI_AUTH=user:pass al subproceso que lanza el backend Reflex.
El backend Reflex (backpropagate/ui_app/**) nunca lee BACKPROPAGATE_UI_AUTH. No se registra ningún middleware de autenticación. No se ejecuta ninguna guardia a nivel de petición. No se ejecuta ninguna guardia en la negociación de actualización WebSocket. Cualquier cliente que alcance el puerto vinculado, ya sea local o remoto según si se usa --share, tiene acceso completo a la UI.
Un comentario inline en backpropagate/cli.py:1217-1218 en el código fuente de v1.1.0 documenta la brecha: "For Phase 1 the variable is exported but Reflex doesn't read it yet." Este comentario era de uso interno; la documentación orientada al usuario (README, CHANGELOG, SHIP_GATE) anunciaba el contrato como aplicado.
Esta alerta se publica principalmente porque el comportamiento en tiempo de ejecución contradecía una afirmación de seguridad dirigida al operador. Los errores exclusivamente de código de forma comparable (verificación de autenticación completamente ausente en una ruta) ya justificarían la divulgación; la dimensión adicional de promesa falsa eleva la severidad.
Impacto
Un atacante que alcance el puerto vinculado puede:
- Leer datasets cargados renderizados en la vista previa de la UI, incluyendo el contenido de cualquier archivo JSONL, CSV o TXT que el operador legítimo haya subido para ajuste fino.
- Disparar ejecuciones de entrenamiento arbitrarias contra cualquier modelo base que el operador tenga instalado localmente o que pueda descargarse desde HuggingFace.
- Disparar publicaciones en HuggingFace Hub hacia repositorios especificados mediante la entrada de la UI (sujeto al alcance del token HF local del operador, típicamente todos los repositorios de su propiedad).
- Provocar un DoS por llenado de disco a través del endpoint
rx.upload(sin límite de tamaño, sin filtro de extensión, sin límite de conteo por sesión en v1.1.0 y v1.1.1). - Leer rutas de modelos (
source_model_path,dataset_path,model,uploaded_path), que son proporcionadas por el usuario y eluden el helpersafe_path()ubicado enbackpropagate/ui_security.py(la validación de rutas es código muerto en la superficie Reflex en v1.1.0 y v1.1.1).
La combinación de control de entrenamiento sin autenticación, suplantación del destino de publicación en HF y traversal mediante entradas de ruta hace que el endpoint afectado sea adecuado tanto para exfiltración de datos (lectura de datos de entrenamiento cargados) como para ataques a la cadena de suministro (publicación de pesos de modelo manipulados en la cuenta HF del operador).
El comportamiento predeterminado de solo escucha local (sin --share) reduce la exposición a un atacante con acceso al host. El flag --share está documentado como una funcionalidad de "URL pública"; los operadores que usaron --share --auth user:pass no recibieron ninguna advertencia de que la parte de autenticación era inerte.
Parches
Corregido en v1.2.0 (publicado el 2026-05-23). El parche implementa middleware ASGI real mediante rx.App(api_transformer=basic_auth_transformer) que protege las rutas HTTP y la negociación de actualización WebSocket /_event. Incluye cuatro modos (no_auth_local_only, token_auto, explicit_creds y production), cookie firmada con HMAC validada antes de websocket.accept(), y listas de permitidos para Host y Origin. El middleware se distribuye junto con una defensa en profundidad de 4 capas en las superficies cli.py, ui_app/app.py, rxconfig.py y eliminación de variables de entorno, de modo que las invocaciones directas con python -m reflex run (que eluden la guardia de la CLI) también aplican autenticación.
Actualización mediante:
# pip
pip install --upgrade backpropagate
# npm
npm install -g @mcptoolshop/backpropagate@latest
Notas de publicación completas: https://github.com/mcp-tool-shop-org/backpropagate/blob/main/CHANGELOG.md#120---2026-05-23
Mitigaciones
Si los usuarios no pueden actualizar de inmediato:
-
No pasar
--authni--shareabackprop ui. Ejecutar la UI sin flags (backprop ui); se vinculará alocalhosty aceptará cualquier cliente que pueda alcanzar127.0.0.1. -
Para acceso remoto, usar reenvío de puertos SSH en lugar de
--share:
# En el cliente:
ssh -L 7860:localhost:7860 <training-host>
# En el servidor:
backprop ui # sin --share
# Luego abrir http://localhost:7860 en el navegador local.
SSH proporciona la capa de autenticación que la UI Reflex no implementaba.
- Auditar despliegues existentes. Si algún host ejecutando
backpropagate >= 1.1.0fue lanzado previamente con--share, tratar cualquier dato de entrenamiento cargado, ruta de modelo o destino de publicación en HF visible en esa sesión de UI como potencialmente expuesto. Revocar y regenerar los tokens HF que hayan estado en uso durante dichas sesiones.
Brecha en la distribución binaria. Los binarios independientes (Windows .exe y macOS .app mediante PyInstaller) no pudieron compilarse para v1.2.0 y se incluirán en una versión de parche posterior. Mientras tanto, los usuarios que dependían de la distribución binaria de v1.1.x deben instalar la versión parcheada mediante pip install backpropagate==1.2.0 para recibir la corrección del bypass de autenticación. Tanto el paquete PyPI de v1.2.0 como el paquete npm @mcptoolshop/backpropagate@1.2.0 incluyen el código parcheado.
Créditos
Descubierto por la auditoría dogfood-swarm Stage A el 2026-05-22 (ID de hallazgo FRONTEND-A-001, clasificado como CRÍTICO). La auditoría también identificó documentación contradictoria en CHANGELOG, SHIP_GATE y README; estas inconsistencias fueron corregidas en v1.2.0 junto con la corrección en tiempo de ejecución.
