fix: use resource URL (not authorization server) as OAuth base_url; forward RFC 9207 iss - #13
Open
tprunk wants to merge 1 commit into
Open
fix: use resource URL (not authorization server) as OAuth base_url; forward RFC 9207 iss#13tprunk wants to merge 1 commit into
tprunk wants to merge 1 commit into
Conversation
…orward RFC 9207 iss new_oauth_state passed discovery.authorization_server as rmcp's base_url, but rmcp treats base_url as the resource server URL for both SEP-985 PRM validation and the RFC 8707 resource parameter. Servers whose resource and authorization server share an origin (e.g. mcp.cloudflare.com) then fail with "Protected resource metadata resource mismatch" before a browser is even opened. Separately, CallbackServer dropped the RFC 9207 iss query parameter and run_interactive_flow called rmcp's issuer-blind handle_callback. Any authorization server that requires iss back at token-exchange time (Cloudflare's does) then fails with "response missing required issuer". Adds regression tests for both: a Cloudflare-shaped mock PRM server for the base_url bug, and a callback-server test asserting iss is captured.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related OAuth bugs that together break authentication against any
server whose resource and authorization server share an origin and that
implements RFC 9207 (e.g.
mcp.cloudflare.com):new_oauth_statepasseddiscovery.authorization_server(the issuerURL) as rmcp's
base_url. rmcp'sAuthorizationManagertreatsbase_urlas the resource server URL — it re-fetches and validatesProtected Resource Metadata against it (SEP-985) and uses it as the
RFC 8707
resourceparameter on authorize/token/refresh requests.Passing the issuer URL instead makes rmcp's own PRM re-fetch mismatch
against the
resourcefield the server correctly advertises, e.g.:It also meant the
resourceparameter sent in actual OAuth requestspointed at the authorization server instead of the resource server —
wrong per RFC 8707 independent of the mismatch bug.
Separately,
CallbackServerdropped the RFC 9207issqueryparameter, and
run_interactive_flowcalled rmcp's issuer-blindhandle_callbackinstead ofhandle_callback_with_issuer. Anyauthorization server that advertises
authorization_response_iss_parameter_supported: trueand sendsisson redirect (Cloudflare does) then fails token exchange with:Changes
src/auth/mod.rs: passdiscovery.resourceinstead ofdiscovery.authorization_servertoOAuthState::new; forwardcode.issviahandle_callback_with_issuer.src/auth/callback.rs: captureissfrom the callback query stringand carry it on
AuthCode.src/auth/discovery.rs: update doc comments onOAuthDiscoverytomatch the corrected field usage;
resourceis no longer dead code.mock_discovery'sresourcefield now points at the mockserver instead of a fake
example.comURL, sinceset_credentials/refresh now actually dereference it; added two regression tests (see
below).
Test plan
cargo test— 122 passed, 0 failed (no regression)cargo test— 2 passed, 0 failed (new regression tests, one perbug:
start_authorization_succeeds_when_resource_and_authorization_server_share_originreproduces Cloudflare's PRM shape and fails with the original
resource-mismatch error when the
base_urlfix is reverted;callback_with_iss_param_is_capturedasserts the RFC 9207issparam survives the local callback round-trip instead of being
silently dropped)
https://mcp.cloudflare.com/mcp:full OAuth flow (browser consent, PKCE,
iss-validated codeexchange) completes and a subsequent
initializerequest returnsa valid MCP response, where main previously failed at the PRM
validation step before a browser was even opened.