> Am 05.11.2025 um 12:21 schrieb Filip Skokan <[email protected]>: > > 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?
For the classic login-via-OIDC use case, the POST endpoint will directly respond with setting a cookie session for the client. For the use-cases you described earlier (step-up auth, OIDC account linking) etc, clicking the confirm link might do well. > 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] > <mailto:[email protected]>> wrote: >> >> >>> Am 05.11.2025 um 10:54 schrieb Filip Skokan <[email protected] >>> <mailto:[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]
