Skip to content

fix(auth): preserve state on authorization error redirects - #2774

Open
Ssavan99 wants to merge 4 commits into
modelcontextprotocol:mainfrom
Ssavan99:fix/authorize-state-on-error-redirect
Open

fix(auth): preserve state on authorization error redirects#2774
Ssavan99 wants to merge 4 commits into
modelcontextprotocol:mainfrom
Ssavan99:fix/authorize-state-on-error-redirect

Conversation

@Ssavan99

@Ssavan99 Ssavan99 commented Sep 9, 2026

Copy link
Copy Markdown

Fixes #2773

authorizationHandler read state out of the parse result after the parse had
already been checked, so any Phase-2 validation failure threw before state was
assigned and the error redirect went out without it. RFC 6749 §4.1.2.1 requires
state on the error response whenever the request carried one, and a client
doing the standard CSRF check has to reject a callback that lacks it — so the
underlying invalid_request never reaches the user.

Capture state from the raw request parameters before validation runs.

Tests

Four cases added to authorize.test.ts:

  • missing code_challenge → error redirect keeps state
  • code_challenge_method=plain → error redirect keeps state
  • same via POST
  • request without state → error redirect still omits it (no regression)

The first three fail on main and pass with the fix. Full server-legacy suite:
172 passed. typecheck, eslint, and prettier clean.

Disclosure: found and patched with AI assistance (Claude Code). I have reviewed
the diagnosis, the fix, and the tests, and can speak to any of it.

authorizationHandler read `state` out of the parse result after the parse
had already been checked, so any Phase-2 validation failure threw before
`state` was assigned and the error redirect went out without it.

RFC 6749 4.1.2.1 requires `state` on the error response whenever the
request carried one. A client performing the standard CSRF check has to
reject a callback that lacks it, so the underlying `invalid_request`
never reaches the user.

Capture `state` from the raw request parameters before validation runs.
@Ssavan99
Ssavan99 requested a review from a team as a code owner September 9, 2026 17:31
@changeset-bot

changeset-bot Bot commented Sep 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fe54b46

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@modelcontextprotocol/server-legacy Patch
@modelcontextprotocol/client Patch
@modelcontextprotocol/codemod Patch
@modelcontextprotocol/core Patch
@modelcontextprotocol/server Patch
@modelcontextprotocol/core-internal Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Sep 9, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@2774

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/@modelcontextprotocol/codemod@2774

@modelcontextprotocol/core

npm i https://pkg.pr.new/@modelcontextprotocol/core@2774

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@2774

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/@modelcontextprotocol/server-legacy@2774

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@2774

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@2774

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@2774

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@2774

commit: fe54b46

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.

authorizationHandler drops the OAuth state parameter on error redirects

1 participant