Skip to main content

Security Advisory: OAuth Open Redirect and Account Takeover in the Nexudus MCP Server


Summary

The OAuth authorization server that protects the Nexudus MCP server (mcp.nexudus.com, used to connect AI assistants such as Claude, ChatGPT and GitHub Copilot to a Nexudus account) did not validate the redirect_uri of an authorization request against any registered client. Anyone could register a client through the open Dynamic Client Registration endpoint with an arbitrary callback, or skip registration altogether, and craft a genuine-looking mcp.nexudus.com sign-in link. A Nexudus administrator who signed in through that link had their authorization code sent to the attacker’s server. The code could then be exchanged for, or used directly as, an access token, and it also contained the administrator’s Nexudus API token in readable form. The sign-in page showed only “Sign in to Nexudus” with email and password fields. It did not show which application was requesting access or where the result would be sent.

Vulnerability Details

Background

MCP clients connect to mcp.nexudus.com with OAuth 2.1. The client sends the user to /auth/authorize, the user signs in with their Nexudus credentials, and the server redirects back to the client’s redirect_uri with an authorization code. The client exchanges the code at /auth/token for an access token used on the MCP endpoint.

Root Cause

Several controls that the OAuth and MCP specifications require were missing or advertised but not enforced:
  1. Redirect URI not validated. /auth/authorize read only redirect_uri and state. client_id and response_type were ignored, and after a successful sign-in the code was redirected to whatever redirect_uri the request contained.
  2. Client registration had no effect. POST /auth/register accepted any metadata without authentication, returned a random client_id and stored nothing. The client_id was never checked by any later endpoint, so registration neither constrained nor identified the client.
  3. PKCE advertised but not enforced. Server metadata advertised S256 PKCE, but /auth/token did not verify a code_verifier, so a stolen code could be redeemed by anyone.
  4. Upstream token readable by the client. Authorization codes and access tokens were signed but not encrypted. Their payload was base64-encoded JSON that included the user’s Nexudus API token.
  5. Authorization codes accepted as access tokens. Codes and access tokens had the same format, so the MCP endpoint accepted an authorization code as a bearer token for the code’s 5-minute lifetime, without going through /auth/token.
  6. No consent screen. Credentials were collected before any validation, and the page did not name the requesting application or the redirect destination.

Affected Endpoints

1. Authorization — Open Redirect of Authorization Codes

  • Endpoint: GET /auth/authorize, POST /auth/authorize
  • Severity: Critical
  • Impact: An attacker can send a Nexudus administrator a link to the genuine mcp.nexudus.com sign-in page whose redirect_uri points to an attacker-controlled server. After the administrator signs in, the authorization code is delivered to the attacker.

2. Client Registration — Unauthenticated, Unconstrained Registration

  • Endpoint: POST /auth/register
  • Severity: High (enabler of #1)
  • Impact: Any anonymous caller can register a client with arbitrary callback URLs, making a malicious request look like a normal MCP client registration.

3. Token Exchange — PKCE Not Enforced

  • Endpoint: POST /auth/token
  • Severity: High
  • Impact: A captured authorization code can be exchanged for an access token without the PKCE code verifier held by the legitimate client.

4. Codes and Tokens — Upstream Credential Exposure and Type Confusion

  • Endpoint: POST / (MCP endpoint), and all issued codes and tokens
  • Severity: Critical
  • Impact: Decoding a captured code or access token revealed the administrator’s Nexudus API token, which gives direct access to the Nexudus API outside the MCP server’s controls (including PII redaction and token revocation). An authorization code could also be used directly as an MCP access token.

Exploitation Prerequisites

  • Authentication Required: No — the attacker needs no Nexudus account.
  • User Interaction: Yes — the victim must open the attacker’s link and sign in with their Nexudus credentials on the genuine mcp.nexudus.com page.
  • Victim Privileges: Only unrestricted Nexudus administrators can complete sign-in to the MCP server. This narrows the set of users who can be targeted, but those accounts have full administrative access to the operator’s data.

Impact Assessment


Remediation

The OAuth protocol endpoints were rebuilt on the authorization handlers shipped with the official MCP TypeScript SDK, behind a Nexudus-specific provider. The fix includes:
  • Redirect URIs validated before anything is rendered. /auth/authorize requires client_id, resolves the client and checks redirect_uri exactly against the client’s registered callbacks (loopback ports relaxed per RFC 8252). An unknown client or callback receives a direct 400 response and is never redirected.
  • Reviewed destination policy. Every non-loopback callback, however the client was registered, must also be on a reviewed list of AI assistant callbacks (Claude, ChatGPT, VS Code, Microsoft Copilot Studio and Microsoft 365 Copilot). Custom URI schemes, fragments, embedded credentials and non-loopback http are rejected. A registration with any other callback is refused.
  • Client identification. Clients are identified by a Client ID Metadata Document hosted on a trusted vendor domain (Claude, ChatGPT), by a constrained Dynamic Client Registration whose client_id is a sealed record of the validated metadata (VS Code, MCP Inspector), or by pre-registration. Client IDs issued before the fix are rejected, and the user is asked to reconnect.
  • Consent page. Before any credentials are entered, the page shows who is requesting access (the verified vendor host, or the self-declared name marked as unverified), the exact redirect destination with a warning for local apps, what access is being granted, and separate Approve and Deny buttons. The page is served with a strict Content Security Policy and cannot be framed.
  • PKCE S256 enforced at both the authorization and token endpoints. A code whose verifier, callback, client or resource does not match is rejected and is not consumed.
  • Encrypted, typed codes and tokens. Codes and access tokens are AES-256-GCM encrypted under a new key, so the Nexudus API token is no longer readable by the client. Each token is bound to its type, and the MCP endpoint accepts only access tokens issued for it.
  • Additional hardening. RFC 9207 iss on authorization responses, RFC 8707 resource binding, rate limits on registration, authorization, token and sign-in endpoints, security event logging that excludes secrets, and an emergency switch to disable authorization.
Regarding the reporter’s recommendation to require authentication on POST /auth/register: open registration is permitted by RFC 7591 and is still required by some MCP clients (for example GitHub Copilot in VS Code), so the endpoint remains available. It can no longer register an arbitrary destination, and registration no longer confers any trust. As a consequence of the fix, all users had to sign in again, and connections created through the old registration flow had to be removed and re-added once. Nexudus API tokens issued to the MCP integration before the fix were not revoked individually. They have a fixed lifetime of 14 days, so the last of them expired on 2026-10-10. This advisory was published after that date so that it does not point to credentials that could still be used.

Exploitation Assessment

Following remediation, server logs and Nexudus API logs were reviewed for authorization requests with callbacks outside the known set of AI assistant clients, token use from unexpected addresses, and unusual administrative operations. Result: No evidence of exploitation was found.

Timeline


Credit

Reported by an independent security researcher through responsible disclosure. Additional issues (PKCE enforcement, token confidentiality and code/token type confusion) were identified by the Nexudus team during the assessment of the report.