CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-102895

CVE-2026-102895: Unauthenticated Administrative Access and Remote Code Execution via Loopback Spoofing in GPUStack

Alon Barad
Alon Barad
Software Engineer

Nov 10, 2026·9 min read·7 visits

Executive Summary (TL;DR)

An authentication bypass in GPUStack (< 2.2.0) allows remote unauthenticated attackers to gain full administrator access by spoofing the X-GPUStack-Real-IP header to 127.0.0.1 or routing requests through a same-host reverse proxy, leading to credential theft and remote code execution.

CVE-2026-102895 is an improper authentication and origin validation vulnerability in GPUStack versions prior to 2.2.0. By default, the API authentication dependency in gpustack/api/auth.py grants built-in administrator privileges to unauthenticated requests resolved as originating from 127.0.0.1 when the force_auth_localhost flag is false. Because client IP resolution trusts same-host reverse proxy TCP peers and unvalidated X-GPUStack-Real-IP headers, remote unauthenticated attackers can bypass authentication, obtain full administrative control, extract sensitive credentials, and achieve remote code execution via the /v2/inference-backends/from-yaml endpoint.

Vulnerability Overview

GPUStack is an open-source GPU cluster manager designed for orchestrating AI model serving and provisioning GPU instances across distributed worker nodes. It exposes a FastAPI-based web management API (typically listening on port 30080) that controls user management, model deployments, cloud provider integrations, and worker node configurations. Because this API governs the entire lifecycle of cluster resources and underlying execution backends, strong authentication boundaries are required on all management endpoints.

Prior to version 2.2.0, GPUStack contained an authentication bypass vulnerability tracked as CVE-2026-102895 (and GHSA-gj9m-f8ph-pmhr). The flaw resides in the core authentication dependency get_current_user within gpustack/api/auth.py. When the configuration option force_auth_localhost is set to False (the default value), the application automatically assigns the primary built-in administrator identity to any incoming HTTP request that lacks authentication credentials but resolves to the loopback IPv4 address (127.0.0.1).

This trust model fails in standard network deployments due to how client IP addresses are evaluated by the client_ip_getter utility. A remote, unauthenticated attacker can satisfy the loopback condition either by routing traffic through a reverse proxy hosted on the same machine as GPUStack—where the immediate TCP socket peer is 127.0.0.1—or by directly injecting the HTTP header X-GPUStack-Real-IP: 127.0.0.1 into requests.

This vulnerability is classified under CWE-287 (Improper Authentication), CWE-290 (Authentication Bypass by Spoofing), and CWE-346 (Origin Validation Error). Successful exploitation grants immediate administrative takeover of the GPUStack cluster, enabling attackers to mint persistent API keys, harvest cloud and worker secrets, and execute arbitrary system commands on worker hosts via custom inference backend configurations. Active exploitation has been observed in the wild against GPUStack 2.1.1 deployments.

Root Cause Analysis

The root cause of CVE-2026-102895 is a combination of implicit localhost privilege elevation and insecure client IP resolution within the FastAPI request handling pipeline. The design intent of the force_auth_localhost setting was to allow local command-line interface (CLI) tools executing on the control plane host to interact with the API without requiring operators to manually pass API tokens.

When an HTTP request reaches a protected endpoint in GPUStack, FastAPI invokes the get_current_user dependency function in gpustack/api/auth.py. This function first checks for standard bearer tokens or basic authentication credentials. If no credentials are provided (user is None), the function falls back to checking whether the client IP address returned by client_ip_getter(request=request) equals "127.0.0.1".

The client_ip_getter function determines the caller's IP address by inspecting incoming HTTP headers—specifically looking for X-GPUStack-Real-IP—before falling back to the underlying ASGI request client host (request.client.host). This introduces two distinct failure modes that break the assumption of local-only access.

