One thing I should add here, and then I’ll head to bed given that it’s almost 5am here 😊- I am fully behind code+PKCE. Auth0 has been supporting code+PKCE in its JS SPA SDKs, including refresh token rotation support, since early last year. I stress this so that no one thinks this an attempt to get out of supporting code+PKCE, it’s not. For true SPAs (no backend) that remains the main way for enabling frontents to call API. This is more about trying to take advantage of the presence of the backend to make things simpler when viable, and to bring some guidance to emerging practices that risk drifting into insecure waters without it.
From: Vittorio Bertocci <vittorio.berto...@auth0.com> Date: Sunday, February 14, 2021 at 04:27 To: Warren Parad <wparad=40rhosys...@dmarc.ietf.org>, Neil Madden <neil.mad...@forgerock.com> Cc: oauth <oauth@ietf.org> Subject: Re: [OAUTH-WG] Token Mediating and session Information Backend For Frontend (TMI BFF) Hi Warren, thanks for the thoughtful comments. Inline. * . It introduces a pseudo AS-like proxy which now has all the requirements of an AS and more. While AS SDKs provide easy ways for client UIs to effectively deal with communication via the AS, there's no way for the AS to provide standard AS specific services prototypes to support BFF. That means that everyone is writing their own BFF AS-proxy. TMI-BFF does provide a sort of proxy for the AS, but it is very constrained both in functionality (only one simple request type) and topology (only one requestor type, with assumptions about sessions, origin provenance etc) hence the requirements are a very limited subset of a full blown AS. In terms of everyone doing their own implementation, the intent here is the exact opposite. By providing guidance on how to format requests/responses and what endpoints to refer to, the implementation details can be factored out from individual apps and stacks, facilitating interoperability. * [..] Which isn't ever justified, but even if we accept that as a true premise, what are these AS doing that even require a BFF? I am not sure how to interpret the statement about “ever justified”. This has little to do with the authorization server. Not every application can have a backend that exposes a façade replicating all the APIs the frontend need to invoke, for all sorts of reasons: maintenance, performance, skills of the developers involved, capabilities of the stacks of choice, and so on. This isn’t theoretical, I had this discussions many times with prospects and developers. * Hypothetically you could argue that the auth code flow requires a BFF and that's required for user login since implicit flow no longer exists, but that isn't true. You can use client side PKCE for validation of these via not requiring the client secret in the front end, and then the problem there is solved. In concrete terms, things are a bit more complicated than “a grant for SPAs already exist”. I am well aware that code+PKCE is a viable solution for SPAs to get access tokens, however that has its own challenges. For example, if you want to use refresh tokens in it, you need to sender constrain them or support refresh token rotation. If you check the current situation across the industry, you’ll see that very few SDKs actually do support rotation or sender constraint today- arguably introducing a new security issue. And of course, there’s the huge debacle about saving tokens in local storage- something that many applications need to do in order to offer the experience their customers require. If a SPA app does not have a backend, code+PKCE is the only game in town. If it has a backend AND can leave all actual API calls to it, there’s no need to get tokens in the user agent. But if you are in one situation where you do have a backend and cannot delegate API calls (see my preceding comment), then TMI-BFF can get tokens to your frontend without requiring complex javascript logic, without having to persist anything in local storage and without requiring the AS to support rotation or sender constraint. As long as the traffic with bff-token proxy is hardened, I would argue TMI-BFF might actually be easier to implement securely that code+PKCE+rotation/SC. Having access tokens in the frontend remains not great, but it seems that giving people who would do it anyway some guidance is better than leaving them at their own device- unless we conclude that this flow cannot be secured, in which case I agree we should explicitly idnciate this as anti pattern. But so far, it seems still to be demosntrated. * There was also the argument of there are lots of people doing this, which is always a terrible argument, but even if we do permit that in the discussion, we still need to answer the why. Why are developers creating BFF for their frontends to communicate with an AS. Is it because AS are terrible, is it because front ends as a service are terrible, etc... Until we know why this is happening concretely, I don't think we should encourage further use of a pattern rife with potential security risks by telling everyone how you can do it (because the guidance we are offering doesn't even slightly increase safety). The preceding comments should have shed more light about the why, and on some of the security concerns (there was one concern raised by Neil, and it seems there are possible mitigations in place) plus how this might actually increase safety in some aspects. But to add more color, one of the other reasons for which this is happening is because it’s simple. Backend OAUth/OIDC SDKs like middlewares and similar are very mature at this point, and they aren’t saddled by a lot of the complexity and uncertainly that browser based SDKs carry. Things like IE zones, ITP, SameSite and our own changing guidance (for good reasons) plus disomogeneous support from providers of the features required for the latest guidance create uncertainty and complexity that many non-initiated won’t put up with. Add to this that the more app development moves to the frontend, the more you don’t get full stack developers and getting a frontend developer to deal with all those quirks is hard. Getting tokens thru well supported middlewares and forward them to the frontend is simple. Also, to be clear. This exact topology has been considered discussed in the past during IETF meetings, in Montreal we had a discussion about including it in some BCP and whether we should have a mechanism for the client to signal to the AS that the tokens will be used by code executing in a weaker security context (user agent) than the requestor’s (confidential client on backed). I am sure we can find the minutes of that. This isn’t something completely left field. * Further, even if we were to accept this pattern and want to create a standard around it, we are effectively creating an AS proxy here, which means we should require it to act like an AS, and delegate the specification of resources, endpoints, terminology, and patterns to existing or future AS related RFCs. I don’t believe that the scope of the proposal warrants doing al that. Could you point at the area in the spec that suggest we’d need to add anything beyond what’s suggested at the moment to achieve the stated goals? * And therefore in conclusion we should focus only on the aspects that are absolutely required which aren't already present in some form in existing AS related RFCs, but what are those? I am still missing how this has to do with missing AS functionality. One of the things we tried to do was not to require any change to the AS. The problem being solved here is how to allow javascript developers to call API directly from their frontend when they have a backend with basic oauth capabilities at their disposal, in the simplest possible way. Changes in the AS doen’t appear to be necessary there * The one counterpoint to all of this is the potential introduction of domain specific cookie language (which doesn't exist in the current draft). Concretely, let's add a response_type=cookie, to AS to support domain first-party cookies and session management. Could you expand on how you envision this would work/solve the problems described above? From: Warren Parad <wparad=40rhosys...@dmarc.ietf.org> Date: Sunday, February 14, 2021 at 01:51 To: Neil Madden <neil.mad...@forgerock.com> Cc: Vittorio Bertocci <vittorio.berto...@auth0.com>, oauth <oauth@ietf.org> Subject: Re: [OAUTH-WG] Token Mediating and session Information Backend For Frontend (TMI BFF) I also flat out reject the premise of this draft. It introduces a pseudo AS-like proxy which now has all the requirements of an AS and more. While AS SDKs provide easy ways for client UIs to effectively deal with communication via the AS, there's no way for the AS to provide standard AS specific services prototypes to support BFF. That means that everyone is writing their own BFF AS-proxy. Additionally, I too am lacking the clarity on the WHY. The only thing mentioned in the draft is That approach is not always viable, as in the absence of reverse proxy deployments the creation and maintenance of a facade for multiple APIs can be expensive Which isn't ever justified, but even if we accept that as a true premise, what are these AS doing that even require a BFF? Hypothetically you could argue that the auth code flow requires a BFF and that's required for user login since implicit flow no longer exists, but that isn't true. You can use client side PKCE for validation of these via not requiring the client secret in the front end, and then the problem there is solved. And if you argue that this can't be done, then the solution is introducing a better way to handle this so that a BFF for AS flows don't have to exist. So what concrete problem is this solving? There was also the argument of there are lots of people doing this, which is always a terrible argument, but even if we do permit that in the discussion, we still need to answer the why. Why are developers creating BFF for their frontends to communicate with an AS. Is it because AS are terrible, is it because front ends as a service are terrible, etc... Until we know why this is happening concretely, I don't think we should encourage further use of a pattern rife with potential security risks by telling everyone how you can do it (because the guidance we are offering doesn't even slightly increase safety). Further, even if we were to accept this pattern and want to create a standard around it, we are effectively creating an AS proxy here, which means we should require it to act like an AS, and delegate the specification of resources, endpoints, terminology, and patterns to existing or future AS related RFCs. (We already have a problem with the current draft as it attempts to redefine and introduce new terms/patterns that have the same functionality as existing ones in the AS, yet fail to capture the full importance of the original RFCs. This is bad duplication). And therefore in conclusion we should focus only on the aspects that are absolutely required which aren't already present in some form in existing AS related RFCs, but what are those? The one counterpoint to all of this is the potential introduction of domain specific cookie language (which doesn't exist in the current draft). Concretely, let's add a response_type=cookie, to AS to support domain first-party cookies and session management. When we built our AS we explicitly added this so that services can use the JWT found in the HttpOnly SameSite=Strict cookie as a security measure against XSS attacks that attempt to exfiltrate access tokens. That's a potential suggestion I would favor, although I still can't know if that solves the problem being presented in the draft. - Warren [Image removed by sender.] Warren Parad Founder, CTO Secure your user data and complete your authorization architecture. Implement Authress<https://authress.io>. On Sun, Feb 14, 2021 at 9:18 AM Neil Madden <neil.mad...@forgerock.com<mailto:neil.mad...@forgerock.com>> wrote: I have a lot of security concerns about this draft. The draft alludes to security issues associated with handling access tokens in the frontend but never really spells them out. >From the Security Considerations it seems that the primary concern is with theft of access tokens from local storage. To do this you’d need an XSS attack. But in that case, wouldn’t the attacker simply use the XSS to make a call to the bff-token endpoint instead? The combination of the bff-token endpoint recommending the use of GET requests together with the hint to use cookie-based authentication is likely going to punch a hole in most CSRF defenses, which assume that GETs are safe. The only thing preventing this being exploitable is Cross-Origin Read Blocking (https://chromium.googlesource.com/chromium/src/+/master/services/network/cross_origin_read_blocking_explainer.md) due to the JSON content-type. That makes me really nervous. We should at least mandate X-Content-Type-Options: nosniff on that response. I’d feel more comfortable if this was a POST request only. As Stoycho Sleptsov mentioned in the other email, the lack of front-channel communication between the AS and the RO seems odd. If the backend is already implicitly trusted then couldn’t you skip OAuth and just get the backend to issue short-lived JWTs to the frontend that it can use for API access? If you want to allow auth code flow etc then perhaps the bff-token endpoint can return a standard error code with an authorization endpoint URI that the SPA then navigates the user to. (Eg the backend can do a PAR request first and return a URI that references that so that authorization details aren’t passed through the frontend). — Neil On 12 Feb 2021, at 20:46, Vittorio Bertocci <vittorio.bertocci=40auth0....@dmarc.ietf.org<mailto:40auth0....@dmarc.ietf.org>> wrote: Dear all, Brian and yours truly are proposing a new specification that shows how the user agent frontend of a web app can delegate token acquisition and persistence to its backend, and request such tokens when needed for direct access of protected resources from the frontend code. The pattern is already in use, in proprietary form, by various modern development stacks, such as Next.JS. Variants of the pattern, often discussed under the catch-all term BFF (backend for frontend), have been often mentioned in this workgroup’s activity, but always left all implementation details to the reader. We believe the pattern has merit, as corroborated by its growing adoption. By delegating access token acquisition to the backend, we avoid many of the often brittle moving parts (and implied attack surface) required to acquire access tokens from a user agent. The topology also relieves the frontend from the need of persisting tokens in local storage, a well known sore point of using OAuth directly in JavaScript, by relying on its backend storage and session to preserve tokens. Although the specification is very simple, providing explicit guidance on the scenario offers many advantages. - It makes it possible to create interoperable SDKs, where frontend dev stacks (any JS flavor) can be mixed and matched with compliant backend stacks (middlewares in node, java, ASP.NET<http://ASP.NET>, PHP etc) - It allows us to provide guidance on how to properly tackle the scenario and warn implementers against security risks (scope escalations, using IDtokens instead of access tokens, etc) - It allows us to discuss (and when appropriate, promote) this pattern as part of the browser apps security guidance, and position the scenario where frontend only calls API on its own backed (hence doesn’t need access tokens) simply as a special case of this more general pattern - This approach makes mocking and testing apps very easy, possibly preventing developers from weakening the security of their system (eg turning on ROPG options) or turning to risky practices like scraping Needless to say, this specification doesn’t entirely eliminate the risks inherent to direct use of access tokens from a browser. But reality is that the pattern is in widespread use, and the circumstances leading to that (eg developers on a particular project only work with frontend stacks; components like reverse proxies might not always be viable; etc) aren’t going away any time soon. By providing simple guidance on this pattern, we can simplify the life of many developers while enshrining basic security hygiene in scenarios that would have otherwise be left to their own device. Looking forward for your feedback! B&V On 2/12/21, 12:41, "internet-dra...@ietf.org<mailto:internet-dra...@ietf.org>" <internet-dra...@ietf.org<mailto:internet-dra...@ietf.org>> wrote: A new version of I-D, draft-bertocci-oauth2-tmi-bff-00.txt has been successfully submitted by Vittorio Bertocci and posted to the IETF repository. Name: draft-bertocci-oauth2-tmi-bff Revision: 00 Title: Token Mediating and session Information Backend For Frontend Document date: 2021-02-12 Group: Individual Submission Pages: 16 URL: https://www.ietf.org/archive/id/draft-bertocci-oauth2-tmi-bff-00.txt Status: https://datatracker.ietf.org/doc/draft-bertocci-oauth2-tmi-bff/ Html: https://www.ietf.org/archive/id/draft-bertocci-oauth2-tmi-bff-00.html Htmlized: https://tools.ietf.org/html/draft-bertocci-oauth2-tmi-bff-00 Abstract: This document describes how a JavaScript frontend can delegate access token acquisition to a backend component. In so doing, the frontend can access resource servers directly without taking on the burden of communicating with the authorization server, persisting tokens, and performing operations that are fraught with security challenges when executed in a user agent, but are safe and well proven when executed by a confidential client running on a backend. Please note that it may take a couple of minutes from the time of submission until the htmlized version and diff are available at tools.ietf.org<http://tools.ietf.org>. The IETF Secretariat _______________________________________________ OAuth mailing list OAuth@ietf.org<mailto:OAuth@ietf.org> https://www.ietf.org/mailman/listinfo/oauth ForgeRock values your Privacy<https://www.forgerock.com/your-privacy>_______________________________________________ OAuth mailing list OAuth@ietf.org<mailto:OAuth@ietf.org> https://www.ietf.org/mailman/listinfo/oauth
_______________________________________________ OAuth mailing list OAuth@ietf.org https://www.ietf.org/mailman/listinfo/oauth