{"id":"CVE-2026-102895","aliases":["EUVD-2026-117124","GHSA-gj9m-f8ph-pmhr"],"status":"published","title":"GPUStack: Authentication bypass via trusted loopback source (reverse-proxy TCP peer or X-GPUStack-Real-IP header) grants unauthenticated admin","description":"GPUStack is an open-source GPU cluster manager for AI model serving and GPU instance provisioning. 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 bypass allowed 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. Exploitation was observed in the wild against a 2.1.1 deployment. This issue is fixed in version 2.2.0.","severity":{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-12","score":0.00517,"percentile":0.44486,"model":"v2026.06.15"},"facts":{"in_kev":true,"known_exploited":true,"public_exploit":false,"fix_available":true},"cwes":["CWE-287","CWE-290","CWE-346"],"published":"2026-11-04T21:16:59Z","modified":"2026-11-09T22:30:04Z","kev":{"date_added":"2026-11-09","due_date":"2026-11-12","required_action":"Apply mitigations in accordance with vendor instructions, ensuring compliance with CISA’s BOD 26-04 Prioritizing Security Updates Based on Risk (see URL in Notes) guidance and CISA’s “Forensics Triage Requirements” (see URL in Notes). Follow applicable BOD 26-04 guidance for cloud services or discontinue use of the product if mitigations are unavailable. Stakeholders are responsible for evaluating each asset's internet exposure and ensuring adherence to BOD 26-04 patching guidelines.","known_ransomware_use":"Unknown"},"exploitation":[{"source":"euvd","since":"2026-11-09"},{"source":"kev","since":"2026-11-09"}],"fixes":[{"ecosystem":"PyPI","package":"gpustack","fixed_in":["2.2.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"gpustack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.2.0"}]}]},{"source":"osv","ecosystem":"PyPI","package":"gpustack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.2.0"}]}],"versions":["0.0.0","0.1.0","0.1.0rc1","0.1.0rc2","0.1.1","0.1.1rc1","0.1.2","0.2.0","0.2.1","0.3.0","0.3.1","0.3.2","0.3.2rc1","0.4.0","0.4.0rc2","0.4.1","0.4.1rc1","0.5.0","0.5.0rc1","0.5.0rc2","0.5.1","0.5.1rc1","0.6.0","0.6.0rc1","0.6.0rc2","0.6.1","0.6.1rc1","0.6.2","0.6.2rc1","0.6.2rc2","0.7.0","0.7.0rc1","0.7.0rc2","0.7.1","0.7.1rc1","0.7.1rc2","2.0.0","2.0.0rc1","2.0.0rc2","2.0.1","2.0.1rc2","2.0.2","2.0.2rc1","2.0.2rc2","2.0.3","2.0.3rc1","2.1.0","2.1.0rc1","2.1.0rc2","2.1.1","2.1.1rc1","2.1.2","2.1.2rc2","2.2.0rc1","2.2.0rc2","2.2.0rc3","2.2.0rc4"]}],"products":[{"vendor":"gpustack","product":"gpustack"}],"references":[{"url":"https://github.com/gpustack/gpustack/security/advisories/GHSA-gj9m-f8ph-pmhr","tags":["x_refsource_CONFIRM","Mitigation","Vendor Advisory","advisory","web"]},{"url":"https://github.com/gpustack/gpustack/pull/5346","tags":["x_refsource_MISC","Issue Tracking","Patch","fix","web"]},{"url":"https://github.com/gpustack/gpustack/commit/53f42a6a553542974396d16a4ff6b12bcbedb48d","tags":["x_refsource_MISC","Patch","fix","web"]},{"url":"https://github.com/gpustack/gpustack/releases/tag/v2.2.0","tags":["x_refsource_MISC","Release Notes","web"]},{"url":"https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-102895","tags":["government-resource","US Government Resource","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-102895","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-gj9m-f8ph-pmhr"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/102xxx/CVE-2026-102895.json","tags":["advisory"]},{"url":"https://github.com/gpustack/gpustack","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-102895","title":"GPUStack: Authentication bypass via trusted loopback source (reverse-proxy TCP peer or X-GPUStack-Real-IP header) grants unauthenticated admin","description":"GPUStack is an open-source GPU cluster manager for AI model serving and GPU instance provisioning. 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 bypass allowed 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. Exploitation was observed in the wild against a 2.1.1 deployment. This issue is fixed in version 2.2.0.","status":"published","published":"2026-11-04T21:16:59.842Z","modified":"2026-11-10T04:55:56.196Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"cna"}],"cwes":["CWE-287","CWE-290","CWE-346"],"updated_at":"2026-11-09T17:34:05.130069Z"}],"euvd":[{"id":"EUVD-2026-117124","description":"GPUStack is an open-source GPU cluster manager for AI model serving and GPU instance provisioning. 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 bypass allowed 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. Exploitation was observed in the wild against a 2.1.1 deployment. This issue is fixed in version 2.2.0.","status":"published","published":"2026-11-04T21:16:59Z","modified":"2026-11-10T04:55:56Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"exploited_since":"2026-11-09","updated_at":"2026-11-10T00:18:44.974895Z"}],"ghsa":[{"id":"GHSA-gj9m-f8ph-pmhr","title":"GPUStack: Authentication bypass via trusted loopback source (reverse-proxy TCP peer or X-GPUStack-Real-IP header) grants unauthenticated admin","description":"### Impact\n\nIn 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:\n\n1. **Same-host reverse proxy (TCP peer).** In the canonical self-hosted shape —\n   GPUStack behind a same-host reverse proxy with `proxy_pass\n   http://127.0.0.1:\u003cport\u003e` — every remote request arrives at GPUStack with TCP\n   peer `127.0.0.1`, so the loopback auto-admin branch fires. No header or\n   credential is required. Verified end-to-end against HEAD `6bee5883`.\n2. **`X-GPUStack-Real-IP` header.** A forged `X-GPUStack-Real-IP: 127.0.0.1`\n   header can cause the request source to be treated as loopback.\n\nEither 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.\n\nThis vulnerability has been observed exploited in the wild against a v2.1.1 deployment (attacker-created custom backends running reverse shells).\n\n### Root cause\n\nTrusting 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.\n\n### Patches\n\nFixed 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.\n\n### Workarounds\n\n- Set `force_auth_localhost=true` to require authentication even for loopback\n  requests.\n- Ensure the reverse proxy / gateway cannot cause GPUStack to treat external\n  traffic as loopback, and strip any client-supplied `X-GPUStack-Real-IP`\n  header at the edge.\n- Keep the API off untrusted networks (VPN / edge authentication).\n\n### Remediation (in the fix)\n\nDo 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).\n\n### Credit\n\nIndependently reported by Nikko Enggaliano; Wei Yunzhou; and Rui Yang \u0026 Haoyu Wang (Johns Hopkins University). Active in the-wild exploitation was reported by Javier Sixto (ulex.fr).","status":"published","published":"2026-11-09T22:15:27Z","modified":"2026-11-09T22:15:29Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"cwes":["CWE-287","CWE-290","CWE-346"],"updated_at":"2026-11-09T22:20:10.289641Z"}],"kev":[{"id":"CVE-2026-102895","title":"GPUStack Improper Authentication Vulnerability","description":"GPUStack contains an improper authentication vulnerability which could allow 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.","cwes":["CWE-287","CWE-290","CWE-346"],"kev":{"date_added":"2026-11-09","due_date":"2026-11-12","required_action":"Apply mitigations in accordance with vendor instructions, ensuring compliance with CISA’s BOD 26-04 Prioritizing Security Updates Based on Risk (see URL in Notes) guidance and CISA’s “Forensics Triage Requirements” (see URL in Notes). Follow applicable BOD 26-04 guidance for cloud services or discontinue use of the product if mitigations are unavailable. Stakeholders are responsible for evaluating each asset's internet exposure and ensuring adherence to BOD 26-04 patching guidelines.","known_ransomware_use":"Unknown"},"updated_at":"2026-11-09T17:08:36.530222Z"}],"nvd":[{"id":"CVE-2026-102895","description":"GPUStack is an open-source GPU cluster manager for AI model serving and GPU instance provisioning. 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 bypass allowed 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. Exploitation was observed in the wild against a 2.1.1 deployment. This issue is fixed in version 2.2.0.","status":"published","published":"2026-11-04T22:17:44.613Z","modified":"2026-11-10T05:17:40.97Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"secondary"}],"cwes":["CWE-287","CWE-290","CWE-346"],"updated_at":"2026-11-09T22:15:54.230687Z"}],"osv":[{"id":"CVE-2026-102895","title":"GPUStack: Authentication bypass via trusted loopback source (reverse-proxy TCP peer or X-GPUStack-Real-IP header) grants unauthenticated admin","description":"GPUStack is an open-source GPU cluster manager for AI model serving and GPU instance provisioning. 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 bypass allowed 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. Exploitation was observed in the wild against a 2.1.1 deployment. This issue is fixed in version 2.2.0.","status":"published","published":"2026-11-04T21:16:59.842Z","modified":"2026-11-11T02:48:54.641415997Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"cwes":["CWE-287","CWE-290","CWE-346"],"updated_at":"2026-11-10T02:45:42.584685Z"},{"id":"GHSA-gj9m-f8ph-pmhr","title":"GPUStack: Authentication bypass via trusted loopback source (reverse-proxy TCP peer or X-GPUStack-Real-IP header) grants unauthenticated admin","description":"### Impact\n\nIn 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:\n\n1. **Same-host reverse proxy (TCP peer).** In the canonical self-hosted shape —\n   GPUStack behind a same-host reverse proxy with `proxy_pass\n   http://127.0.0.1:\u003cport\u003e` — every remote request arrives at GPUStack with TCP\n   peer `127.0.0.1`, so the loopback auto-admin branch fires. No header or\n   credential is required. Verified end-to-end against HEAD `6bee5883`.\n2. **`X-GPUStack-Real-IP` header.** A forged `X-GPUStack-Real-IP: 127.0.0.1`\n   header can cause the request source to be treated as loopback.\n\nEither 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.\n\nThis vulnerability has been observed exploited in the wild against a v2.1.1 deployment (attacker-created custom backends running reverse shells).\n\n### Root cause\n\nTrusting 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.\n\n### Patches\n\nFixed 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.\n\n### Workarounds\n\n- Set `force_auth_localhost=true` to require authentication even for loopback\n  requests.\n- Ensure the reverse proxy / gateway cannot cause GPUStack to treat external\n  traffic as loopback, and strip any client-supplied `X-GPUStack-Real-IP`\n  header at the edge.\n- Keep the API off untrusted networks (VPN / edge authentication).\n\n### Remediation (in the fix)\n\nDo 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).\n\n### Credit\n\nIndependently reported by Nikko Enggaliano; Wei Yunzhou; and Rui Yang \u0026 Haoyu Wang (Johns Hopkins University). Active in the-wild exploitation was reported by Javier Sixto (ulex.fr).","status":"published","published":"2026-11-09T22:15:27Z","modified":"2026-11-09T22:30:04.096651997Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"cwes":["CWE-287","CWE-290","CWE-346"],"updated_at":"2026-11-09T22:41:08.537457Z"}]}}
