I'm also not confident, which is why I just want to know what exactly is happening *only on the victim's side*. It's trivial to figure out what the attacker can do on their side. But if you're correct, and it's a question about exfiltrated authorization codes, is the assumption that PKCE doesn't solve the problem because PKCE too could be logged?
On Fri, Nov 7, 2025 at 11:30 AM Frederik Krogsdal Jacobsen <[email protected]> wrote: > Warren: My understanding is that the interception in the sentences you > quoted happens in the attacker's user agent, while the CSRF detection > happens as a result of interactions with the victim's user agent. So the > attacker cannot generally block AS requests. > And in particular, the CSRF detection happens as a result of a request by > the victim's user agent, which is not controlled by the attacker. > > The client server can thus invalidate the code upon detecting the CSRF (by > any mechanism), and there's nothing the attacker can do about that except > obtaining and exchanging the code fast enough that the invalidation has not > happened yet. > For the mentioned information vectors for obtaining the code (such as logs > or asking the user for the URL), I think it is unlikely that the attacker > can obtain the code faster than the client server can invalidate it. > So I think this mitigation (whatever the mechanism for invalidation) is > enough to prevent essentially all practical attacks. > > But I'm not that confident that my understanding is correct, or whether we > are even talking about the same thing any longer. I think this thread is on > the verge of becoming too messy for any productive conversation to happen. > The quotes and references (1), S1, etc. are not very easy to follow across > subthreads. > > Cheers, > Frederik > > On Fri, 7 Nov 2025 at 10:52, Warren Parad <wparad= > [email protected]> wrote: > >> You know, I had that thought, but I read this statement by Jonas: >> >> The attacker intercepts the authorization URL when being sent to the >>> authorization server. Most of the time, this works by copying the URL >>> displayed on the AS’s login page. Sometimes it’s a bit more complicated >>> because the attacker must intercept URLs called in their browser. However, >>> the attacker has full control over their web browser, so this is easy. >> >> >> Which tells me that it is actually the same vulnerability. (However, I >> read "web browser" as "application" here, so that could be my mistake). >> "Attacker has control over the web browser" means that they will do >> anything in their power to circumvent the controls in place. >> >> If the attacker controls the application in the user agent, I don't think >> it makes sense to secure less useful mechanisms. For instance, if the >> attacker could block AS requests, then it doesn't make sense to introduce a >> "but intentionally using PKCE without a verifier is one way to revoke a >> code without getting a token that you could accidentally use." because that >> would just be blocked. Sure the attacker might not block AS requests, but >> if they could, then we will see this attack vector become the only one that >> gets used. So in practice, we should assume attackers to perform the most >> sophisticated attack possible given any scenario. >> >> On Fri, Nov 7, 2025 at 10:42 AM Frederik Krogsdal Jacobsen >> <[email protected]> wrote: >> >>> Warren, I think you may be mixing this thread up with Andrey's thread on >>> a different, but related topic? Some of the replies to Andrey's thread got >>> scattered across different threads (at least in my email client). >>> In this attack (as I understand it), the attacker does not block any >>> request to the AS. >>> PKCE by itself does not fix this problem, but intentionally using PKCE >>> without a verifier is one way to revoke a code without getting a token that >>> you could accidentally use. >>> >>> Cheers, >>> Frederik >>> >>> On Fri, 7 Nov 2025 at 10:36, Warren Parad <wparad= >>> [email protected]> wrote: >>> >>>> 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'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? >>>> >>>> On Fri, Nov 7, 2025 at 10:08 AM Frederik Krogsdal Jacobsen >>>> <[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 <aaron= >>>>> [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]> >>>>>> 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]> 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]> 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] >>>>>>>> >: >>>>>>>> >>>>>>>> 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]> 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]> <[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]> 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] >>>>>>>>> Web: https://kn.inf.uni-tuebingen.de >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> OAuth mailing list -- [email protected] >>>>>>>>> To unsubscribe send an email to [email protected] >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OAuth mailing list -- [email protected] >>>>>>>> To unsubscribe send an email to [email protected] >>>>>>>> >>>>>>>> -- >>>>>>>> Tim Würtele, M.Sc. >>>>>>>> Room V38 2.434 >>>>>>>> Institute of Information Security - SEC >>>>>>>> Universität StuttgartUniversitä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-88468https://sec.uni-stuttgart.de >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OAuth mailing list -- [email protected] >>>>>>>> To unsubscribe send an email to [email protected] >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OAuth mailing list -- [email protected] >>>>>>>> To unsubscribe send an email to [email protected] >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OAuth mailing list -- [email protected] >>>>>>>> To unsubscribe send an email to [email protected] >>>>>>>> >>>>>>> _______________________________________________ >>>>>> OAuth mailing list -- [email protected] >>>>>> To unsubscribe send an email to [email protected] >>>>>> >>>>> _______________________________________________ >>>>> OAuth mailing list -- [email protected] >>>>> To unsubscribe send an email to [email protected] >>>>> >>>>
_______________________________________________ OAuth mailing list -- [email protected] To unsubscribe send an email to [email protected]
