User Auth - oAuth questions - node.js

I have in the past done a hand rolled app that stores a user token on client side $window.sessionStorage.
I have since then realized this is not safe. I am now looking for the most safe, standard way to secure an app that uses a node/express backend api that I will make, and also uses a front end that makes requests to this api such as angular for web or a native mobile app. Plus, whenever I would close the browser, I would have to re-log in because the $window's session storage was wiped out.
From what I've researched thus far, one of the safest ways to date if you're going to handroll it is to store a jwt in an http only secure cookie.
However, I'd kind of like to use a service that already exists, such as oAuth. Couple questions:
1) How safe is oAuth in terms of keeping ownershp of your userbase? What if 3 years from now oAuth just suddenly or slowly dies out? Aren't all my users technically stored on their server? How would I keep my users native to my app?
2) If I'm going to be creating a startup app in the same realm as snapchat, twitter, tumblr, etc... would it be generally recommended to use a service like oAuth to handle my authentication? Of course the future is unknown, but assuming the best, that my app would reach millions of users, would using a service like oAuth still be a smart choice? It seems like once you start using oAuth, there's never any going back to storing your users in your own database a year or two down the road.
Thanks

OAuth is an open standard for authorization.
Maybe you're thinking about Auth0. There are a lot of services that can handle user authorization for you, including Auth0, Stormpath, Apigee, UserApp, AuthRocket or Amazon Cognito. Whichever you choose, make sure that you can get the database from them in case you want to stop using their service. Not everyone explicitly offers an easy way to leave them but if that's important for you then make sure who suits your needs and who doesn't, and base your decision on that.
As for OAuth, see the https://en.wikipedia.org/wiki/OAuth article.
There's a huge list of OAuth providers on Wikipedia but those are services like Twitter, Google or Facebook. In a way you can use one of those services to manage all your logins but as soon as they see you as their competition, you're in trouble. I've heard stories like that.
Some interesting read on the subject:
The dangers of OAuth/Social Login
Signing Me onto Your Accounts through Facebook and Google: a Traffic-Guided Security Study of Commercially Deployed Single-Sign-On Web Services
OpenID Vulnerability report: Data confusion
Social Login Setups – The Good, the Bad and the Ugly

Related

Ways to secure API that do not require authentication, to be called only from one pre-defined consumer

I have currently developed a backend app that has some important functionalities. I want to consume my backend endpoints from my frontend but I want to be sure that only my fronted calls the backend endpoint and no other. Currently anyone that access my web-app can take advantage of the functionalities (I do not require any user registration or authentication).
How can I be safe that my backend is not being called form other possible malicious attackers that may try to steal the functionalities of my backend?
I have read some other posts regarding solutions how to secure a backend app that do not require user authentication but none has a precise and secure way for that. Some say enabling CORS but during my experience I can say that CORS can be manipulated easily with the help of a simple browser plugin. (not speaking about mobile apps that do not consider it at all)
I would really appreciate if I would have some opinions in case of a web-frontend-app, mobile app and other backend systems that would try to call my API and how can I stop them.
Typical front-end authentication would be best (OpenID, ...).
If you want something different, you could check on your backend whether a specific header with a specific token is sent in the query. If it is not then you send back a 401 HTTP code.
This requires that your customers somehow get that token (through some registration process, probably) and then keep it long-term (it can be stored in LocalStorage but can be lost when cleaning up the browser)
OWASP Authentication is a good source of information.

Can this OAuth2 Native app flow be considered secure?

