Skip to content

fix(xai): validate OAuth state before settling callbacks - #2228

Merged
kevincodex1 merged 1 commit into
Gitlawb:mainfrom
fancive:fix/xai-oauth-callback-state-2101
Sep 15, 2026
Merged

kevincodex1 merged 1 commit into
Gitlawb:mainfrom
fancive:fix/xai-oauth-callback-state-2101

Conversation

@fancive

@fancive fancive commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixes xAI OAuth Loopback Server Leads to Denial of Service (DoS) #2101. Validate the expected OAuth state in the xAI loopback handler before processing either an error or an authorization code.
  • Missing, mismatched, or whitespace-altered state returns HTTP 400 without settling the pending login. Keep the service-level state check as defense in depth.
  • Reviewed AGENTS.md and CONTRIBUTING.md.

Impact

  • User-facing impact: an unsolicited callback can no longer consume an in-flight xAI login through its error, missing-parameter, or forged-code path.
  • Developer/maintainer impact: the callback server requires the flow's expected state; existing CORS, valid OAuth errors, manual recovery, and cancellation behavior are preserved. No new dependency or runtime change.

Testing

  • I ran the required local preflight, with the verified pre-existing failures below.
  • Passed: bun install --frozen-lockfile --network-concurrency 8, bun run typecheck, bun run typecheck:type-tests, node bin/openclaude --version, NODE_DISABLE_COMPILE_CACHE=1 node bin/openclaude --version, npm run test:provider-recommendation, and bun run security:pr-scan -- --base FETCH_HEAD --head HEAD after fetching canonical upstream main. Exact-scope lint and git diff --check passed.
  • Focused tests: bun test src/services/api/xaiOAuthCallback.test.ts src/services/api/xaiOAuthShared.test.ts — 36 passed. Eight invalid-state regressions failed before the fix. Real loopback HTTP tests cover recovery by valid callback, manual code, and cancellation; discovery and token exchange are mocked.
  • bun run check built the CLI/SDK and passed smoke/deadcode, but printed 65 unique failing test names despite exiting 0 without a full-suite summary. The same command on untouched base e2b021d8bbda66b64cef7dbe1e089fea3eaa563f reproduced the identical 65 names (fact extraction, registry append, attribution, pricing, model limits, and fast mode). This is not a green full-suite result.
  • bun run test:provider: 1,657 passed, one failed: Claude stream watchdog > falls back when the top-level stream iterator never settles. Untouched base reproduced the same failure (1,646 passed, one failed). The change does not touch these failing paths; delivery follows the contribution guide's verified pre-existing failure exception.

Notes

  • Provider/model path tested: xAI authorization-code loopback and manual recovery, using local HTTP and mocked xAI endpoints; no live account login or model request.
  • Screenshots: not applicable; no UI change.
  • Limits: browser-specific cross-origin delivery and live xAI login were not exercised. Web checks are not applicable. CI still supplies clean-runner and supported-Node-matrix coverage.

Summary by CodeRabbit

  • Bug Fixes
    • OAuth callbacks now require a matching security state before login can continue.
    • Invalid or missing callback states are rejected without completing the sign-in flow.
    • OAuth errors and authorization codes are processed only after state validation succeeds.
    • Login remains recoverable after an invalid callback, allowing valid completion through callback, manual code entry, or cancellation.

@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 57686073-8328-4870-900b-fb039b9f4758

📥 Commits

Reviewing files that changed from the base of the PR and between e2b021d and 97ab641.

📒 Files selected for processing (3)
  • src/services/api/xaiOAuth.ts
  • src/services/api/xaiOAuthCallback.test.ts
  • src/services/api/xaiOAuthCallback.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (3)
Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny.

⚙️ CodeRabbit configuration file

Files:

  • src/services/api/xaiOAuth.ts
  • src/services/api/xaiOAuthCallback.test.ts
  • src/services/api/xaiOAuthCallback.ts
Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions.

⚙️ CodeRabbit configuration file

Files:

  • src/services/api/xaiOAuthCallback.test.ts
Apply the OpenClaude maintainer review rubric from AGENTS.md.

⚙️ CodeRabbit configuration file

Files:

  • src/services/api/xaiOAuth.ts
  • src/services/api/xaiOAuthCallback.test.ts
  • src/services/api/xaiOAuthCallback.ts
🔇 Additional comments (3)
src/services/api/xaiOAuthCallback.ts (1)

