Hi Torsten,

> On 16 May 2020, at 19:50, Torsten Lodderstedt <tors...@lodderstedt.net> wrote:
> 
> Hi Philippe, 
> 
>> On 16. May 2020, at 17:08, Philippe De Ryck 
>> <phili...@pragmaticwebsecurity.com> wrote:
>> 
>> Hi all,
>> 
>> I am working on formulating developer guidelines on using Refresh Token 
>> Rotation (RTR), as required by "OAuth 2.0 for Browser-Based Apps". 
>> 
>> The protection offered by RTR kicks in the moment a refresh token is used 
>> twice, so the assumption is that the attacker has the ability to steal 
>> tokens from the client. In general, this means the attacker has malicious 
>> code running in the application (e.g., XSS, remote JS inclusion, ...). 
>> 
>> Within these constraints, I can think of a couple of malicious payloads that 
>> sidestep the protection offered by RTR:
>> 
>> 1. Stealing access tokens in an online XSS attack
>> 2. Stealing refresh tokens, but waiting to use the latest until the original 
>> client is no longer active
>> 3. Running a silent authentication flow in an iframe to obtain a new and 
>> unrelated AT and RT, and use that until it expires
>> 
>> Scenario 1 is straightforward in most applications, but the attack requires 
>> the vulnerable application to remain online. Scenario 2 might be difficult 
>> if the RT is kept out of reach from the main application (e.g. in a worker 
>> thread). Scenario 3 is most dangerous, but also a bit tricky to implement as 
>> the payload needs to make sure the application's code does not interfere 
>> (however, the browser's Same-Origin Policy will not intervene). The 
>> specifics depend on the concrete implementation, but all three attacks are 
>> technically feasible.
>> 
>> With these attacks in mind, it seems that the use of the Authorization Code 
>> flow with RTR does not really add much improvement for security, if other 
>> best practices are followed (e.g., using HTTPS). RTR does a lot for 
>> usability and handling third-party cookie blocking scenarios though.
> 
> I also see this as the main advantage of RTs.
> 
> I think scenario 3 can be made more difficult for the attacker by requiring 
> user interaction. That’s ok since the normal case would be to refresh via RT 
> and not via authorization flow, so the legit app shouldn’t be affected. 

Preventing a silent flow from happening would indeed stop this attack vector, 
but it might create usability problems in single page applications.

A typical scenario is an SPA running a silent authentication flow in an iframe 
when it is first started. This allows the app to bootstrap itself with the 
user’s authentication status if a session already exists. This pattern is 
common when tokens are kept in memory, as a simple page reload causes that 
state to be cleared. Since Safari and Brave already block third-party cookies, 
they cannot run a silent flow in an iframe. A workaround would be to run a 
top-level silent redirect-based flow to check if an authenticated session 
exists or not. The impact on the UX for this initial redirect is limited, since 
it is silent anyway. By turning off a silent flow, both use cases would stop 
working. 

I totally get that this is a quite challenging problem to address. Given your 
suggestion, the authorization server could prevent iframe-based flows when RTs 
are used, but still allow top-level navigation flows for the bootstrap phase. 
Right now, I don’t think we can implement such a detection mechanism in a 
reliable way, but hopefully the upcoming Sec-Fetch-Dest header can help here 
(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Dest 
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Dest>)

> 
>> 
>> In this context, my advice to developers is to avoid handling tokens in the 
>> browser in security-sensitive scenarios. A Backend-for-frontend pattern 
>> gives a server-side component control over tokens, along with the ability to 
>> implement additional security measures.
> 
> I full agree with those advice. Handling security sensitive aspects of the 
> app out of reach of the user (which might be an attacker) is a good idea. On 
> the functional side, this also gives the app access to authentication and 
> sender constrained access tokens via mTLS.

That’s precisely my recommendation as well. 

>> 
>> Additionally, is there any official recommendation to link the validity of a 
>> refresh token to the lifetime of the user's session with the Authorization 
>> Server? Having that property gives RTR similar security properties as the 
>> silent renew scenario. 
> 
> Section 4.12.2. of the Security BCP recommends refresh token revocation in 
> case of logout. 

Right, I should have checked that more closely for the details. I also see it 
recommends the timeout after inactivity, which corresponds somewhat to linking 
it to the session lifetime (which would have similar properties). 

Thanks!

Philippe

> 
> best regards,
> Torsten. 
> 
>> 
>> Any feedback on this train of thought is more than welcome.
>> 
>> Philippe
>> 
>> 
>> _______________________________________________
>> OAuth mailing list
>> OAuth@ietf.org <mailto:OAuth@ietf.org>
>> https://www.ietf.org/mailman/listinfo/oauth 
>> <https://www.ietf.org/mailman/listinfo/oauth>
_______________________________________________
OAuth mailing list
OAuth@ietf.org
https://www.ietf.org/mailman/listinfo/oauth

Reply via email to