Biblioteka Python Backpropagate (wersje 1.1.0 i 1.1.1) eksponuje interfejs webowy Reflex do sterowania procesem trenowania modeli językowych bez jakiegokolwiek uwierzytelnienia, mimo że dokumentacja oraz flaga --auth sugerowały odwrotnie. Podatność jest szczególnie groźna, ponieważ operator może nieświadomie udostępnić niezabezpieczony panel publicznie poprzez flagę --share.
▸ Pokaż oryginał (EN)
Backpropagate is a Python library for fine-tuning large language models on a single GPU. In versions 1.1.0 and 1.1.1, the optional Reflex web UI exposes a training control plane without authentication: dataset upload, model load, training start/stop, multi-run orchestration, GGUF export, and HuggingFace Hub push. The CLI accepts two operator-facing flags intended as security controls: --auth user:pass — documented as "require HTTP Basic authentication on every request to the UI." and--share — documented as "expose the UI on a public address; requires --auth." When --auth user:pass is passed, the CLI prints Auth: enabled (user: <username>) to confirm to the operator that authentication is active, then exports BACKPROPAGATE_UI_AUTH=user:pass to the subprocess that launches the Reflex backend. The Reflex backend (backpropagate/ui_app/**) never reads BACKPROPAGATE_UI_AUTH. No authentication middleware is registered. No request-level guard runs. No WebSocket upgrade guard runs. Any client that reaches the bound port — local or remote, depending on whether --share is used — has full UI access. An inline comment at backpropagate/cli.py:1217-1218 in the v1.1.0 source documents the gap: "For Phase 1 the variable is exported but Reflex doesn't read it yet." This comment was internal-facing; the user-facing documentation (README, CHANGELOG, SHIP_GATE) advertised the contract as enforced. An attacker who reaches the bound port can read uploaded datasets, trigger arbitrary training runs against any local base models as well as read their paths, trigger HuggingFace Hub pushes and cause disk-fill DoS. This issue has been fixed in version 1.2.0. If developers cannot immediately upgrade to 1.2.0 run backprop ui with no flags so it binds to localhost, use SSH port-forwarding (ssh -L 7860:localhost:7860 <training-host>) instead of --share for remote access, and audit any host previously launched with --share, re-issuing any HF tokens used during those sessions.
Flaga CLI --auth user:pass jedynie eksportuje zmienną środowiskową BACKPROPAGATE_UI_AUTH do procesu potomnego uruchamiającego backend Reflex, jednak backend nigdy tej zmiennej nie odczytuje — żadne middleware uwierzytelniające ani żadna kontrola na poziomie żądań HTTP czy połączeń WebSocket nie są zarejestrowane. W kodzie źródłowym wersji 1.1.0 (plik backpropagate/cli.py, linie 1217–1218) widnieje komentarz wewnętrzny: "For Phase 1 the variable is exported but Reflex doesn't read it yet", podczas gdy dokumentacja użytkownika (README, CHANGELOG, SHIP_GATE) prezentowała mechanizm jako w pełni działający. Każdy klient, który osiągnie nasłuchujący port — lokalnie lub zdalnie przy użyciu flagi --share — uzyskuje pełny dostęp do panelu sterowania.
Nieuwierzytelniony atakujący może odczytać przesłane zbiory danych treningowych, uruchamiać dowolne sesje trenowania na lokalnych modelach bazowych oraz poznawać ich ścieżki na dysku, inicjować publikację modeli na HuggingFace Hub (co może skutkować ujawnieniem tokenów HF), a także wywołać atak DoS poprzez zapełnienie dysku.
Należy zaktualizować Backpropagate do wersji 1.2.0, w której problem został naprawiony. Do czasu aktualizacji: uruchamiać interfejs UI bez żadnych flag (wiązanie wyłącznie do localhost), zamiast flagi --share stosować tunel SSH (ssh -L 7860:localhost:7860 <host-treningowy>) dla dostępu zdalnego oraz przeprowadzić audyt hostów, na których wcześniej używano flagi --share, i unieważnić wszystkie tokeny HuggingFace wykorzystywane podczas takich sesji.
Backpropagate w wersjach 1.1.0 oraz 1.1.1 (biblioteka Python do fine-tuningu dużych modeli językowych); problem dotyczy instancji uruchomionych z opcjonalnym interfejsem webowym Reflex, szczególnie narażone są instalacje używające flagi --share.
W kodzie źródłowym wersji 1.1.0 istnieje jawny komentarz wewnętrzny (backpropagate/cli.py:1217–1218) potwierdzający świadomość luki na etapie implementacji: uwierzytelnienie zostało celowo pominięte jako funkcja planowana na późniejszy etap, lecz nie zostało to zakomunikowane użytkownikom.
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X