> 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] > <mailto:[email protected]>> wrote: >> Hi Dick, >> >> >>> Am 05.11.2025 um 06:32 schrieb Dick Hardt <[email protected] >>> <mailto:[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] >>> <mailto:[email protected]>> wrote: >>>> Hi Neil, >>>> >>>>> Am 04.11.2025 um 09:53 schrieb Neil Madden <[email protected] >>>>> <mailto:[email protected]>>: >>>>> >>>>> >>>>> >>>>>> On 4 Nov 2025, at 13:37, Primbs, Jonas <[email protected] >>>>>> <mailto:[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] >>>>>>> <mailto:[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] <mailto:[email protected]> >>>> To unsubscribe send an email to [email protected] >>>> <mailto:[email protected]> >>
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ OAuth mailing list -- [email protected] To unsubscribe send an email to [email protected]
