By navigating to the redirect URL, the browser sends the URL (including query 
parameters, excluding fragment parameters) to the backend as a GET request.
This happens for web apps because that is how browsers work if a URL is called 
from a different host (the authorization server).
Fragment was originally meant to reference to a specific section on the website 
(see how referencing to sections work in Wikipedia). Therefore, the browser 
does not send the fragment part of the URL to the backend.

However, I think for mobile apps, if you can be sure that the URL is being 
opened within the app, and not in a web browser, query seems totally fine too.


> Am 07.11.2025 um 08:35 schrieb Warren Parad <[email protected]>:
> 
> Can you explain further under what circumstance the url would be sent to the 
> backend and why in that circumstance the fragment would not be sent?
> 
> 
> On Fri, Nov 7, 2025, 14:31 Primbs, Jonas <[email protected] 
> <mailto:[email protected]>> wrote:
>> Fragment parameters are not transferred to the backend. They remain in the 
>> user's browser.
>> This does not entirely solve the issue for web apps, but it reduces the 
>> attack surface because the attacker requires access to the user’s client, 
>> e.g., if they share the same workstation.
>> I think for mobile apps, fragment almost solves the issue, because there’s 
>> no URL bar to enable URL sharing, no referer header, probably no analytics, 
>> and near-real-time log access is also difficult due to the isolation of apps 
>> and the fact that mobile devices are rarely shared between users.
>> 
>> 
>> 
>>> Am 07.11.2025 um 07:50 schrieb Warren Parad <[email protected] 
>>> <mailto:[email protected]>>:
>>> 
>>> How is fragment any different from query?
>>> 
>>> On Fri, Nov 7, 2025, 13:45 Primbs, Jonas <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>>> Hi Warren,
>>>> 
>>>> 
>>>>> Am 07.11.2025 um 04:36 schrieb Warren Parad 
>>>>> <[email protected] <mailto:[email protected]>>:
>>>>> 
>>>>> If PKCE fixes a problem, then that's the solution to the problem, it 
>>>>> doesn't make sense to add a "standard alternative" because of that. 
>>>>> State, never existed for CSRF protection, that was the nonce, which has 
>>>>> been deprecated with the introduction of PKCE, so neither S1 or S3 are 
>>>>> relevant right?
>>>>> 
>>>> 
>>>> I also prefer always recommending PKCE, because it simplifies a lot, even 
>>>> in the rest of the draft.
>>>> You mean S2 or S3, right? Because S1 is the PKCE solution.
>>>> 
>>>>> I'm missing the value in a "revocation mechanism" for authorization 
>>>>> codes, if the attacker can block requests to the AS, then how would the 
>>>>> revocation mechanism end up getting called? What would trigger that?
>>>>> 
>>>> 
>>>> Tthat’s correct. If the authorization code revocation can be blocked by 
>>>> the attacker until the attacker requests the tokens, the protection is 
>>>> useless.
>>>> Then the only solution is not disclosing the authorization code, e.g., by 
>>>> using response_mode=fragment for client-side mobile/web apps, or 
>>>> response_mode=form_post for server-side apps.
>>>> If the client is running on the server side, I think it is unusual that 
>>>> the attacker can intercept or at least delay the authorization code 
>>>> revocation, because that would require the attacker to be between the 
>>>> client server and the authorization server.
>>>> 
>>>> 
>>>>> On Fri, Nov 7, 2025 at 10:08 AM Frederik Krogsdal Jacobsen 
>>>>> <[email protected] 
>>>>> <mailto:[email protected]>> wrote:
>>>>>> I think S1 is the best bet for a standard solution to mention in OAuth 
>>>>>> 2.1.
>>>>>> State could be deprecated as a solution for CSRF protection, but it is 
>>>>>> still useful for other things.
>>>>>> 
>>>>>> An AS could individually recommend variations on S2 if they do not plan 
>>>>>> to implement PKCE.
>>>>>> 
>>>>>> I still think that a more general cancellation/revocation mechanism as 
>>>>>> mentioned by Max would be useful (also for other grant types such as 
>>>>>> auth_req_ids from CIBA), but I understand that introducing this is 
>>>>>> probably off-topic for this thread.
>>>>>> 
>>>>>> Cheers,
>>>>>> Frederik
>>>>>> 
>>>>>> On Thu, 6 Nov 2025 at 17:43, Aaron Parecki 
>>>>>> <[email protected] 
>>>>>> <mailto:[email protected]>> wrote:
>>>>>>> I think that's covered as part of the discussion of how a client and AS 
>>>>>>> know that each other are speaking OAuth 2.1 vs 2.0. 
>>>>>>> 
>>>>>>> 
>>>>>>> On Thu, Nov 6, 2025 at 11:40 AM Neil Madden <[email protected] 
>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>> The only issue I have with deprecating state for CSRF protection is 
>>>>>>>> that the client has no way in general to know if the AS supports (in 
>>>>>>>> fact enforces) PKCE. If it doesn’t, then we may end up with no CSRF 
>>>>>>>> protection at all, and clients being vulnerable to Login CSRF/session 
>>>>>>>> fixation-like attacks. 
>>>>>>>> 
>>>>>>>> — Neil
>>>>>>>> 
>>>>>>>>> On 6 Nov 2025, at 16:12, Aaron Parecki <[email protected] 
>>>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>> 
>>>>>>>>> S1 seems like the cleanest solution to me. I think this should also 
>>>>>>>>> come with language officially deprecating "state" for CSRF protection 
>>>>>>>>> like Philippe said.
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> On Thu, Nov 6, 2025 at 10:59 AM Primbs, Jonas 
>>>>>>>>> <[email protected] 
>>>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>>>> Let’s collect auth code revocation solutions:
>>>>>>>>>> 
>>>>>>>>>> S1: Enforce PKCE + normal token request but without code_verifier.
>>>>>>>>>> + No additional endpoints
>>>>>>>>>> + Works for many existing implementations
>>>>>>>>>> - AS must implement PKCE and enforce it for all clients (bad for 
>>>>>>>>>> testing)
>>>>>>>>>> 
>>>>>>>>>> S2: Use specific client_id at the token endpoint.
>>>>>>>>>> + No additional endpoints
>>>>>>>>>> -  A bit hacky
>>>>>>>>>> 
>>>>>>>>>> S3: Specify a dedicated token endpoint
>>>>>>>>>> + One official way
>>>>>>>>>> - Huge changes required
>>>>>>>>>> 
>>>>>>>>>> S4: Use token revocation endpoint
>>>>>>>>>> + Just an extension of existing endpoints
>>>>>>>>>> - Client cannot know if the AS implements this
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>> Am 06.11.2025 um 08:24 schrieb Neil Madden <[email protected] 
>>>>>>>>>>> <mailto:[email protected]>>:
>>>>>>>>>>> 
>>>>>>>>>>> This makes me wonder if we could in fact have a special client_id 
>>>>>>>>>>> value that indicates that the AS should revoke the code (and any 
>>>>>>>>>>> tokens if issues)? It's a bit hacky but has the advantage of likely 
>>>>>>>>>>> doing the right thing for most ASes, as Tim mentions. Something 
>>>>>>>>>>> like client_id=csrf_detected_revoke_please.
>>>>>>>>>>> 
>>>>>>>>>>>> On 6 Nov 2025, at 13:04, Tim Würtele 
>>>>>>>>>>>> <[email protected] 
>>>>>>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>>>>>> 
>>>>>>>>>>>> Hi Jonas,
>>>>>>>>>>>> 
>>>>>>>>>>>> a minor (but imho relevant to this discussion) nitpicking inline.
>>>>>>>>>>>> 
>>>>>>>>>>>> Best,
>>>>>>>>>>>> 
>>>>>>>>>>>> Tim
>>>>>>>>>>>> 
>>>>>>>>>>>> On 05.11.25 16:25, Primbs, Jonas wrote:
>>>>>>>>>>>>> Hi Frederik,
>>>>>>>>>>>>> 
>>>>>>>>>>>>> yes, calling the token request validly, thereby invalidating the 
>>>>>>>>>>>>> authorization code for future usage by the attacker, and throwing 
>>>>>>>>>>>>> away the token response could also be a solution.
>>>>>>>>>>>>> However, I am not sure what the implications could be with 
>>>>>>>>>>>>> respect to how authorization servers handle this (e.g., starting 
>>>>>>>>>>>>> a session, which confuses users when they look at the list of 
>>>>>>>>>>>>> active sessions) or how clients handle this (e.g., logging tokens 
>>>>>>>>>>>>> in a potential crash dump).
>>>>>>>>>>>>> If authorization servers implement token revocation correctly, 
>>>>>>>>>>>>> when authorization codes are used twice, sending a second valid 
>>>>>>>>>>>>> token request with the same authorization code afterwards might 
>>>>>>>>>>>>> ensure that the issued tokens cannot be used anymore.
>>>>>>>>>>>>> 
>>>>>>>>>>>>> Again, this might fail if the client faces any issues. So I 
>>>>>>>>>>>>> prefer a standardized authorization code invalidation mechanism.
>>>>>>>>>>>>> One opportunity here, which is already standardized, is enforcing 
>>>>>>>>>>>>> PKCE and sending no code_verifier in the token request 
>>>>>>>>>>>>> intentionally.
>>>>>>>>>>>> The issue with that is the (historically grown) lack of precision 
>>>>>>>>>>>> in the specs as to when exactly an authZ code is to be invalidated 
>>>>>>>>>>>> by the AS. Let me elaborate a bit:
>>>>>>>>>>>> 
>>>>>>>>>>>> RFC 6749 says (in 4.x) the client MUST only use the code once and 
>>>>>>>>>>>> the AS MUST deny all but the first request with a given code (and 
>>>>>>>>>>>> SHOULD revoke associated tokens). In 10.5, we have "Authorization 
>>>>>>>>>>>> codes MUST be [...] single-use." - without being explicit about 
>>>>>>>>>>>> whether this statement applies to the "user" of the code (the 
>>>>>>>>>>>> client), the AS, or both; although I'd argue that interpreting 
>>>>>>>>>>>> this as "the client may only use it once" is a justifiable 
>>>>>>>>>>>> interpretation (especially because the subsequent sentences in 
>>>>>>>>>>>> 10.5 also just repeat the SHOULD statement from 4.x).
>>>>>>>>>>>> 
>>>>>>>>>>>> RFC 6819, 4.4.1.1 does say "The authorization server should 
>>>>>>>>>>>> enforce a one-time usage restriction (see Section 5.1.5.4)."; but 
>>>>>>>>>>>> the language there is not normative ("may", "may want", ...); the 
>>>>>>>>>>>> same is true for 5.2.1.1.
>>>>>>>>>>>> 
>>>>>>>>>>>> OIDC is even more vague (3.1.3.2): The AS MUST ... "If possible, 
>>>>>>>>>>>> verify that the Authorization Code has not been previously used."
>>>>>>>>>>>> 
>>>>>>>>>>>> ... just a few examples.
>>>>>>>>>>>> 
>>>>>>>>>>>> Using PKCE does not change this ambiguity; RFC 7636 does not talk 
>>>>>>>>>>>> about code invalidation at all.
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> In other words: An error response from the AS's token EP, e.g., 
>>>>>>>>>>>> due to a wrong/missing code_verifier does not guarantee that the 
>>>>>>>>>>>> code has been invalidated. And as others have pointed out in this 
>>>>>>>>>>>> thread, there are AS implementations out there that do accept a 
>>>>>>>>>>>> code multiple times (be it "on purpose", or due to CAP). Of 
>>>>>>>>>>>> course, one might argue that these are not standards-compliant, 
>>>>>>>>>>>> but I don't think there's a very strong case for that claim, given 
>>>>>>>>>>>> the (historically) inaccurate wording...
>>>>>>>>>>>> 
>>>>>>>>>>>> That being said: If I were to implement a client today, I would 
>>>>>>>>>>>> make such a "wrong" token request to at least give the AS a chance 
>>>>>>>>>>>> of detecting the attack - and if the AS follows the SHOULD-advise 
>>>>>>>>>>>> from 6749, any tokens issued for that code would then immediately 
>>>>>>>>>>>> be invalidated, which of course does not prevent an attack, but 
>>>>>>>>>>>> may help to limit the damage.
>>>>>>>>>>>> 
>>>>>>>>>>>> Side note: This "best effort" damage control strategy does not 
>>>>>>>>>>>> even need PKCE, just sending the code with a wrong client_id 
>>>>>>>>>>>> should lead to the same result (from a "did the AS implement 
>>>>>>>>>>>> 6749's SHOULD" perspective).
>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>> If there already is a spec for that in CIBA, we should include or 
>>>>>>>>>>>>> at least reference this in the OAuth 2.1 spec.
>>>>>>>>>>>>> 
>>>>>>>>>>>>> Greetings,
>>>>>>>>>>>>> Jonas
>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Am 05.11.2025 um 04:02 schrieb Frederik Krogsdal Jacobsen 
>>>>>>>>>>>>>> <[email protected]> 
>>>>>>>>>>>>>> <mailto:[email protected]>:
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Hi Jonas,
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Thanks for the detailed explanation of the attack and possible 
>>>>>>>>>>>>>> mitigations.
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> It seems to me that your suggestion 3 could be implemented by 
>>>>>>>>>>>>>> the client by simply exchanging the code and throwing away the 
>>>>>>>>>>>>>> token response when the initial CSRF is detected.
>>>>>>>>>>>>>> This would of course only work with an AS that correctly 
>>>>>>>>>>>>>> implements the security guidance in section 10.5 of RFC 6749: 
>>>>>>>>>>>>>> "Authorization codes MUST be short lived and single-use."
>>>>>>>>>>>>>> The main problem with this approach is that it is a bit 
>>>>>>>>>>>>>> confusing to explain.
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> I also know that in practice, some AS implementers allow 
>>>>>>>>>>>>>> multiple uses of the code, so it may be interesting to look into 
>>>>>>>>>>>>>> defining a specific "cancel request" that uses up a code without 
>>>>>>>>>>>>>> returning a token.
>>>>>>>>>>>>>> Defining such a request might also make the approach easier to 
>>>>>>>>>>>>>> explain.
>>>>>>>>>>>>>> In fact, many OIDC providers already define custom "cancel" 
>>>>>>>>>>>>>> requests to mitigate phishing. A "cancel" request might also be 
>>>>>>>>>>>>>> useful for OpenID CIBA [1].
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Do you see any problems with this approach?
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Cheers,
>>>>>>>>>>>>>> Frederik
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> [1]: 
>>>>>>>>>>>>>> https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> On Tue, 4 Nov 2025 at 05:10, Primbs, Jonas 
>>>>>>>>>>>>>> <[email protected] 
>>>>>>>>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>>>>>>>>> Hi all,
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> according to Aaron’s recommendation, I have created a PR for 
>>>>>>>>>>>>>>> OAuth 2.1: https://github.com/oauth-wg/oauth-v2-1/pull/230
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> It references OpenID Connect’s response modes (fragment and 
>>>>>>>>>>>>>>> form_post) as solutions for Browser-Swapping attacks, which I 
>>>>>>>>>>>>>>> have presented in today’s OAuth WG meeting.
>>>>>>>>>>>>>>> If you have missed my presentation, but are still interested, 
>>>>>>>>>>>>>>> here are my slides: 
>>>>>>>>>>>>>>> https://datatracker.ietf.org/meeting/124/materials/slides-124-oauth-sessa-browser-swapping-01
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> I’m interested in your feedback on this first draft, which 
>>>>>>>>>>>>>>> currently covers only recommendation #2 from my slides, because 
>>>>>>>>>>>>>>> this is probably the least controversial change.
>>>>>>>>>>>>>>> If you are attending onsite, also feel free to speak to me in 
>>>>>>>>>>>>>>> the hallway. My company gave me enough of the „No, PKCE…“ 
>>>>>>>>>>>>>>> t-shirts for the rest of the week, so that it’s easier for you 
>>>>>>>>>>>>>>> to find me. @Brian & Mike: I have learned from the best ;-)
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> Greetings,
>>>>>>>>>>>>>>> Jonas
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> Jonas Primbs M.Sc.
>>>>>>>>>>>>>>> University of Tübingen
>>>>>>>>>>>>>>> Faculty of Science
>>>>>>>>>>>>>>> Department of Computer Science
>>>>>>>>>>>>>>> Sand 13, 72076 Tübingen, Germany 
>>>>>>>>>>>>>>> <https://www.google.com/maps/search/Sand+13,+72076+T%C3%BCbingen,+Germany?entry=gmail&source=g>
>>>>>>>>>>>>>>> Tel.: (+49) 7071 / 29-70512
>>>>>>>>>>>>>>> Mail: [email protected] 
>>>>>>>>>>>>>>> <mailto:[email protected]>
>>>>>>>>>>>>>>> Web: https://kn.inf.uni-tuebingen.de 
>>>>>>>>>>>>>>> <https://kn.inf.uni-tuebingen.de/>
>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>> OAuth mailing list -- [email protected] <mailto:[email protected]>
>>>>>>>>>>>>>>> To unsubscribe send an email to [email protected] 
>>>>>>>>>>>>>>> <mailto:[email protected]>
>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>> OAuth mailing list -- [email protected] <mailto:[email protected]>
>>>>>>>>>>>>> To unsubscribe send an email to [email protected] 
>>>>>>>>>>>>> <mailto:[email protected]>
>>>>>>>>>>>> -- 
>>>>>>>>>>>> Tim Würtele, M.Sc.
>>>>>>>>>>>> Room V38 2.434
>>>>>>>>>>>> Institute of Information Security - SEC
>>>>>>>>>>>> Universität Stuttgart
>>>>>>>>>>>> Universitätsstraße 38 
>>>>>>>>>>>> <https://www.google.com/maps/search/Universit%C3%A4tsstra%C3%9Fe+38?entry=gmail&source=g>
>>>>>>>>>>>> D-70569 Stuttgart
>>>>>>>>>>>> Germany
>>>>>>>>>>>> Phone: +49 (0) 711 685-88468
>>>>>>>>>>>> https://sec.uni-stuttgart.de 
>>>>>>>>>>>> <https://sec.uni-stuttgart.de/>_______________________________________________
>>>>>>>>>>>> OAuth mailing list -- [email protected] <mailto:[email protected]>
>>>>>>>>>>>> To unsubscribe send an email to [email protected] 
>>>>>>>>>>>> <mailto:[email protected]>
>>>>>>>>>>> 
>>>>>>>>>>> _______________________________________________
>>>>>>>>>>> OAuth mailing list -- [email protected] <mailto:[email protected]>
>>>>>>>>>>> To unsubscribe send an email to [email protected] 
>>>>>>>>>>> <mailto:[email protected]>
>>>>>>>>>> 
>>>>>>>>>> _______________________________________________
>>>>>>>>>> OAuth mailing list -- [email protected] <mailto:[email protected]>
>>>>>>>>>> To unsubscribe send an email to [email protected] 
>>>>>>>>>> <mailto:[email protected]>
>>>>>>> _______________________________________________
>>>>>>> OAuth mailing list -- [email protected] <mailto:[email protected]>
>>>>>>> To unsubscribe send an email to [email protected] 
>>>>>>> <mailto:[email protected]>
>>>>>> _______________________________________________
>>>>>> OAuth mailing list -- [email protected] <mailto:[email protected]>
>>>>>> To unsubscribe send an email to [email protected] 
>>>>>> <mailto:[email protected]>
>>>>> _______________________________________________
>>>>> OAuth mailing list -- [email protected] <mailto:[email protected]>
>>>>> To unsubscribe send an email to [email protected] 
>>>>> <mailto:[email protected]>
>>>> 
>> 

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to