auth: issuer mix-up mitigation (#859)
This PR functions as a Reference implementation of [SEP-2468](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2468) / [RFC9207](https://datatracker.ietf.org/doc/rfc9207/). This PR hardens the MCP OAuth Client functionality against Mix-Up attacks: > Mix-up attacks aim to steal an authorization code or access token by > tricking the client into sending the authorization code or access > token to the attacker instead of the honest authorization or resource > server This PR hardens the client by adding support for a new `iss` parameter in authorization responses: - Authorization Servers broadcast support for the `iss` parameter via the `authorization_response_iss_parameter_supported` metadata parameter - If the parameter is supported, clients expect to receive the `iss` parameter in the authorization response - Clients compare the `iss` parameter in the authorization response to the `Issuer` parameter in the authorization metadata. The two must match exactly for the response to be processed. Fixes #941
This commit is contained in:
parent
4cbdd6a514
commit
2d47cc9664
1 changed files with 151 additions and 9 deletions
|
|
@ -15,6 +15,7 @@ import (
|
|||
"maps"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
|
|
@ -178,6 +179,8 @@ func (s *FakeAuthorizationServer) handleMetadata(w http.ResponseWriter, r *http.
|
|||
CodeChallengeMethodsSupported: []string{"S256"},
|
||||
ClientIDMetadataDocumentSupported: cimdSupported,
|
||||
TokenEndpointAuthMethodsSupported: []string{"client_secret_post", "client_secret_basic"},
|
||||
// Advertise RFC 9207 support: the authorize endpoint includes "iss" in responses.
|
||||
AuthorizationResponseIssParameterSupported: true,
|
||||
}
|
||||
// Set CORS headers for cross-origin client discovery.
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
|
|
@ -267,8 +270,9 @@ func (s *FakeAuthorizationServer) handleAuthorize(w http.ResponseWriter, r *http
|
|||
}
|
||||
|
||||
state := r.URL.Query().Get("state")
|
||||
issuer := s.URL() + s.config.IssuerPath
|
||||
|
||||
redirectURL := fmt.Sprintf("%s?code=%s&state=%s", redirectURI, code, state)
|
||||
redirectURL := fmt.Sprintf("%s?code=%s&state=%s&iss=%s", redirectURI, code, state, url.QueryEscape(issuer))
|
||||
http.Redirect(w, r, redirectURL, http.StatusFound)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue