Skip to content

xAI OAuth Loopback Server Leads to Denial of Service (DoS) #2101

Description

@nedlir

Related Disclosure: GHSA-c73c-x77g-854r / CVE-2026-42073 (Unpatched Sibling Variant)

Description

The xAI OAuth loopback callback server (src/services/api/xaiOAuthCallback.ts) evaluates the error query parameter before performing CSRF state parameter validation.

This vulnerability is an unpatched sibling variant of disclosed advisory GHSA-c73c-x77g-854r ("MCP OAuth Callback: State Check Bypass via error Param Leads to DoS"). While the fix for GHSA-c73c-x77g-854r reordered checks in src/services/mcp/auth.ts and src/services/mcp/xaaIdpCallback.ts to validate state before processing errors, the xAI OAuth loopback callback handler was omitted during remediation.

When an unauthenticated request containing ?error=... is received on http://127.0.0.1:56121/callback, xaiOAuthCallback.ts marks the flow as settled and rejects waitForCallback() without verifying whether a valid state parameter was supplied.

Because the callback server runs on a fixed port (56121), any malicious website visited by the user while an xAI OAuth login is in progress can issue a cross-origin GET request (e.g., via <img src="..."> or fetch(..., {mode: 'no-cors'})) to immediately abort the victim's authentication attempt.

Proof of Concept

An attacker web page triggers a cross-origin request:

<img src="http://127.0.0.1:56121/callback?error=access_denied">

Detailed Attack Sequence

  1. Loopback Server Initialization: Upon initiating xAI authentication, OpenClaude starts a temporary HTTP listener bound to fixed constants DEFAULT_XAI_OAUTH_CALLBACK_PORT = 56121 and XAI_OAUTH_CALLBACK_PATH = '/callback'.
  2. Cross-Origin Trigger: While the authentication flow is in flight, the victim visits an attacker-controlled web page.
  3. Unauthenticated GET Dispatch: The web page issues a cross-origin HTTP GET request targeting http://127.0.0.1:56121/callback?error=access_denied (e.g. via <img src="...">, top-level navigation, or fetch(..., {mode: 'no-cors'})).
  4. Premature Flow Settlement: The loopback HTTP handler inspects url.searchParams.get('error') first. Finding the parameter populated, it executes rejectCallback(...) and sets settled = true, terminating the pending authentication promise without checking state.
  5. Legitimate OAuth Failure & User Confusion: When xAI subsequently redirects the victim's browser back to http://127.0.0.1:56121/callback?code=<legitimate_code>&state=<valid_state>, the loopback server ignores the code because settled is already true. The victim's browser displays an HTTP 200 "success" page ("You can return to OpenClaude...") while the CLI/app login has actually failed.

Impact

Unauthenticated remote cross-origin Denial of Service against in-flight xAI OAuth login flows.

Remediation

Validate the state query parameter against the expected OAuth state token before processing error or code parameters, bringing src/services/api/xaiOAuthCallback.ts into fix parity with src/services/mcp/auth.ts.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions