---
id: "CVE-2026-48797"
kind: "vulnerability"
aliases: ["CVE-2026-48797", "GHSA-f65r-h4g3-3h9h"]
title: "Backpropagate: backprop ui --auth and backprop ui --share do not enforce authentication"
severity: "critical"
cvss: 9.3
epss: 0.00324
exploited: false
status: "open"
category: "package"
products: [{"name": "backpropagate", "fixed": ["1.2.0"], "affected": ">= 1.1.0, < 1.2.0", "ecosystem": "pypi"}, {"name": "@mcptoolshop/backpropagate", "fixed": ["1.2.0"], "affected": ">= 1.1.0, < 1.2.0", "ecosystem": "npm"}]
ecosystems: ["npm", "pypi"]
tags: ["cwe-1295", "cwe-358", "cwe-862", "huggingface", "ml-training", "npm", "package", "python", "self-hosted"]
not_affected_if: ["cli-only-use", "ui-not-installed", "version-1.2.0-or-later"]
published_at: "2026-06-17T13:20:43+00:00"
first_seen_at: "2026-10-27T16:20:27+00:00"
updated_at: "2026-10-27T16:33:07+00:00"
sources: [{"source": "ghsa", "url": "https://github.com/advisories/GHSA-f65r-h4g3-3h9h", "first_seen_at": "2026-10-27T16:20:27+00:00"}, {"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-48797", "first_seen_at": "2026-10-27T16:33:07+00:00"}]
---

# Backpropagate: backprop ui --auth and backprop ui --share do not enforce authentication

The optional Backpropagate web UI ignores the --auth and --share flags, so the Reflex backend never checks credentials. Anyone who can reach the bound port can read uploaded training datasets, start training runs, and trigger Hugging Face Hub pushes.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- pypi:backpropagate affected >= 1.1.0, < 1.2.0 fixed 1.2.0
- npm:@mcptoolshop/backpropagate affected >= 1.1.0, < 1.2.0 fixed 1.2.0

## How to check

- Run `pip show backpropagate` or `npm ls @mcptoolshop/backpropagate` and compare the version against `1.2.0`.
- Look for `backprop ui` launched with `--share` or `--auth` in service files, shell history or process lists.
- Check whether port 7860 is reachable from other hosts.

## Fix

- Upgrade the PyPI package to `backpropagate==1.2.0` or later (`pip install --upgrade backpropagate`).
- Upgrade the npm package to `@mcptoolshop/backpropagate@1.2.0` or later (`npm install -g @mcptoolshop/backpropagate@latest`).
- Until upgraded, run `backprop ui` without `--auth` or `--share` and reach it over SSH port-forwarding.
- Rotate any Hugging Face tokens used in sessions that were started with `--share`.

## Timeline

- 2026-10-27T16:20:27+00:00 ghsa https://github.com/advisories/GHSA-f65r-h4g3-3h9h
- 2026-10-27T16:33:07+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-48797

## From the sources

## Summary

In `backpropagate >= 1.1.0`, the optional Reflex web UI (`pip install backpropagate[ui]`, launched via `backprop ui`) exposes a training control plane: 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."
- `--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.

This advisory is filed primarily because the runtime contradicted an operator-facing security claim. Code-only bugs of comparable shape (auth check missing entirely from a path) would already warrant disclosure; the additional false-promise dimension raises the severity.

## Impact

An attacker who reaches the bound port can:

- **Read uploaded datasets** rendered in the UI preview, including content of any JSONL/CSV/TXT file the legitimate operator has uploaded for fine-tuning.
- **Trigger arbitrary training runs** against any base model the operator has installed locally or that can be downloaded from HuggingFace.
- **Trigger HuggingFace Hub pushes** to repositories named via the UI input (subject to the operator's local HF token's scope — typically all repos owned by the operator).
- **Cause disk-fill DoS** via the `rx.upload` endpoint (no size cap, no extension filter, no per-session count cap in v1.1.0 / v1.1.1).
- **Read model paths** (`source_model_path`, `dataset_path`, `model`, `uploaded_path`) which are user-supplied and bypass the `safe_path()` helper that lives in `backpropagate/ui_security.py` (path validation is dead code on the Reflex surface in v1.1.0 / v1.1.1).

The combination of unauthenticated training control, HF push target spoofing, and path-input traversal makes the affected endpoint suitable for both data exfiltration (reading uploaded training data) and supply-chain attacks (pushing tampered model weights to the operator's HF account).

The local-only default (no `--share`) reduces exposure to a host-local attacker. The `--share` flag is documented as a "public URL" feature; operators who used `--share --auth user:pass` had no warning that the auth half was inert.

## Patches

Fixed in **v1.2.0** (released 2026-05-23). The patch implements real ASGI middleware via `rx.App(api_transformer=basic_auth_transformer)` that gates HTTP routes AND the `/_event` WebSocket upgrade. Four modes (`no_auth_local_only` / `token_auto` / `explicit_creds` / `production`), HMAC-signed cookie validated PRE-`websocket.accept()`, Host + Origin allowlists. The middleware ships alongside a 4-layer defense in depth at the cli.py / ui_app/app.py / rxconfig.py / env-strip surfaces so direct `python -m reflex run` invocations (bypassing the CLI guard) also enforce authentication.

Upgrade with:

- pip: `pip install --upgrade backpropagate`
- npm: `npm install -g @mcptoolshop/backpropagate@latest`

Full release notes: https://github.com/mcp-tool-shop-org/backpropagate/blob/main/CHANGELOG.md#120---2026-05-23

## Workarounds

If users cannot upgrade immediately:

1. **Do not pass `--auth` or `--share` to `backprop ui`.** Run the UI with no flags (`backprop ui`); it will bind to `localhost` and accept any client that can reach `127.0.0.1`.
2. **For remote access, use SSH port-forwarding** instead of `--share`:
   ```
   # On the client:
   ssh -L 7860:localhost:7860 <training-host>
   # On the server:
   backprop ui            # no --share
   # Then open http://localhost:7860 in your local browser.
   ```
   SSH provides the authentication layer the Reflex UI did not.
3. **Audit existing deployments.** If any host running `backpropagate >= 1.1.0` has previously been launched with `--share`, treat any uploaded training data, model paths, or HF push targets visible in that UI session as potentially exposed. Re-issue HF tokens that have been in use during such sessions.

**Binary distribution gap.** Standalone binaries (Windows .exe / macOS .app via PyInstaller) failed to build for v1.2.0 and will land in a follow-up patch release. In the interim, users who relied on the v1.1.x binary distribution should install the patched version via `pip install backpropagate==1.2.0` to receive the auth-bypass fix. The v1.2.0 PyPI package and `@mcptoolshop/backpropagate@1.2.0` npm package both carry the patched code.

## Credit

Discovered by the dogfood-swarm Stage A audit on 2026-05-22 (finding ID `FRONTEND-A-001`, classified CRITICAL). The audit also surfaced contradicting documentation in CHANGELOG / SHIP_GATE / README; those were corrected in v1.2.0 alongside the runtime fix.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
