- Severity: CRITICAL
- CVE: CVE-2026-102895
- Ecosystems: pip
- Packages: gpustack
### Impact
In GPUStack before v2.2.0, `get_current_user` (in `gpustack/api/auth.py`) promotes any request whose source is considered loopback to the built-in administrator account when `force_auth_localhost` is `False` (the default). The “source” is derived by `client_ip_getter`, which can be made to report `127.0.0.1` without any credentials in two ways:
1. **Same-host reverse proxy (TCP peer).** In the canonical self-hosted shape —
GPUStack behind a same-host reverse proxy with `proxy_pass
http://127.0.0.1:` — every remote request arrives at GPUStack with TCP
peer `127.0.0.1`, so the loopback auto-admin branch fires. No header or
credential is required. Verified end-to-end against HEAD `6bee5883`.
2. **`X-GPUStack-Real-IP` header.** A forged `X-GPUStack-Real-IP: 127.0.0.1`
header can cause the request source to be treated as loopback.
Either path yields **full, unauthenticated administrative access** over the network: enumerate and modify users, models, workers, and configuration; mint persistent admin API keys (scope `[“*”]`, valid from any source IP thereafter); read worker credentials and cloud/provider secrets. Combined with admin-only functionality such as `POST /v2/inference-backends/from yaml`, this leads to code execution on worker hosts.
This vulnerability has been observed exploited in the wild against a v2.1.1 deployment (attacker-created custom backends running reverse shells).
### Root cause
Trusting the network source of a request (socket peer, or a…
Source: GitHub Security Advisories · 2026-11-09