93-93: LGTM!

Also applies to: 157-166, 181-181

src/services/api/xaiOAuth.ts (1)

290-290: LGTM!

Also applies to: 314-314

src/services/api/xaiOAuthCallback.test.ts (1)

1-1: LGTM!

Also applies to: 6-6, 13-13, 240-240, 245-245, 250-364, 402-402


📝 Walkthrough

Walkthrough

The xAI OAuth loopback callback now validates the expected state before processing errors or codes. Invalid-state requests return HTTP 400 and leave the OAuth flow pending. Tests cover callback, manual-code, and cancel completion paths.

Changes

xAI OAuth state validation

Layer / File(s) Summary
Callback state contract and validation
src/services/api/xaiOAuthCallback.ts, src/services/api/xaiOAuth.ts
startXaiOAuthCallback requires expectedState. The callback rejects missing or mismatched state before handling errors or codes. XaiOAuthService passes the generated state.
Callback state validation tests
src/services/api/xaiOAuthCallback.test.ts
Tests require matching state values and cover invalid-state requests before callback, manual-code, and cancel completion. HTML-escaping coverage supplies the expected state.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~15 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 97ab6

The callback now validates OAuth state before handling errors or codes, preventing unsolicited callbacks from ending an active login flow. No remaining merge-blocking risk was identified.

🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise, scoped to xAI OAuth, and accurately describes the callback state-validation change.
Description check ✅ Passed The description includes all required sections and clearly explains the change, impact, testing results, pre-existing failures, and limitations.
Linked Issues check ✅ Passed Issue #2101 requires state validation before error or code handling. startXaiOAuthCallback now requires expectedState, rejects missing, mismatched, and whitespace-altered states with HTTP 400, and…
Out of Scope Changes check ✅ Passed The changes are limited to the xAI OAuth callback and service integration, plus focused automated tests and related callback documentation. These changes directly implement Issue #2101 and preserve th…
Risk Surface Disclosed ✅ Passed The PR touches the xAI OAuth authentication and loopback callback path. The review explicitly describes the risk surface: unsolicited callbacks could consume an in-flight login, and the fix validates …
No Hidden Policy Change ✅ Passed PASS. The PR changes only the xAI OAuth callback path and its tests. The trust-model change is explicit: startXaiOAuthCallback receives the flow's expectedState, rejects missing or mismatched stat…
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Sep 15, 2026

Copy link
Copy Markdown

Greptile Summary

This PR hardens the xAI OAuth loopback callback by validating the expected state before processing either an OAuth error or authorization code.

  • Passes the generated OAuth state into the callback server.
  • Rejects missing, altered, or mismatched state without settling the pending login.
  • Retains the service-level state check as defense in depth.
  • Adds focused coverage for valid errors, forged callbacks, subsequent recovery, manual completion, and cancellation.

Confidence Score: 5/5

The PR appears safe to merge; the callback validation is consistently wired into the production flow and preserves valid completion, recovery, and cancellation behavior.

No actionable failure remains: the expected state is generated once, round-trips through URL-safe encoding, is checked before callback settlement, and is independently checked again before token exchange.

Important Files Changed

Filename Overview
src/services/api/xaiOAuthCallback.ts Adds exact expected-state validation before any callback error or authorization code can settle the pending flow.
src/services/api/xaiOAuth.ts Supplies the same generated state to the callback server and authorization URL while retaining downstream validation.
src/services/api/xaiOAuthCallback.test.ts Adds focused regression coverage showing invalid-state requests cannot consume a login and that all supported completion paths remain functional.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Loopback callback received] --> B{Correct method and path?}
    B -- No --> C[Return 404 or 405]
    B -- Yes --> D{State exactly matches expected state?}
    D -- No --> E[Return 400; keep login pending]
    D -- Yes --> F{OAuth error present?}
    F -- Yes --> G[Return 400; reject pending callback]
    F -- No --> H{Authorization code present?}
    H -- No --> I[Return 400; reject pending callback]
    H -- Yes --> J[Return success; resolve callback]
    J --> K[Service validates state again]
    K --> L[Exchange authorization code]
Loading

Reviews (1): Last reviewed commit: "fix(xai): validate OAuth state before se..." | Re-trigger Greptile

@kevincodex1 kevincodex1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great! thanks

@kevincodex1
kevincodex1 merged commit d16318a into Gitlawb:main Sep 15, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants