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
- 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'.
- Cross-Origin Trigger: While the authentication flow is in flight, the victim visits an attacker-controlled web page.
- 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'})).
- 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.
- 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.
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 theerrorquery parameter before performing CSRFstateparameter 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.tsandsrc/services/mcp/xaaIdpCallback.tsto validatestatebefore processing errors, the xAI OAuth loopback callback handler was omitted during remediation.When an unauthenticated request containing
?error=...is received onhttp://127.0.0.1:56121/callback,xaiOAuthCallback.tsmarks the flow as settled and rejectswaitForCallback()without verifying whether a validstateparameter 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-originGETrequest (e.g., via<img src="...">orfetch(..., {mode: 'no-cors'})) to immediately abort the victim's authentication attempt.Proof of Concept
An attacker web page triggers a cross-origin request:
Detailed Attack Sequence
DEFAULT_XAI_OAUTH_CALLBACK_PORT = 56121andXAI_OAUTH_CALLBACK_PATH = '/callback'.http://127.0.0.1:56121/callback?error=access_denied(e.g. via<img src="...">, top-level navigation, orfetch(..., {mode: 'no-cors'})).url.searchParams.get('error')first. Finding the parameter populated, it executesrejectCallback(...)and setssettled = true, terminating the pending authentication promise without checkingstate.http://127.0.0.1:56121/callback?code=<legitimate_code>&state=<valid_state>, the loopback server ignores the code becausesettledis alreadytrue. 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
statequery parameter against the expected OAuth state token before processingerrororcodeparameters, bringingsrc/services/api/xaiOAuthCallback.tsinto fix parity withsrc/services/mcp/auth.ts.