First, client_ip_getter trusts the X-GPUStack-Real-IP header unconditionally without verifying whether the immediate network peer is a trusted upstream proxy. Any remote client with direct network access to the GPUStack API port can supply X-GPUStack-Real-IP: 127.0.0.1 to spoof a loopback origin. Second, in production and containerized environments where GPUStack is fronted by a reverse proxy (such as Nginx, Envoy, or Higress) running inside the same network namespace or host, the proxy forwards external requests over the local loopback interface. If the proxy does not set X-GPUStack-Real-IP to the true remote client IP, request.client.host evaluates to the proxy's TCP socket peer (127.0.0.1), causing all external traffic passing through the proxy to be treated as local administrative traffic.

Code Analysis

In versions prior to 2.2.0, gpustack/api/auth.py implemented the fallback authentication logic directly inside get_current_user. When token resolution yielded no user object, the code queried the database for the first user record with the is_admin attribute set to True and returned it as the authenticated session principal.

# gpustack/api/auth.py (Vulnerable logic prior to v2.2.0)
async def get_current_user(request: Request, session: AsyncSession, ...):
    ...
    if token is not None:
        user, api_key = await get_user_from_api_token(session, token)
 
    # VULNERABLE: Implicitly trusts client_ip_getter output to grant admin rights
    if user is None and client_ip_getter(request=request) == "127.0.0.1":
        if not server_config.force_auth_localhost:
            user = await User.first_by_field(session, "is_admin", True)
            
    if user:
        if not user.is_active:
            raise UnauthorizedException(message="User account is deactivated")
        return user

