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]>:
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
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 [email protected]
--
Tim Würtele, M.Sc.
Room V38 2.434
Institute of Information Security - SEC
Universität Stuttgart
Universitätsstraße 38
D-70569 Stuttgart
Germany
Phone: +49 (0) 711 685-88468
https://sec.uni-stuttgart.de
_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]