Hi Will,
Sorry for the late reply over the holidays, and thanks for your insightful comments!
My responses are below.
CIMD.
> I wanted to understand your opinion around CIMD better.
> Given the context of your larger comment (preference for redirect_uri
mitigation) ...
Yes, my larger comment is that distinct redirect_uri mitigation can be useful, but I’m supportive of making iss mandatory in ecosystems that involve CIMD (including MCP).
>> the hosted CIMD document is typically static and includes a fixed redirect_uris array
> are you suggesting that the CIMD response should include iss-specific redirect_uris?
No. What I mean is that since the CIMD response is usually static (it should not/cannot return iss-specific redirect_uri), we should instead rely on the RFC9207 defense.
> I interpret "making iss mandatory" in the context of CIMD to mean making iss a mandatory input parameter (issuer is not an output parameter in CIMD).
> can you clarify what you mean by making
iss mandatory in CIMD?
To clarify: When an AS is working with a client that adopts CIMD, the AS shall return an iss parameter in the authorization response (per RFC9207), and the Client shall validate the iss per RFC9207. The CIMD request (input) & response (output) themselves do not take or return an iss parameter.
The Larger Topic.
> I largely agree with your analysis that redirect_uris are more suitable today, because of low adoption on RFC9207. However, this low adoption is what I hope to change by making issuer mandatory
on authorization servers in OAuth 2.1.
I understand your perspective. My thinking is that there are multiple reasons RFC9207 is not widely adopted. Maybe the fact that it is not a MUST in RFCs is only part of the story. More importantly, as we were discussing, the spec does not define clear interoperability when RFC8414 (OAuth AS Metadata) is not used.
> I worry about recommending issuer-specific redirect_uris because this implementation burden is imposed on the least sophisticated participants in the OAuth ecosystem.
> there are many more clients than … OAuth providers
> provider ... are often OAuth experts, but ... client developers much more often OAuth non-experts
I agree this was the case and likely still is the case in the majority of ecosystems today: A non-OAuth-expert developer picks a few well-known OAuth providers (experts), and builds a client that talks to them.
However, for mix-up attack cases that are most practical (i.e., open ecosystems where there is a legit use case/high chance to add a malicious AS), we are talking about a smaller world. MCP is one example, and the "OAuth client aggregator implementations” (in Max’s words, which we also studied in our research) are another.
In these ecosystems, there’s a paradigm shift: there can be more ASs/OAuth providers than clients. For example, Microsoft Power Platform has 1000+ pre-built connectors (mostly OAuth providers themselves) and unlimited custom ones, which could be operated by any SaaS app or data source (potentially non-OAuth-experts).
Looking at them requires a different mindset: the client (being the minority, OAuth-expert like Zapier, Microsoft Power Platform, Amazon Bedrock AgentCore) should have a way to protect every single AS. Distinct redirect_uri defense requires no special opt-ins, which fits the purpose.
AS Pre-configuration.
This is an interesting point, thanks for bringing it up!
> With regard to pre-configuration specifically. I think of there being three configuration paths:
> 1. Metadata (RFC8414 or OpenID Connect) => RFC9207 just works.
> 2. Three-value (issuer, authorization server, token server) preconfiguration => RFC9207 just works. Maybe we can call this "OAuth 2.1 preconfiguration”
> 3. Two-value (authorization server, token server) preconfiguration => issues you describe. Maybe we can call this "OAuth 2.0-compatible preconfiguration"
For 2. Three-value preconfiguration, the problem is, without RFC8414:
if the issuer value is specified by the AS (together with authorization server and token server), there is no mechanism to verify whether the preconfigured issuer is authentic, rather than spoofed (in a malicious config).
If the issuer value is specified by the Client, then the AS would need to return a client-specific issuer value, which is undocumented and hard to manage.
For 3. Two-value preconfiguration:
> I think if I were working on an OAuth client aggregator implementation, I would handle the RFC9207 issuer response parameter with two-value preconfiguration by writing a more relaxed check - assert(response.issuer.origin == configuration.authorizationServer.origin)
- instead of the RFC9207-mandated assert(response.issuer = configuration.issuer).
- If configuration.authorizationServer.origin means the origin of the authorization endpoint, then an attacker could pair a benign authorization endpoint with a malicious token endpoint/server to (still) launch mix-up attack.
- If not, see below.
> While no standard explicitly declares such a restriction, in almost every OAuth implementation I've seen, the origin of all three preconfigured values (issuer, authorization
server, token server) strictly matches.
Unfortunately, there are some famous exceptions 😊
"issuer": "https://accounts.google.com",
"authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
"token_endpoint": "https://oauth2.googleapis.com/token",
"issuer": "https://account.samsung.com/iam",
"authorization_endpoint": "https://account.samsung.com/iam/oidc/authorize",
"token_endpoint": "https://api.account.samsung.com/auth/oidc/token”,
Also note that for "OAuth client aggregators", such strict rules would need to apply to all (thousands of) ASs.
> Checking the origin is also sufficient to mitigate the mix-up attack unless an origin hosts multiple OAuth providers on different paths (which, while possible, is something I've never seen in practice).
https://cognito-idp.<Region>.amazonaws.com/<your user pool ID>/.well-known/openid-configuration
(Whether it’s possible to launch mix-up here is a separate discussion, but multiple OAuth providers can exist on different paths)
To sum up:
I support making iss compulsory (i.e., mandating RFC9207) in CIMD use cases; however, the RFC8414 compatibility on AS side still needs to be taken into account (MCP may expect a smoother transition because RFC8414 is already mandatory, MCP iterates fast, and can negotiate supported versions easily).
In scenarios where mix-up attacks are most practical (especially “OAuth client aggregators” with custom, openly-added OAuth providers), distinct redirect_uri defense may still be useful to protect existing-OAuth 2.0-compliant AS with minimum transition efforts. Also note that in these ecosystems, counterintuitively, there could be fewer Clients than ASs, with clients operated by well-known vendors.
Lack of RFC8414 support is a major barrier to making RFC9207 mandatory. Certain plausible workarounds may have their own issues.
Happy New Year,
Kaixuan
Hi Kaixuan,
Thank you for your mail and research links.
I wanted to understand your opinion around CIMD better. You wrote both:
> the hosted CIMD document is typically static and includes a fixed redirect_uris array"
And
> "certain OAuth use cases/profiles can definitely make iss mandatory, such as FAPI (already), CIMD [...]."
These seem somewhat contradictory. I interpret "making iss mandatory" in the context of CIMD to mean making iss a mandatory input parameter (issuer is not an output parameter in CIMD). Given the context of your larger comment (preference for redirect_uri
mitigation), are you suggesting that the CIMD response should include iss-specific redirect_uris? Thus, your suggestion is for CIMD documents to stop being static and instead be dynamic? Or, if I have misunderstood, can you clarify what you mean by making
iss mandatory in CIMD?
Taking a step back and addressing the larger topic.
I largely agree with your analysis that redirect_uris are more suitable today, because of low adoption on RFC9207. However, this low adoption is what I hope to change by making issuer mandatory
on authorization servers in OAuth 2.1.
I worry about recommending issuer-specific redirect_uris because this implementation burden is imposed on the least sophisticated participants in the OAuth ecosystem. The OAuth ecosystem consists
of - OAuth provider, OAuth libraries, OAuth protected resources, OAuth clients, and the developers of each of the aforementioned components. This list is already sorted by increasing quantity (there are many more clients than resources, and many more resources
than libraries or providers) and decreasing sophistication (provider and library developers are often OAuth experts, but resource and client developers much more often OAuth non-experts and experts in another (non-authentication) domain). RFC9207 puts the
burden on experts - OAuth provider and library developers - while using issuer-specific redirect_uris puts the burden on non-experts - OAuth client developers. OAuth client developers typically provide their redirect_uri as input to OAuth providers.
With regard to pre-configuration specifically. I think of there being three configuration paths:
Metadata (RFC8414 or OpenID Connect) => RFC9207 just works.
Three-value (issuer, authorization server, token server) preconfiguration => RFC9207 just works. Maybe we can call this "OAuth 2.1 preconfiguration"
Two-value (authorization server, token server) preconfiguration => issues you describe. Maybe we can call this "OAuth 2.0-compatible preconfiguration"
I think if I were working on an OAuth client aggregator implementation, I would handle the RFC9207 issuer response parameter with two-value preconfiguration by writing a more relaxed check - assert(response.issuer.origin == configuration.authorizationServer.origin)
- instead of the RFC9207-mandated assert(response.issuer = configuration.issuer). While no standard explicitly declares such a restriction, in almost every OAuth implementation I've seen, the origin of all three preconfigured values (issuer, authorization
server, token server) strictly matches. Checking the origin is also sufficient to mitigate the mix-up attack unless an origin hosts multiple OAuth providers on different paths (which, while possible, is something I've never seen in practice).
To sum up:
I agree that issuer-specific redirect_uri is a better mitigation today, largely because servers don't support RFC9207.
I think RFC9207 is a better north star, because it imposes burdens on a small number of experts instead of a larger number of non-experts.
I'm less convinced that clients will struggle with RFC9207 and two-value pre-configuration - I see a workable heuristic that mitigates the attack sufficiently for such older configurations.
Perhaps it makes sense to explicitly recommend this heuristic in some sort of standard.
Thanks,
Will
Hi all,
I’d like to put in my two cents, drawing on our research into practical mix-up attacks in the wild [1]-[3].
For MCP, I’m supportive of making RFC9207 (iss parameter in auth response) mandatory. Since the MCP spec mandates RFC8414 AS Metadata in the first place, it provides a trusted, verifiable source for the issuer value. Also, as Will pointed
out on MCP Github issue, with CIMD (Client ID Metadata Document) now adopted by MCP as a DCR alternative, it would be hard to apply the distinct redirect_uri defense, as the hosted CIMD document is typically static and includes a fixed
redirect_uris array.
I have only one minor concern:
> RFC9207 Section 4:
Clients ... MUST NOT allow multiple authorization servers to use the same issuer identifier.
In particular, when authorization server details can be manually configured in the client, the client
MUST ensure that the accepted
iss values are unique for each authorization server.
There are legit use cases where two benign MCP servers with the same AS/IdP connect to one MCP client (e.g., two MCP servers using Google IdP, or an official vs. custom Dropbox MCP Server). Technically, such two
MCP servers should (still) be considered as using one AS (but two AS instances), therefore not violating the normative text above. However, I fear that some MCP clients may interpret the text differently, blocking a second MCP server simply because the issuer
matches an existing one. This may require a special call-out in the MCP spec for clarification.
For a future-proof OAuth 2.1, I’m hesitant about whether we should mandate
iss in the broader OAuth world outside MCP.
The iss defense works best when paired with RFC8414 OAuth AS Metadata, but AS Metadata is not REQUIRED by OAuth 2.1. Without it, it’d be hard to know what to return as
iss value (for an AS) and/or hard to verify the authenticity of
iss value (for the OAuth Client). It is documented that,
> RFC9207 Section 2.4: If OAuth metadata is not used, clients
MUST use deployment-specific ways (for example, a static configuration) to decide if the returned
iss value is the expected value in the current flow …
> RFC9207 Section 4:
When OAuth metadata is not used, the client can use, for example, a statically configured expected
iss value for each configured authorization server.
This means without RFC8414, the exact value of iss which an AS returned in authorization response, as well as its validation, hinges on its actual configuration/coordination with a particular client. This raises implementation costs, complicates
conformance testing, and may also open room for issuer spoofing. Conversely, when RFC8414 is used, the expected value and authenticity of
iss is anchored in the HTTPS-hosted metadata, where its "issuer" claim equates the server origin.
For protecting existing OAuth 2.0-compliant ecosystems, my take is enforcing
iss is less practical.
OAuth 2.0 will be around for a long time. If we wish to fix mix-up at early stage across all OAuth ecosystems, it should be noted that RFC9207 needs explicit opt-in, whereas distinct redirect_uri defense allows ASs and
Clients only compliant with RFC6749 to be easily secured, as the latter defense does not involve protocol-level changes.
Outside MCP and a few niche ecosystems such as FAPI, RFC8414 OAuth AS Metadata adoption remains limited. This contrasts with the widespread deployment of OIDC openid-configuration by major IdPs. Likewise, today we also see limited support of RFC9207 across
industry, both on AS and OAuth Client side.
Max mentioned "OAuth client aggregator implementations", including no-code/integration platforms and Token Vaults in Agentic AI. We have been investigating these ecosystems [1]-[2], and felt like the
iss parameter defense (RFC9207) would often be less practical than distinct redirect_uri:
In these implementations, with each OAuth client supporting hundreds or thousands of pre-built and custom integrations, we may expect a long tail and cannot expect that the
ASs would just supply the iss parameter. Each AS is protected individually only if they opt-in, and those who don’t remain unprotected.
On the other hand, distinct redirect_uri is more practical:
Overall, I think the cost of updating client registration is lower than adopting RFC9207 at scale. I understand AS adding a new parameter in authorization response itself is simple, but it is more than that:
If the iss is sourced from RFC8414, then both Client and ASs need to support RFC8414 for interoperability; Currently, most, if not all of these platforms/vaults rely on manually configured AS information in a
platform-specific configuration, rather than conveyed through AS metadata (unlike MCP).
If the iss does not rely on RFC8414, then the platform/vault’s OAuth client should generate an
iss value for each AS, and the AS shall return that client-specific
iss, rather than a constant, universal value, which takes additional efforts.
So my take is that regardless of whether we call it a secure-OAuth-2.0 or OAuth 2.1, if our goal is to protect existing OAuth implementations, especially for ALL OAuth2.0-compliant ASs, then I think distinct redirect_uri still has its value.
And certain OAuth use cases/profiles can definitely make iss mandatory, such as FAPI (already), CIMD, MCP, etc.
References:
Some of our work on mix-up attack analysis (referred to as Cross-app OAuth Account Takeover, COAT in our context)
[1] Low-code/No-code Integration Platforms:
BlackHat USA 2024,
OAuth Security Workshop 2025,
USENIX Security 2025.
[2] Token Vaults in Agentic AI:
BlackHat USA 2025 (Cross-agent COAT).
[3]
IETF Interim Meeting,
IETF Draft.
Thanks,
Kaixuan Luo
PhD Candidate
The Chinese University of Hong Kong (CUHK)
The lack of issuer being required just points to the exact security flaw when it isn't being required. I don't think anyone needs to be reminded of that. The point to suggest that issuer
be required in OAuth2.1 is something I am also in favor of.
Will -
The `iss` response parameter approach is also far easier to deploy than the multiple redirect URL mitigation approach. Deployment can be done in a forward-compatible way without manual coordination between existing OAuth
ASs and OAuth clients.
For a non-MCP flavored example - there are many OAuth client "aggregator" implementations today. These are services that manage access and refresh tokens for a wide number of external APIs. Think of companies like Zapier in the no-code space, Nango in the product
integration space, or various Token Vault services in the AI space. These aggregators often manage many client identities to facilitate integrations with multiple separate OAuth ASs.
If we require these aggregators to move to a separate redirect URL per AS instead, every pre-existing client registration containing the old redirect URL will need to be updated. These updates must be performed manually
by the aggregator's customers. An aggregator cannot tell an AS that "cust_client_1234" is now using a new redirect URL - only the owner of "cust_client_1234" (the aggregator's customer) can do that.
In comparison, a rollout of the `iss` response parameter does not require the client registration to be updated. As soon as an AS starts to support the `iss` response, all clients of that AS can begin enforcement. All (Zapier <-> Google) interactions can be
secured at once.
I am supportive of making this response parameter mandatory in 2.1.
Best,
Max
Hi folks,
Summary: OAuth 2.1 incorporates RFC 9207's issuer response parameter optionally. I believe OAuth 2.1 should make this parameter mandatory.
Rationale:
MCP needs this to mitigate the mix-up attack.
Enabling clients to mitigate the mix-up attack requires a very small amount of work from servers - returning a constant response value (iss).
We (OAuth WG) should strive for a simpler world for non-auth experts where non-auth specifications (like MCP) can just reference OAuth 2.1 and be secure. It should not be necessary for non-auth experts
to reference OAuth 2.1 and also read many OAuth 2 extensions and evaluate which of those extensions are needed for security.
The status quo (optional) makes implementing OAuth 2.1 slightly easier for OAuth providers, at the cost of requiring more complex security analysis from specifications that reference OAuth 2.1 (like MCP) and clients that implement OAuth 2.1 (like MCP clients).
Given that the implementation burden on OAuth providers is very small, I believe that mandating this response parameter is the right tradeoff. There will undoubtably be a small flurry of activity when OAuth 2.1 is finalized where implementations advertise
their compliance. We should take advantage of that opportunity to mitigate the mix-up attack once and for all.
Thanks,
Will Bartlett
_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]