*applause*

Sucks you need to explain yourself several times but this is very helpful for 
the community.

> On Aug 28, 2023, at 7:52 AM, Philippe De Ryck 
> <phili...@pragmaticwebsecurity.com> wrote:
> 
> Responses inline.
> 
>> Still, there is some initial incorrect point that makes the rest of the 
>> discussion complicated, and partly wrong.
> 
> I believe the key to make the discussion less complicated is to acknowledge 
> that there are two separate issues:
> 
> 1. An attacker can potentially obtain tokens from the legitimate application
> 2. An attacker can obtain a set of tokens from the AS directly, completely 
> independent of any application behavior
> 
> Given that the goal is to prevent an attacker from obtaining tokens, scenario 
> 1 becomes irrelevant when scenario 2 is a possibility. It would be really 
> helpful to analyze the SW approach with this in mind. I’ll add comments 
> inline to highlight why this matters.
> 
>> 
>> Specifically, §6.4.2.1 says this: The service worker MUST NOT transmit 
>> tokens, authorization codes or PKCE code verifier to the frontend 
>> application.
>> 
>> Wording should be refined, but the idea is that the service worker is to 
>> actually restrict authorization codes from even reaching the frontend. Of 
>> course, easier said than done, but that part happens to be quite easy to 
>> implement. 
> 
> This is related to both scenarios. If the SW is running, you can indeed hide 
> tokens from the main browsing context, which helps to support scenario 1. For 
> scenario 2, you need the guarantee that the SW will intercept all new flows, 
> otherwise the attacker  can run a silent flow. As long as the SW is running 
> in the main context, I would assume that the attacker can indeed not reach 
> the authorization endpoint directly. 
> 
> The key part above is “as long as the SW is running”. An attacker with the 
> ability to run malicious JS can unregister the SW that prevents the attacker 
> from reaching the authorization endpoint. 
> 
> I have raised this issue before, and the response back then was that the SW 
> is only actually removed after the browsing context reloads, which is true. 
> So from the main context, the attacker cannot launch the attack. However, 
> when the attacker instantiates a new browsing context (i.e., an iframe), the 
> unregistered SW is no longer present, and is thereby not able to restrict 
> access to the authorization endpoint. 
> 
> I address this concern in the talk I have referenced before. This link with 
> the time code included (https://youtu.be/OpFN6gmct8c?feature=shared&t=1973) 
> points you to the exact demo scenario, where I illustrate how an unregistered 
> SW cannot prevent access to an endpoint in an iframe. Admittedly, I have not 
> implemented a full OAuth client as a SW, but the minimal PoC you see here 
> suffices to illustrate the ineffectiveness of this approach.
> 
> With this information, the attack scenario becomes the following:
> The attacker unregisters the SW in the main browsing context, preventing it 
> from being used in any new browsing context
> The attacker injects a new iframe and points it to the authorization endpoint
> The AS responds with a redirect with the authorization code
> The attacker detects the redirect, copies the authorization code, and aborts 
> the page from loading (so that the authorization code is never exchanged or 
> the SW is never reloaded)
> The attacker extracts the authorization code and exchanges it for tokens
> 
> 
> TL;DR: a SW is not a security mechanism, and the browser cannot guarantee 
> that a SW permanently prevents requests to a certain endpoint.
> 
> 
>> This has further impact on much of the other statements:
>> > The main problem with a browser-only client is that the attacker with 
>> > control over the client has the ability to run a silent Authorization Code 
>> > flow, which provides them with an independent set of tokens
>> [...]
>> > The security differences between a BFF and a browser-only app are not 
>> > about token storage, but about the attacker being able to run a new flow 
>> > to obtain tokens.
>> [...]
>> > Again, the security benefits of a BFF are not about stoken storage. Even 
>> > if you find the perfect storage solution for non-extractable tokens in the 
>> > browser, an attacker still controls the client application and can simply 
>> > request a new set of tokens. 
>> 
>> Truth is: no, you can't start a new authentication flow and get the 
>> authorization code back in the main thread. I'm talking about the 
>> redirection scenario, which I'm the most familiar with, but it would 
>> probably apply to the "message" one as well (which is new to me and seems to 
>> be ashtoningly legit due to vague "for example" wording in the OAuth2 spec 
>> :-) ).
> 
> The attack scenario above does not run the redirect scenario in the main 
> browsing context, but in an iframe. Opening an iframe instantiates a new 
> nested browsing context, where unregistered SWs are not available. 
> 
> 
>> The service worker, according to 
>> https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/fetch_event#description
>>  , just intercepts the authorization code, gets a token, and never sends it 
>> back to the main code.
> 
> This point is not relevant, since your SW is no longer active when the 
> attacker’s authorization code is being returned. 
> 
> 
>> But don't trust me on my words: what about demonstrating our claims with 
>> actual code, and as such create a shorter, simpler, but more constructive 
>> discussion?
> 
> I don’t understand where this remark comes from. I have already demonstrated 
> back in January that this approach is not effective, and have referred to the 
> recording of this presentation numerous times. I stand by my demonstration of 
> the ineffectiveness of SW and encourage you to test this out yourself. It is 
> as simple as setting up your SW, unregistering it, and running an 
> authorization code flow in an iframe. You’ll see that the request goes 
> through to the AS, and that your SW is no longer able to stop it.
> 
>> 
>> The demonstration in its current form would not lead to a successful 
>> compromise of a good implementation of access tokens handled by a service 
>> worker.
> 
> Once again, I refer back to the start of my mail: it is not about protecting 
> existing tokens (scenario 1), it is all about preventing the attacker from 
> running a new flow (Scenario 2).
> 
> 
> I understand that all of this is quite inconvenient, especially if one is 
> heavily invested in running browser-only OAuth clients. Unfortunately, it is 
> the nature of web-based applications, and doing so requires a complete 
> picture of the security implications. That’s exactly what we are working on 
> with the specification.
> 
> 
> Kind regards
> 
> Philippe
> 
> 
> —
> Pragmatic Web Security
> Security for developers
> https://pragmaticwebsecurity.com/
> _______________________________________________
> OAuth mailing list
> OAuth@ietf.org
> https://www.ietf.org/mailman/listinfo/oauth
_______________________________________________
OAuth mailing list
OAuth@ietf.org
https://www.ietf.org/mailman/listinfo/oauth

Reply via email to