That would require the POST request response from the client to set yet another session with the authenticated account that is then used/merged with the original one in the follow up GET that the user needs to first confirm with an explicit action?
I don't think you're missing anything but the suggestion is beyond the realm of practical, usable or suggestable from my perspective. S pozdravem, *Filip Skokan* On Wed, 5 Nov 2025 at 18:09, Primbs, Jonas <[email protected]> wrote: > > > Am 05.11.2025 um 10:54 schrieb Filip Skokan <[email protected]>: > > > That’s right, but you don’t need a full session for finishing the > authorization code flow. > > That's a rather sweeping statement which is only conditionally true. There > are very specific cases for which in fact this is false (e.g. step-up, > re-auth, account-linking). > > > But couldn’t this be fixed by the user clicking a confirm link on the HTML > response of the POST redirect URI endpoint? > > So calling the POST callback URI would submit only the SameSite=none state > cookie to implement the CSRF mitigation. > If the state verification and the token request succeeded, the client > responds with a HTML document like „You are authenticated as [the OIDC > user] from [the IdP]. Is that right?“. > Then the user needs to click a „confirm“ button which is a link to a > confirmation page. Technically, this is a same-site GET request initiated > by the user, so samesite=lax and I think even samesite=strict session > cookies will be sent along with this request. > > Or did I miss anything here? > > > S pozdravem, > *Filip Skokan* > > > On Wed, 5 Nov 2025 at 16:34, Primbs, Jonas <[email protected]> > wrote: > >> Hi Dick, >> >> >> Am 05.11.2025 um 06:32 schrieb Dick Hardt <[email protected]>: >> >> Jonas >> >> + Filip given his expertise >> >> I tried to follow this thread but got lost. >> >> My understanding is you are suggesting we recommend >> response_mode=form_post over response_mode=redirect >> >> >> * response_mode=query, but yes. >> >> If session cookies are sameSite=lax, they won't to be sent via form_post >> -- so client web sites would have to set session cookies to sameSite=none >> -- which is susceptible to CSRF of course, and while there are other ways >> to protect against CSRF, your attack is CSRF -- so it would seem that if >> the site has protected against CSRF then the attack can't happen. >> >> >> That’s right, but you don’t need a full session for finishing the >> authorization code flow. >> Instead, you just need to remember the state sent in the authorization >> request and (if PKCE is being used) the code_verifier. >> This means, when starting the authorization code flow, you can set the >> following cookie when redirecting from the client to the authorization >> request URI: >> >> Set-Cookie: state_{state}={code-verifier}; SameSite=none >> >> When you will be sent back with the POST request to the client, your >> browser sends this cookie to the client backend (because of SameSite=none) >> and since the POST body contains the same state parameter (reflected by the >> AS), you fulfill the double submit pattern which is a well-known CSRF >> protection. >> >> Does this make things clear for you? >> >> Greetings, >> Jonas >> >> >> What am I missing? >> >> /Dick >> >> On Wed, Nov 5, 2025 at 3:56 AM Primbs, Jonas < >> [email protected]> wrote: >> >>> Hi Neil, >>> >>> Am 04.11.2025 um 09:53 schrieb Neil Madden <[email protected]>: >>> >>> >>> >>> On 4 Nov 2025, at 13:37, Primbs, Jonas <[email protected]> >>> wrote: >>> >>> Hi Neil, >>> >>> thanks for your valuable feedback. >>> You will find my thoughts inline. >>> >>> Am 04.11.2025 um 04:19 schrieb Neil Madden <[email protected]>: >>> >>> Thanks for sharing your slides. Although this is an interesting >>> theoretical attack, I do not think it is much of a concern in practice. If >>> we take your attack vectors from slide 12: >>> >>> * Referer header leaks: the default policy in browsers since 2019 is >>> strict-origin-when-cross-origin, which prevents this leak [1]. >>> >>> >>> I still think it is worth to mention in the draft because even if it’s >>> the default, it does not mean that client implementors do not change it in >>> a bad way. >>> Moreover, in modern infrastructures, reverse proxies are often used for >>> path-based routing, which results resources (images, favicons etc) being >>> referenced on the same host but requests will be routed to external parties >>> like CDNs. >>> >>> * URL sharing and analytics tools are already addressed by [2] in the >>> original OAuth RFC 6749, which already says to avoid 3rd party analytics on >>> the redirect endpoint and to redirect immediately after collecting the >>> credentials. I think most providers do in fact do this? >>> >>> >>> Yes, I have never seen the issue with the analytics tools in the wild >>> before, I just added it for completeness. >>> Out of the last 10 oauth client penetration tests, of which 6 were >>> affected by the browser swapping attack (the other 4 did not even implement >>> the CSRF protection), only one was affected by the URL sharing. >>> However, redirecting to another URL, not including scripts, and ensuring >>> that referrer-policies are applied correctly are all mitigation strategies, >>> but not solve the general issue of sending a secret (the authorization >>> code) as a query parameter, which is a bad practice in general [1]. >>> >>> That leaves leakage via logs, which IMO is adequately addressed by (a) >>> use of TLS (minimising on-path observers) and (b) using short-lived auth >>> codes. >>> >>> >>> a) That’s correct. >>> b) According to RFC 6749, the maximum validity period is 10 minutes. >>> Today, many logging happens in real-time, so my impression was that 10 >>> minutes is enough for attackers with access to logs. Think of a shell >>> script which polls every minute for the logs and greps for the keyword >>> „code“, extracts the authorization code and automatically resolves that. >>> >>> >>> Attackers with real-time access to logs are generally already quite >>> privileged (eg they have ssh access to the servers or access to a SIEM). >>> The risk from logs mostly comes from them being copied into support tickets >>> or archived to insecure S3 buckets and similar things. Those things don't >>> generally happen in 10 minutes. >>> >>> >>> I don’t agree here. >>> Having read-only access to a SIEM system, which provides you real-time >>> access to logs being collected from a client application or any involved >>> reverse proxy, load balancer, middleware etc, should not enable you taking >>> over the client session of any user. >>> This is a behavior, which many service providers will not expect from an >>> OAuth-compliant software. >>> >>> Moreover, this increases the criticality of misconfigured HTTP servers, >>> e.g., an NGINX or Apache web server which allow you to access the server’s >>> logs in real-time by browsing something like >>> /../../../../var/logs/nginx/access.log >>> I agree, such misconfigurations should not be in scope of OAuth. >>> However, this increases the criticality of such a finding from an >>> information leak to a medium or even high - and OAuth could improve that by >>> slightly changing the specs. >>> >>> >>> Using fragments or form_post both have significant downsides. Fragments >>> only work with Javascript, which introduces new failure cases and attack >>> surface (ideally the redirect endpoint would be served with CSP >>> script-src=none). >>> >>> >>> Yes, that’s why I recommend this for web apps running in the user’s >>> browser with javascript anyways, or for mobile apps. >>> >>> >>> Re-reading my old blog post ( >>> https://neilmadden.blog/2019/01/16/can-you-ever-safely-include-credentials-in-a-url/) >>> reminds me of a drawback of using the fragment: if you don't explicitly >>> clear it, then it is carried over on redirects, potentially leaking the >>> auth code to other pages/sites. (At least, that used to be the case - I >>> don't believe that behaviour has changed). >>> >>> >>> Yes, but we have the same issue with query parameters too, right? >>> Fragment however has the advantage of reducing the attack surface with >>> respect to logging from an entire landscape down to the client. >>> >>> >>> >>> Form post requires use of samesite=none cookies, weakening CSRF >>> protections. I don’t think we should be recommending weakening protections >>> against very real threats (XSS, CSRF) to protect against something that >>> seems unlikely. >>> >>> >>> Thanks a lot for that hint with the CSRF protection with samesite=none. >>> I think samesite=none works perfectly fine, if the „session“ cookie is >>> not a real session cookie, but the state parameter instead, because then >>> the „state“ cookie, which contains the state parameter combined with the >>> identical state parameter reflected by the AS in the POST body parameter >>> apply the double submit cookie pattern [2], which is also a well-known CSRF >>> protection mechanism. >>> The real session cookie (if you even need one before you are logged in) >>> could still use samesite=strict or lax. >>> But I get the point that maybe I should mention this in the draft. >>> >>> We can perhaps improve the wording around existing countermeasures if >>> there is evidence they are being ignored, but I think that is enough. I >>> could be persuaded otherwise, but I’d need to see more evidence that this >>> is a problem in practice and that the countermeasures do more good than >>> harm. >>> >>> >>> I think the problem with response_mode=query in general is that the >>> authorization code is transferred in the URL which opens up many attack >>> vectors that all need to be fixed. >>> The most critical one are logs because there is no general fix for that, >>> exept not providing the authorization code as a query parameter. >>> My impression was that our customers were really surprised that this is >>> still the default behavior of OAuth and they didn’t expect that from such a >>> big large-scale deployed standard. >>> Especially our customers, which just deploy existing client >>> implementations, did not expect that they have to care that much about logs >>> of, e.g., their reverse proxies, and they were shocked that these logs >>> which are sometimes audited by external partners enable the log auditor to >>> start a browser-swapping attack and take over, e.g., administrator accounts. >>> >>> >>> I agree in general, but (a) the situation is a lot less bad than it used >>> to be and (b) the short-lived nature of auth codes does IMO mitigate a lot >>> of these issues. According to >>> https://www.oauth.com/oauth2-servers/authorization/the-authorization-response/, >>> most auth codes are in fact only valid for 30–60 seconds, which would >>> further reduce the opportunity to exploit this. >>> >>> >>> That’s right, maybe we should recommend a validity period of 1 instead >>> of 10 minutes in OAuth 2.1. >>> >>> By the way, Aaron and I had a discussion on that today and we figured >>> out that the „implicit flow“ of OIDC might also be affected. Probably >>> things are much more critical here than in OAuth. >>> >>> We also discovered an alternative fix for that by enforcing PKCE for >>> every flow and sending a token request from client to AS even if state >>> parameters don’t match. >>> This promises to simplify the specs in general with the nice side effect >>> that it also sufficiently fixes browser-swapping attacks without breaking >>> changes. >>> I will discuss that with Aaron and Mike and will send an update. >>> >>> I'm sympathetic to the idea that query mode is not great, but it's >>> pretty well established at this point and we've spent a long time telling >>> people to use it. I don't find this a compelling enough reason to suggest a >>> change. >>> >>> >>> I get your point. However, I’m not a friend of leaving things as they >>> are, just for not having to correct previous statements, especially if >>> we could do better. >>> >>> I totally agree, that we cannot simply deprecate response_mode=query for >>> legacy reasons. However, I think we should ensure that client developers >>> and providers are aware of the risk that authorization codes can get logged >>> and can be used to take over user sessions. >>> >>> [1] >>> https://owasp.org/www-community/vulnerabilities/Information_exposure_through_query_strings_in_url >>> [2] >>> https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#alternative-using-a-double-submit-cookie-pattern >>> >>> >>> — Neil >>> >>> >>> Independently of whether browser-swapping attacks are a realistic attack >>> or not — does anyone disagree with adding or at least referencing response >>> modes in the OAuth 2.1 spec in general? >>> I personally would have been glad to have had any reference to them from >>> another document instead of being lucky that I accidentially stumbled over >>> this spec. >>> >>> Greetings, >>> Jonas >>> >>> >>> _______________________________________________ >>> 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]