The remediation, committed in 53f42a6a553542974396d16a4ff6b12bcbedb48d (Pull Request #5346), completely removes the loopback authentication bypass rather than attempting to restrict header parsing. The patch deletes the conditional check in gpustack/api/auth.py, ensuring that all requests to protected API endpoints require valid authentication tokens regardless of their network origin.

diff --git a/gpustack/api/auth.py b/gpustack/api/auth.py
index 3b6f0f7f58..e71af95038 100644
--- a/gpustack/api/auth.py
+++ b/gpustack/api/auth.py
@@ -120,9 +120,6 @@ async def get_current_user(
             if token is not None:
                 user, api_key = await get_user_from_api_token(session, token)
 
-        # Removed loopback auto-admin elevation entirely
-        if user is None and client_ip_getter(request=request) == "127.0.0.1":
-            if not server_config.force_auth_localhost:
-                user = await User.first_by_field(session, "is_admin", True)
         if user:
             if not user.is_active:
                 raise UnauthorizedException(message="User account is deactivated")

In addition to removing the bypass logic, the maintainers updated gpustack/config/config.py and gpustack/cmd/start.py to deprecate the force_auth_localhost setting, converting it into a non-functional no-op to preserve backward compatibility with existing deployment manifests and CLI scripts.

diff --git a/gpustack/config/config.py b/gpustack/config/config.py
index 4ad18e7ace..37d4b32b5c 100644
--- a/gpustack/config/config.py
+++ b/gpustack/config/config.py
@@ -157,7 +156,10 @@ class Config(WorkerConfig, BaseSettings):
     resources: Optional[dict] = None
     ssl_keyfile: Optional[dict] = None
     ssl_certfile: Optional[dict] = None
-    force_auth_localhost: bool = False
+    # Deprecated, no-op. Localhost callers must always authenticate now.
+    # Kept for backwards compatibility with existing config files
+    # and CLI invocations. Will be removed in a future release.
+    force_auth_localhost: Optional[bool] = None

The fix is complete with respect to this vulnerability class. By eliminating IP-based authentication altogether and enforcing token verification across both loopback (127.0.0.1 and ::1) and external interfaces, the patch prevents any variant attacks relying on proxy misconfigurations or header spoofing from bypassing authentication. Unit tests added in tests/api/test_auth.py confirm that requests with client_host="127.0.0.1" or x-forwarded-for headers now raise UnauthorizedException when credentials are omitted.

Exploitation

Exploiting CVE-2026-102895 requires network access to the GPUStack HTTP API and a target instance running a version prior to 2.2.0 with force_auth_localhost in its default state (False). No prior authentication, valid user accounts, or user interaction are needed.

An attacker initiates exploitation by sending an unauthenticated HTTP request to an administrative endpoint while including the X-GPUStack-Real-IP: 127.0.0.1 header. If the instance is behind a same-host reverse proxy that does not set X-GPUStack-Real-IP, even standard HTTP requests without the spoofed header will automatically resolve to 127.0.0.1 and succeed. To establish persistent access that survives header-filtering mitigations, attackers first call the API key creation endpoint (POST /v1/api-keys) to generate a valid bearer token bound to the built-in administrator account.

POST /v1/api-keys HTTP/1.1
Host: gpustack.example.com:30080
X-GPUStack-Real-IP: 127.0.0.1
Content-Type: application/json
 
{
  "name": "system-maintenance-key",
  "expires_in": 31536000
}

Once administrative access or a persistent API key is acquired, the attacker can query sensitive endpoints such as GET /v1/cloud-credentials and worker management routes to exfiltrate cloud provider secrets and worker enrollment tokens. To escalate from administrative API access to Remote Code Execution (RCE), the attacker targets the POST /v2/inference-backends/from-yaml endpoint.

POST /v2/inference-backends/from-yaml HTTP/1.1
Host: gpustack.example.com:30080
X-GPUStack-Real-IP: 127.0.0.1
Content-Type: application/json
 
{
  "content": "backend_name: custom-exec\ndefault_run_command: /bin/sh -c 'id > /tmp/pwned'\n..."
}

The /v2/inference-backends/from-yaml endpoint allows administrators to define custom inference engines by supplying a YAML specification that includes container images, custom entrypoints, and shell commands executed when a model instance is scheduled onto a GPU worker node. By registering or modifying an inference backend and deploying a model using that backend, the attacker forces the GPUStack server or connected worker nodes to execute arbitrary operating system commands under the privileges of the GPUStack worker service.

Impact Assessment

The security impact of CVE-2026-102895 is a complete compromise of the GPUStack control plane and all managed GPU worker nodes. The vulnerability carries a CVSS v3.1 base score of 9.8 (Critical) with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. The attack surface is accessible over the network (AV:N), requires low attack complexity (AC:L), demands no privileges (PR:N) or user interaction (UI:N), and results in high impact across confidentiality, integrity, and availability.

In terms of Confidentiality (C:H), attackers gain read access to all data stored within the GPUStack database. This includes third-party cloud provider credentials (GET /v1/cloud-credentials) used to provision external GPU instances, worker registration tokens, internal user metadata, and proprietary AI model weights or prompts processed by the cluster.

In terms of Integrity (I:H) and Availability (A:H), attackers can modify or delete existing user accounts, replace production AI models with poisoned variants, reconfigure inference backends, and execute arbitrary code on the underlying infrastructure via POST /v2/inference-backends/from-yaml. Because GPU clusters typically possess high-bandwidth network connectivity and substantial compute capacity, compromised nodes are prime targets for unauthorized cryptocurrency mining, botnet enrollment, or lateral movement into internal corporate and cloud networks.

> [!NOTE] > CVE-2026-102895 was confirmed as actively exploited in the wild against a production GPUStack 2.1.1 deployment. Consequently, CISA added the vulnerability to the Known Exploited Vulnerabilities (KEV) catalog on November 9, 2026, with a remediation deadline of November 12, 2026 under Binding Operational Directive (BOD) 26-04.

Remediation

The primary remediation is to upgrade GPUStack to version 2.2.0 or later immediately. Version 2.2.0 completely removes the loopback authentication bypass from gpustack/api/auth.py and deprecates the force_auth_localhost configuration parameter. Operators running containerized deployments should pull the gpustack/gpustack:v2.2.0 image and redeploy all server pods.

If an immediate upgrade to 2.2.0 is blocked by operational constraints, administrators can neutralise the vulnerability on versions prior to 2.2.0 by explicitly enforcing authentication on localhost requests. This can be configured via command-line flags (--force-auth-localhost=true), the YAML configuration file (force_auth_localhost: true), or environment variables:

export GPUSTACK_FORCE_AUTH_LOCALHOST=true

In addition to enabling localhost authentication, deployments fronted by a reverse proxy (such as Nginx, Envoy, HAProxy, or Traefik) must be configured to strip or overwrite client-supplied X-GPUStack-Real-IP headers so remote callers cannot spoof their origin IP:

# Nginx configuration to overwrite untrusted client IP headers
location / {
    proxy_set_header X-GPUStack-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:30080;
}

Because CVE-2026-102895 has been exploited in the wild to mint persistent credentials, upgrading or applying workarounds is insufficient if an instance was previously exposed to untrusted networks. Defenders must audit the GPUStack database for unauthorized API keys, administrative users, and modified inference backends created prior to patching:

-- Audit recently created API keys for unauthorized persistence
SELECT id, name, user_id, created_at, expires_at FROM apikeys ORDER BY created_at DESC;

Any unrecognized API keys must be revoked, and all cloud provider credentials and worker tokens stored within the platform should be rotated.

Official Patches

GPUStackGPUStack v2.2.0 Official Release
GPUStackOfficial Security Patch Commit
GPUStackSecurity Pull Request #5346
GPUStackGitHub Security Advisory GHSA-gj9m-f8ph-pmhr

Fix Analysis (1)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.33%
Top 74% most exploited

Affected Systems

GPUStack (< 2.2.0)

Affected Versions Detail

Product
Affected Versions
Fixed Version
GPUStack
gpustack
< 2.2.0 (including v0.6.1, v0.7.0, v0.7.1, v2.0.0, v2.0.1, v2.0.2, v2.1.0, v2.1.1)2.2.0
AttributeDetail
CWE IDCWE-287 (Improper Authentication), CWE-290, CWE-346
CVSS v3.1 Score9.8 Critical (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
Attack VectorNetwork (Unauthenticated HTTP via X-GPUStack-Real-IP or Reverse Proxy)
Affected Componentget_current_user in gpustack/api/auth.py
Primary ImpactUnauthenticated Admin Access, Secret Exfiltration, and RCE via /v2/inference-backends/from-yaml
Exploit StatusActively Exploited in the Wild (Observed on v2.1.1)
CISA KEV StatusListed (Added 2026-11-09, Due 2026-11-12)
EPSS Score0.33% (26.46th Percentile)

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1078Valid Accounts
Initial Access
T1059Command and Scripting Interpreter
Execution
T1552Unsecured Credentials
Credential Access
CWE-287
Improper Authentication

When an actor attempts to access a resource or execute actions, the system fails to verify, or incorrectly verifies, the identity claim of the actor, compounded by CWE-290 (Authentication Bypass by Spoofing) and CWE-346 (Origin Validation Error).

Vulnerability Timeline

CVE-2026-102895 and GHSA-gj9m-f8ph-pmhr published; GPUStack v2.2.0 released with patch
2026-11-04
Added to CISA Known Exploited Vulnerabilities (KEV) catalog following confirmed in-the-wild exploitation against v2.1.1
2026-11-09
NVD and CVE records updated with CISA KEV metadata
2026-11-10
CISA BOD 26-04 remediation due date for federal agencies
2026-11-12

References & Sources

  • [1]NVD CVE-2026-102895 Record
  • [2]CVE.org Official Entry for CVE-2026-102895
  • [3]GitHub Security Advisory GHSA-gj9m-f8ph-pmhr
  • [4]Official Security Patch Commit (53f42a6a553542974396d16a4ff6b12bcbedb48d)
  • [5]GPUStack Security Pull Request #5346
  • [6]GPUStack v2.2.0 Release Notes
  • [7]CISA Known Exploited Vulnerabilities (KEV) Catalog Entry
  • [8]CISA BOD 26-04 Directive
  • [9]CISA Forensics Triage and Implementation Guidance

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•22 minutes ago•CVE-2026-126187
9.5

CVE-2026-126187: Unauthenticated Remote Code Execution in React Server Components

A critical deserialization vulnerability exists in React Server Components (RSC) packages (`react-server-dom-webpack`, `react-server-dom-parcel`, and `react-server-dom-turbopack`) across versions 19.0.0 through 19.3.0. The flaw occurs during the processing of React Flight protocol streams when handling multiple typed arrays sharing a backing ArrayBuffer alongside attacker-controlled inputs. By combining byte-stream buffer detachment semantics with unvalidated thenable invocation and exposed internal response states, an unauthenticated attacker can achieve remote code execution on server runtimes supporting React Server Components.

Alon Barad
Alon Barad
2 views•11 min read
•about 1 hour ago•CVE-2026-125123
2.3

CVE-2026-125123: Improper Output Neutralization and CI Workflow Command Injection in compose-lint CLI Parser

An improper output neutralization vulnerability (CWE-117 / CWE-150) exists in compose-lint version 0.31.0. When compose-lint is invoked on untrusted file paths without a preceding '--' option delimiter, Python's standard argparse module rejects malformed or dash-prefixed paths and writes them directly to standard error without passing through the application's output sanitizer. An attacker submitting a pull request containing crafted directory or file names with carriage returns or Unicode whitespace can inject arbitrary CI workflow commands into GitHub Actions or Azure Pipelines job logs.

Alon Barad
Alon Barad
3 views•10 min read
•about 2 hours ago•CVE-2026-125116
4.8

CVE-2026-125116: Type Confusion in Mongoose Discriminator Resolution

CVE-2026-125116 (GHSA-wr5m-5jph-8m96) is a type confusion vulnerability (CWE-843) in Mongoose, the MongoDB object modeling library for Node.js. When resolving discriminator models or schemas via user-supplied discriminator keys (defaulting to `__t`), Mongoose performs direct property indexing on plain JavaScript registry objects without verifying own-property ownership. Supplying inherited `Object.prototype` property names such as `'constructor'` causes Mongoose to resolve built-in functions rather than valid Mongoose constructors, resulting in unhandled runtime exceptions, schema validation bypasses, and persistent collection query denial of service.

Alon Barad
Alon Barad
3 views•11 min read
•about 3 hours ago•CVE-2026-125119
7.5

CVE-2026-125119: Connection-Level Filter Sanitization Bypass in Mongoose ODM

A flaw in Mongoose's query condition casting pipeline causes the `sanitizeFilter` configuration option to be silently ignored when defined at the connection level via `mongoose.connect()` or `mongoose.createConnection()`. Because internal query methods inspect `Connection.options` rather than `Connection.config`, applications relying on connection-scoped filter sanitization remain vulnerable to NoSQL query selector injection (CWE-943), permitting authentication bypass and unauthorized data access across Mongoose versions 6.x through 9.x.

Amit Schendel
Amit Schendel
3 views•9 min read
•about 4 hours ago•CVE-2026-125110
5.3

CVE-2026-125110: Path Canonicalization Mismatch and Security Header Bypass in Rack::Static

CVE-2026-125110 is a path canonicalization mismatch vulnerability in Rack (specifically within the Rack::Static middleware component). When serving static files, Rack normalizes the requested URL path to resolve the physical file on disk, but evaluates configured path-specific header rules against an unnormalized, raw path that has only undergone URL percent-decoding. Unauthenticated remote attackers can exploit this discrepancy by injecting raw or percent-encoded dot-segments into HTTP requests, causing Rack to serve restricted static assets without their intended security headers.

Amit Schendel
Amit Schendel
6 views•10 min read
•about 5 hours ago•CVE-2026-118776
3.7

CVE-2026-118776: Improper PKCS#7 Padding Validation in node-forge CBC and ECB Cipher Modes

CVE-2026-118776 (also tracked as GHSA-2vgq-wchc-25w7) is an improper input and integrity check validation vulnerability affecting the node-forge cryptographic library prior to version 1.4.1. In vulnerable versions, the PKCS#7 unpadding implementations for Cipher Block Chaining (CBC) and Electronic Codebook (ECB) modes only examined the final byte of the decrypted buffer and permitted padding counts up to four times the cipher block size. This defect allowed malformed ciphertexts containing zero-length padding, oversized padding values, or mismatched preceding padding bytes to pass validation, resulting in silent plaintext truncation of up to four blocks and integrity verification bypass in applications relying on unpadding success.

Amit Schendel
Amit Schendel
2 views•10 min read