GHSA-gj9m-f8ph-pmhr

Suggest an improvement
Source
https://github.com/advisories/GHSA-gj9m-f8ph-pmhr
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/11/GHSA-gj9m-f8ph-pmhr/GHSA-gj9m-f8ph-pmhr.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-gj9m-f8ph-pmhr
Aliases
Published
2026-11-09T22:15:27Z
Modified
2026-11-09T22:30:04Z
Severity
  • 9.8 (Critical) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H CVSS Calculator
Summary
GPUStack: Authentication bypass via trusted loopback source (reverse-proxy TCP peer or X-GPUStack-Real-IP header) grants unauthenticated admin
Details

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:<port> — 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 client-controllable header) as an authentication signal. When GPUStack is fronted by a same-host reverse proxy, the socket peer is always loopback, so the "localhost is trusted" assumption no longer holds.

Patches

Fixed in gpustack 2.2.0: the loopback auto-admin path was removed and client-IP / forwarding-header handling was hardened. Upgrade to 2.2.0 or later.

Workarounds

  • Set force_auth_localhost=true to require authentication even for loopback requests.
  • Ensure the reverse proxy / gateway cannot cause GPUStack to treat external traffic as loopback, and strip any client-supplied X-GPUStack-Real-IP header at the edge.
  • Keep the API off untrusted networks (VPN / edge authentication).

Remediation (in the fix)

Do not derive authentication from the request's network source. Remove implicit loopback-based admin, and only accept a real client-IP header from an authenticated/trusted gateway (never from arbitrary clients).

Credit

Independently reported by Nikko Enggaliano; Wei Yunzhou; and Rui Yang & Haoyu Wang (Johns Hopkins University). Active in the-wild exploitation was reported by Javier Sixto (ulex.fr).

Database specific
{
    "cwe_ids": [
        "CWE-287",
        "CWE-290",
        "CWE-346"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-11-09T22:15:27Z",
    "nvd_published_at": "2026-11-04T22:17:44Z",
    "severity": "CRITICAL"
}
References

Affected packages

PyPI / gpustack

Package

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
2.2.0

Affected versions

0.*
0.0.0
0.1.0rc1
0.1.0rc2
0.1.0
0.1.1rc1
0.1.1
0.1.2
0.2.0
0.2.1
0.3.0
0.3.1
0.3.2rc1
0.3.2
0.4.0rc2
0.4.0
0.4.1rc1
0.4.1
0.5.0rc1
0.5.0rc2
0.5.0
0.5.1rc1
0.5.1
0.6.0rc1
0.6.0rc2
0.6.0
0.6.1rc1
0.6.1
0.6.2rc1
0.6.2rc2
0.6.2
0.7.0rc1
0.7.0rc2
0.7.0
0.7.1rc1
0.7.1rc2
0.7.1
2.*
2.0.0rc1
2.0.0rc2
2.0.0
2.0.1rc2
2.0.1
2.0.2rc1
2.0.2rc2
2.0.2
2.0.3rc1
2.0.3
2.1.0rc1
2.1.0rc2
2.1.0
2.1.1rc1
2.1.1
2.1.2rc2
2.1.2
2.2.0rc1
2.2.0rc2
2.2.0rc3
2.2.0rc4

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/11/GHSA-gj9m-f8ph-pmhr/GHSA-gj9m-f8ph-pmhr.json"