I think, by far, Philippe’s perspective on web security and the threat modeling 
of BFF vs SPA based implicit flows is accurate and astute.

His perspective should be the driving force for any standard in this area.

I also think it’s dangerous misinformation to claim that BFF has no security 
benefits.

Thanks all,
--
Jim Manico
@Manicode
Secure Coding Education

> On Aug 28, 2023, at 8:15 AM, Jim Manico <j...@manicode.com> wrote:
> 
> *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