GPUStack before 2.2.0 treats loopback-looking requests as the admin (CVE-2026-102895, 9.8); exploited, CISA KEV 2026-11-09; run 2.3.0
TL;DR
GPUStack, an open-source GPU cluster manager for serving models, treated any request whose source looked like 127.0.0.1 as the built-in administrator in every version before 2.2.0. A same-host reverse proxy, or a client-supplied X-GPUStack-Real-IP header, makes a remote request look like loopback, so an unauthenticated network caller gets full admin: users, models, persistent admin API keys, worker and cloud-provider secrets, and code execution on workers. The vendor advisory records exploitation against a 2.1.1 deployment, and CISA added CVE-2026-102895 to the Known Exploited Vulnerabilities catalog on 2026-11-09 with a due date of 2026-11-12. The fix shipped in the gpustack/gpustack:v2.2.0 image on 2026-06-18 with no security wording in the release notes. Run 2.3.0, the current release, because 2.2.2 and 2.3.0 each fixed further authorization bugs. If an instance before 2.2.0 was reachable from an untrusted network, treat every secret it stored as exposed.
What happened
The bug. The CNA record (GitHub, published 2026-11-04 21:16 UTC, updated 2026-11-09) says: "Prior to 2.2.0, get_current_user in gpustack/api/auth.py treated a loopback request source as the built-in administrator when force_auth_localhost was false, which was the default. A remote request could appear to originate from 127.0.0.1 because client_ip_getter accepted a same-host reverse proxy peer or a client-supplied X-GPUStack-Real-IP loopback value." The record lists the impact as "unauthenticated administrative access, including user and model changes, persistent administrator API-key creation, disclosure of worker and cloud-provider secrets, and code execution through POST /v2/inference-backends/from-yaml", and states "Exploitation was observed in the wild against a 2.1.1 deployment." CVSS 3.1 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H), supplied by the GitHub CNA. CWE-287, CWE-290, CWE-346. Affected: < 2.2.0.
Five dates for one bug.
| Date | Event | Source |
|---|---|---|
| 2026-05-19 | Fix merged as pull request #5346, titled "refactor: remove localhost auto-admin bypass" | GitHub issue-search API |
| 2026-06-18 | gpustack/gpustack:v2.2.0 pushed to Docker Hub; GitHub release v2.2.0 dated "18 Jun" |
Docker Hub tag API, release page |
| 2026-07-31 | Vendor advisory GHSA-gj9m-f8ph-pmhr published | vendor advisory page |
| 2026-11-04 | CVE-2026-102895 published by the GitHub CNA | CVE Services |
| 2026-11-09 | Added to CISA KEV, due 2026-11-12; entered the GitHub Advisory Database as reviewed | KEV JSON, database page |
The v2.2.0 release notes, read 2026-11-10, do not contain the words security, localhost or force_auth_localhost and name no CVE or GHSA. The nearest lines are access-control bug fixes such as "Fixed API keys of deactivated users still working". An operator who read the notes in June had no signal that the release closed an unauthenticated admin path. The advisory came six weeks after the release, and the CVE record fourteen weeks after the advisory.
Exploitation. The vendor advisory says: "This vulnerability has been observed exploited in the wild against a v2.1.1 deployment", credits Javier Sixto (ulex.fr) for reporting the active exploitation, and adds that the attackers created custom inference backends on the instance. The KEV entry (dateAdded 2026-11-09, knownRansomwareCampaignUse Unknown, forensicTriage Yes) repeats the CNA's impact list. No count of affected instances is given by the vendor, the CNA or CISA, and this file states none.
The registry does not carry the fix. The advisory and the database row label the package as pip gpustack with patched version 2.2.0. pip index versions gpustack on 2026-11-10 lists 0.5.1 as the newest version, uploaded 2025-02-12, and no 2.x release. GPUStack 2.x is installed from the gpustack/gpustack container image, which is what the current installation docs describe, with no pip path. pip install -U gpustack therefore cannot reach the fix, and a scanner keyed to the PyPI package will flag every pip install as vulnerable with no upgrade available. The fixed artifact is the Docker image.
2.2.0 is not the version to stop at. The releases page, read 2026-11-10, marks v2.2.2 (24 Jul) as a security release for "Missing authorization on several cluster and resource endpoints" affecting 2.2.0 and 2.2.1 and for a SAML callback that trusted an unverified response, and lists a worker that exposed /serveLogs and /debug without authentication among its bug fixes. v2.3.0 (Docker Hub tag pushed 2026-10-23, marked Latest) lists three more: a worker-management authentication bypass that let inference-only API keys reach worker management endpoints, a Kubernetes cluster proxy authorization bypass, and cross-cluster worker registration with cluster-scoped credentials. None of those carries a CVE id on the releases page. This file tracks CVE-2026-102895 and names the others so that "fixed in 2.2.0" is not read as "safe at 2.2.0".
Why it is here. A GPUStack server holds what an AI gateway holds: model-provider keys, cloud credentials for provisioning GPU instances, and worker credentials. It is commonly placed behind nginx or Caddy on the same host, which is one of the two conditions the advisory names. The loopback-means-admin shortcut is the same class as the Loom for AWS default-admin control plane and the header-trust bugs in LLM proxies this corpus already tracks.
Am I affected?
- Find the version.
docker ps --format '{{.Image}} {{.Names}}' | grep -i gpustack, thendocker inspect --format '{{.Config.Image}}' <container>. An untaggedgpustack/gpustackpulled before 2026-06-18 is before 2.2.0. For a pip install,pip show gpustack: any version on PyPI is affected. - Check the two conditions. Is there a reverse proxy on the same host as the server, or can a client reach the API port directly and set headers? Either is enough. Check whether
force_auth_localhostis set totrue. The default wasfalse. - Look for use. In the GPUStack UI or API, list admin API keys and users and look for ones nobody on the team created. List custom inference backends and look for ones nobody defined. Search proxy and application logs for unauthenticated requests to
/v2/inference-backends/from-yamland for anX-GPUStack-Real-IPrequest header arriving from outside.
If you are affected
- Upgrade the image to
gpustack/gpustack:v2.3.0or later. Until then, apply the advisory's workarounds: "Setforce_auth_localhost=trueto require authentication even for loopback requests", strip any client-suppliedX-GPUStack-Real-IPheader at the edge, and "Keep the API off untrusted networks (VPN / edge authentication)." - If the instance was reachable from an untrusted network before the upgrade, assume admin access: delete unknown API keys, users and custom backends, then rotate every model-provider key, cloud credential and worker credential the instance stored, at the issuer. Rotating cloud credentials has the order.
- The CNA lists code execution on workers. Treat worker hosts that ran an unknown backend as compromised and rebuild them; if your local AI agent was exploited covers host triage.
Prevention
- Never use the network source as identity. A reverse proxy on the same host makes every caller local. Require authentication on loopback too, and set the proxy to overwrite, not forward, client IP headers.
- Keep model-serving control planes off the public internet. Put them behind a VPN or an authenticating edge, as the advisory says. Credential hygiene covers scoping the provider keys such a server holds.
- Read the vendor's advisory tab, not only its release notes. This fix shipped as a refactor. Track the image tag you run against the vendor's security advisories and the KEV feed.
Update 2026-11-11: the SAML bypass fixed in 2.2.2 has a CVE, CVE-2026-102894 (9.1), and it affects deployments that never configured SAML
The 2.2.2 SAML fix this file listed with no CVE has one. The GitHub CNA published CVE-2026-102894 on 2026-11-04 (updated 2026-11-06), and the entry reached the GitHub Advisory Database on 2026-11-10. The vendor advisory, GHSA-62m9-f875-rqw6, is dated 2026-09-30.
The bug, per the CNA record. "From 0.7.1 until 2.2.2, the /auth/saml/callback endpoint decoded SAML XML, used its NameID and attributes to resolve or provision a user, and minted a gpustack_session JWT" without verifying "the signature, issuer, audience, destination, or time conditions." "Any network client could submit an identity for an existing user, including an administrator, or provision a new non-administrator account, even when SAML was not configured." CVSS 3.1 9.1 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N), supplied by the GitHub CNA. Affected >= 0.7.1, < 2.2.2.
What changes for readers. 2.2.0 and 2.2.1 close CVE-2026-102895 and are still open to an unauthenticated administrator login through this endpoint. The advice in this file, run 2.3.0, already covers it. The advisory gives no configuration workaround and says to block /auth/saml/callback at the reverse proxy or ingress until the upgrade. Neither the CNA record nor the advisory reports exploitation of this id, and it is not in the KEV catalog as of the 2026-11-10 catalog version.
Credits per the advisory: Austin Chu, Sohee Kim and Corban Villa (UC Berkeley), and an anonymous researcher who reported it earlier and independently.
Sources
- CVE Services: CVE-2026-102895, fetched 2026-11-10: GitHub CNA, published 2026-11-04, updated 2026-11-09; description quoted above;
< 2.2.0; CVSS 3.1 9.8; references to the vendor advisory, pull request #5346, the fix commit and the v2.2.0 release. - gpustack/gpustack: GHSA-gj9m-f8ph-pmhr, fetched 2026-11-10: published 2026-07-31, Critical 9.8, the three workarounds, the exploitation sentence, credits (Nikko Enggaliano, Wei Yunzhou, Rui Yang and Haoyu Wang of Johns Hopkins University, Javier Sixto for the exploitation report). Single vendor source for the mechanism; the CNA record and the KEV entry repeat it.
- GitHub Advisory Database: GHSA-gj9m-f8ph-pmhr, fetched 2026-11-10: database-published and reviewed 2026-11-09, NVD-published 2026-11-04, package labelled pip
gpustack, patched 2.2.0, EPSS 0.331 percent on the read date. - CISA KEV JSON feed, catalog 2026.11.09 fetched 2026-11-10: CVE-2026-102895 "GPUStack Improper Authentication Vulnerability", added 2026-11-09, due 2026-11-12, ransomware use Unknown.
- gpustack/gpustack releases and v2.2.0, fetched 2026-11-10: v2.2.0 dated 18 Jun with no security wording; v2.2.2 and v2.3.0 security lines quoted above; v2.3.0 marked Latest. The pages show day and month only.
- Docker Hub tag API: gpustack/gpustack, read 2026-11-10:
v2.2.0last updated 2026-06-18 15:27 UTC,v2.2.32026-07-31,v2.3.02026-10-23 09:50 UTC. - GPUStack installation docs, fetched 2026-11-10: Docker image
gpustack/gpustack, no pip path described. pip index versions gpustack, run 2026-11-10: newest 0.5.1 (uploaded 2025-02-12 per the PyPI JSON API); no 2.x release.gh api search/issuesforrepo:gpustack/gpustack is:pull-request 5346, run 2026-11-10: title "refactor: remove localhost auto-admin bypass", created and merged 2026-05-19.- 2026-11-11 update sources — CVE Services: CVE-2026-102894, fetched 2026-11-11: GitHub CNA, published 2026-11-04, updated 2026-11-06; description quoted above; range; CVSS 3.1 9.1. GitHub Advisory Database: GHSA-62m9-f875-rqw6, fetched 2026-11-11: vendor advisory 2026-09-30, database entry 2026-11-10, patched 2.2.2, the proxy workaround, credits. CISA KEV JSON catalog 2026.11.10, fetched 2026-11-11: CVE-2026-102894 not listed.