I have an OpenID Connect provider built with IdentityServer4 and ASP.NET Identity, running on let's say: login.example.com.
I have a SPA application running on let's say spa.example.com, that already uses my OpenID Connect provider to authenticate users through login.example.com and authorize them to access the SPA.
I have a mobile app (native on both platforms) that is using a custom authentication system at the moment.
I thought it would be nice to get rid of the custom auth system, and instead allow my users to log-in with the same account they use on the SPA, by using my OpenID provider.
So I started by looking on the OpenID connect website and also re-reading the RFC6749, after a few google searches I realized that was a common problem and I found RFC8252 (OAuth2 for Native clients), also Client Dynamic Registration (RFC7591) and PKCE (RFC7636).
I scratched my head about the fact that it was no longer possible to store any kind of "secret" on the client/third-party (the native apps) as it could become compromised.
I disscussed the topic with some co-workers and we came out with the following set-up:
Associate a domain let's say app.example.com to my mobile app by using Apple Universal Links and Android App Links.
Use an AuthenticationCode flow for both clients and enforce them to use PKCE.
Use a redirect_uri on the app associated domain say: https://app.example.com/openid
Make the user always consent to log-in into the application after log-in, because neither iOS or Android would bring back the application by doing an automatic redirect, it has to be the user who manually clicks the universal/app link every time.
I used AppAuth library on both apps and everything is working just fine right now on test, but I'm wondering:
Do you think this is a secure way to prevent that anyone with the right skills could impersonate my apps or by any other means get unauthorized access to my APIs? What is the current best practice on achieving this?
Is there any way to avoid having the user to always "consent" (having them to actually tap the universal/app link).
I also noted that Facebook uses their application as a kind of authorization server itself, so when I tap "sing-in with facebook" on an application I get to a facebook page that asks me if I would like to" launch the application to perform log-in". I would like to know how can I achieve something like this, to allow my users login to the SPA on a phone by using my application if installed, as facebook does with theirs.
I thought it would be nice to get rid of the custom auth system, and instead allow my users to log-in with the same account they use on the SPA, by using my OpenID provider.
This is what OAuth 2.0 and OpenID Connect provides you. The ability to use single user identity among different services. So this is the correct approach .!
it was no longer possible to store any kind of "secret" on the client/third-party (the native apps) as it could become compromised
Correct. From OAuth 2.0 specification perspective, these are called public clients. They are not recommended to have client secrets associated to them. Instead, authorization code, application ID and Redirect URL is used to validate token request in identity provider. This makes authorization code a valuable secret.!
Associate a domain let's say app.example.com to my mobile app by using Apple Universal Links and Android App Links.
Not a mobile expert. But yes, custom URL domains are the way to handle redirect for OAuth and OpenID Connect.
Also usage of PKCE is the correct approach. Hence redirect occur in the browser (user agent) there can be malicious parties which can obtain the authorization code. PKCE avoid this by introducing a secret that will not get exposed to user agent (browser). Secret is only used in token request (direct HTTP communication) thus is secure.
Q1
Using authorization code flow with PKCE is a standard best practice recommended by OAuth specifications. This is valid for OpenID Connect as well (hence it's built on OAuth 2.0)
One thing to note is that, if you believe PKCE secret can be exploited, then it literally means device is compromised. Think about extracting secret from OS memory. that means system is compromised (virus/ keylogger or what ever we call them). In such case end user and your application has more things to be worried about.
Also, I believe this is for a business application. If that's the case your clients will definitely have security best practice guide for their devices. For example installation of virus guards and restrictions of application installation. To prevent attacks mentioned above, we will have to rely on such security establishments. OAuth 2.0 alone is not secure .! Thats's why there are best practice guides(RFC68129) and policies.
Q2
Not clear on this. Consent page is presented from Identity Provider. So it will be a configuration of that system.
Q3
Well, Identity Provider can maintain a SSO session in the browser. Login page is present on that browser. So most of the time, if app uses the same browser, users should be able to use SPA without a login.
The threat here comes from someone actually installing a malicious app on their device that could indeed impersonate your app. PKCE prevents another app from intercepting legitimate sign in requests initiated from your app so the standard approach is about as safe as you can make it. Forcing the user to sign in/consent every time should help a bit to make them take note of what is going on.
From a UX PoV I think it makes a lot of sense to minimize the occasions when the browser-based sign in flow is used. I'd leverage the security features of the platform (e.g. secure enclave on iOS) and keep a refresh token in there once the user has signed in interactively and then they can sign in using their PIN, finger print or face etc.

Restrict usage of Heroku app by Authentication?

I developed my Heroku app that exposes APIs only (no UI) and it works fine.
But how can I restrict the APIs to certain authorized/authenticated users only?
I absolutely need an authentication layer to protect the app APIs and prevent unauthorized accesses. A sort of login(user, psw) call to use before an external system can start invoking my API.
But I don't find any reference in the docs, it only says that these are the main security best practices:
Heroku SSL
Force the use of HTTPS
Trusted IP Range
Any idea?
That's something you'll need to implement at the application layer and not something that Heroku provides. At it's simplest you could implement basic auth in your app so that the user would pass them with their request, a more complex solution would involve user accounts and oauth etc etc.
You could implement all the authentication logic directly in your app.
Alternatively, take a look Auth0, which basically provides you with authentication and identity management as a service. You can easily add Auth0 to your Heroku app as a free add-on via the Heroku Elements marketplace.
They have lots of different use-cases and associated walk-throughs, and they offer a very generous free-tier.
From your requirements, it sounds like you might want to look at Auth0 Machine to Machine applications, using the OAuth2 Client Credentials Grant. With that, your external system(s) would basically need to authenticate with Auth0 using a Client Id and Client Secret (that you could generate in Auth0 and supply to them). Then, they would access your API with a JWT that you could easily validate in your app (Auth0 will provide you with generated code in many different languages for you to do that very easily). Your API will then reject requests without a valid JWT (by sending a "401 Unauthorized" response).
This may all sound a little intimidating at first, but it's really worth going through the relevant Auth0 "quickstart". They really go out of their way to try to make it as easy as possible!

which authentiation to use

Our application is currently written in .NET Framework + Razor, and traditional Membership authentication.
I am trying to modernize it, so I stawted to work on a .net core + react solution, but it has to cooperate with the existing application.
So currently, we have the old monolit, and an other .net core apis, called by react. The react is embedded inside the Razor.
Now I need to choose what authentication to use. I guess membership and other session based authentications can't be used, because there are multiple apps in multiple domains. So I need tokens.
I am not really sure about which solution can or should I use. I know buzzwords like bearer token, .NET Identity, OAuth + OpenId, but can I use any of them in this situation, to use it to protect the API and as well for the "traditional" razor app?
And where should I store the token? Should I store it in a session of the razor app, and pass it to the React too?
I need a solution where user credentials are stored in our own database, not something list Google's or Facebook's single sign on.
Is there a good tutorial for this?
You're asking for a lot here. I would suggest brushing up on this topic from the beginning. If you only know the buzz words you won't get anywhere quick. I can give some quick advice but if you aren't familiar with the basics this won't really help. There is no quick solution for your answer.
I would suggest authentication on the edge of the application to achieve a nice separation to work with the existing app. I would create a light weight method that receives the request from the client and gives the api gateway proof of the user identity in a way the API can verify. I would go with OAuth and OpenId Connect protocol to achieve this separation. Also, take a look at IdentityServer, it is an open source product that makes it easy to implement single sign-on and access control(Authentication) in web applications and HTTP APIs.
OpenId Connect to authenticate users
OAuth to limit collaboration for these light weight method calls
JSON Web Tokens (JWTs) for user identities
Now the problem with this solution is that there is a high level of trust between this light weight method call and the rest of the system. The principle of defense in depth would suggest to implement a layering strategy, so that if this layer is compromised another layer is there as the next line of defense. I'll leave the rest up to you.

Implement a secured and production ready authentication system in a Node.js server without being tied to a third-party provider

I am used to develop web apps using the Meteor JavaScript framework, which handles authentication. I am now developing for the first time a web app using a Node.js (Express) + GraphQL stack on the backend, with React on the frontend, so I have to handle authentication myself.
I read a lot of things about it, and I like the idea of token based authentication. I am thinking about using JWT, so I don't have to deal with sessions.
I know there are a lot of tutorials, but each one always has a sort of disclaimer like : "this tutorial is not production ready, use it for educational purposes only...". Every time I read something about authentication, it seems to be something so difficult to implement that I shouldn't implement it myself. But I don't want to use services providers like AWS Cognito, Google Cloud Platform because I want to keep my users data in my own system and database. I don't want to be tied to a third party provider.
I know how to generate jwt tokens, refresh tokens, how to verify them, etc... I am able to develop a working auth system, but I am never sure I do it in a secure and production ready way because of all those comments I can read on the Internet.
So, what would you recommend to implement a secured and production ready authentication system in a Node.js server without being tied to a third-party provider. Do you know any complete tutorial or documentation about it?
There are several approaches to implement authentication for an application.
Use a identity server manage by you
Use a fully manage service for authentication.
Use authentication middleware.
Write your own authentication solution.
If you are afraid in vender locking I would suggest to use an authentication middleware like PassportJS which will facilitate the abstraction of authentication strategy with its implementation.
On the otherhand writing your custom authentication can be challenging in terms of security, specially finding snd fixing these vulnerabilities.

Resources