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