What happened
get_current_user in gpustack/api/auth.py treated a loopback source as the built-in administrator when force_auth_localhost was false (the default). Because the client IP getter trusted a same-host reverse-proxy peer or a client-supplied X-GPUStack-Real-IP loopback value, a purely remote request could impersonate localhost. This granted unauthenticated full administrator access, including secret disclosure and RCE through the inference-backends-from-yaml endpoint.
Why it matters
GPUStack is used to serve and provision AI models on GPU fleets. A remote, unauthenticated actor can take over the control plane of an AI serving cluster, read cloud/worker credentials, and execute code on the manager — turning a single open port into full compromise of the AI model-serving infrastructure.
Attack vector
A remote request can be made to appear as originating from 127.0.0.1 because client_ip_getter accepts a same-host reverse-proxy peer or a client-supplied X-GPUStack-Real-IP loopback value. An unauthenticated attacker then reaches get_current_user-as-admin, enabling user/model changes, persistent admin API-key creation, disclosure of worker and cloud-provider secrets, and code execution via POST /v2/inference-backends/from-yaml.
Affected systems
GPUStack < 2.2.0 (also CVE-2026-102894 SAML bypass in 0.7.1–2.2.2 and CVE-2026-103002 cluster_apiserver_proxy authz gap in 2.2.0–2.2.2)
Mitigation
Upgrade to GPUStack 2.2.0 (or 2.2.2 for the SAML/proxy issues); see GHSA-gj9m-f8ph-pmhr and the v2.2.0 tag. Review for admin API keys and worker/cloud secrets created before upgrading.