How to use email authentication in Firebase using Node.js - node.js

I'm trying to use the Firebase authentication service by email and password for my App.
I've noticed there are two SDKs, Client and Admin, both of them have methods to create a new user.
I've also noticed that only the client SDK has method to validate the user email and to return the new user's token after creation.
The two SDKs made me confuse regarding the way I should use this service so I have few questions:
Should I create a "signup" route in my server and use the Admin SDK or I should use the client SDK?
If I use the client SDK for signing it should be in the server side or in the client side?
How I can verify the user email using Firebase "Email address verification" template?
If someone can give me some guidelines.

The Firebase Admin SDKs are meant to run in a trusted environment, such as your development machine, a server you control, or Cloud Functions. They run with elevated, administrative privileges, based on a service account that you specify when initializing them. As such, there is no way to sign a user in with an Admin SDK, even though they indeed (as you noted) have the ability to create user accounts.
The client-side Node.js SDK is meant to be used in non-trusted environments, like for example IoT setups. This SDK indeed allows you to sign in as a specific user, and this information is then passed when you call other Firebase APIs from within the Node app.
Which of the two you should use depends on the use-case, which you're unfortunately not describing. Without that, the above is the best guidance we can give: if your code runs in a trusted environment, use the Admin SDK; otherwise use the client-side SDK.

Related

How to secure client -> backend on firebase NodeJS

I'm building a bot hosted on Azure and using firebase for cloud functions (ie proactive messaging, collating data etc.) and for cloud firestore db.
Sorry as I'm a bit new to security and please feel free to just link to any useful resources on the below.
Within my bot code I'm using the admin SDK to access firebase. The bot will have no created users. Firestore rules therefore block read and write access to everyone (as admin SDK still has full access).
I have a couple of questions about security:
Is using the admin SDK in this manner (on the bot side) fine? It looks a bit mixed on the firebase documentation - ie https://firebase.googleblog.com/2019/03/firebase-security-rules-admin-sdk-tips.html mentions only using these in trusted environments, which I think the bot should be?
Secondly I am trying to send messages from cloud functions to the bot itself. This will just be a post with no sensitive data attached but I would like to authenticate this on the bot side to check it is from the backend. Is there a way to use firebase to do this (ie authenticating on client?). How else can I do this? I've been a bit confused reading about JWTs and encoding etc.
Thanks
Is using the admin SDK in this manner (on the bot side) fine?
It's totally fine. You don't have security rules there but Cloud functions (or servers) are secure environments so no one can reverse engineer that. You should validate the incoming data yourself. If I assume you are using Discord.JS, then you can just read ID of author and authorize the user:
const {id} = message.author
// use this ID as an identifier
You don't have to worry about the ID being false as it's not being passed by any client. Just make sure you fetch resources of that specific user only.
I am trying to send messages from cloud functions to the bot itself. I would like to authenticate this on the bot side to check it is from the backend
You don't need to validate that. Anyone can send message through your bot only if they get your bot's token which is a secret on server/cloud function. You must make sure only you have it.

What is the best way to use aws congito in javascript/nodejs app?

I am building a web app where front end of plain javascript, css and html. Services are hosted(EC2) in nodejs layer connecting with database. I was looking to use aws cognito as AWS is preferred cloud solution for user management for standard functions such as signup, sign in, mfa, forgot pwd, sign out and so on. My question is: Is it good solution to build custom UI where username and pwd are accepted and sent to nodejs layer(on EC2) over https and then nodejs layer can connect to cognito via nodejs low level api from sdk to execute required functions such as signup, signin, mfa and return required data? I am not web app security expert, so please elaborate if this is not even a option.
It is certainly an option but not a more secure one as you are transferring user credentials over HTTPS in both cases. You should avoid sending any user credentials to your backend. Let the frontend send user credentials to cognito and exchange it for temporary tokens. Cognito provides its own hosted GUI which handles all the standard cognito functions that you mentioned above.

Signing into my Gitlab CE installation with my app's login

I have a nodejs webapp with many users with a custom login process. I would like gitlab to accept that authentication and not force users to create a new app. What is the best way to accomplish this?
I would go for OAuth 2.0 Single Sign On (SSO). Below you can find the architecture diagram taken from here. As you can see the client is redirected to log in in the OAuth2 provider to get a valid token for authentication. The OAuth2 server must be configured for the application requesting access including the secret, the client id and the callback URL.
You can configure GitLab CE to sign in with almost any OAuth2 provider. Only be careful with the limitations:
It can only be used for Single Sign on, and will not provide any other access granted by any OAuth provider (importing projects or users, etc)
It only supports the Authorization Grant flow (most common for client-server applications, like GitLab)
It is not able to fetch user information from more than one URL
It has not been tested with user information formats other than JSON
You also need to configure your node js web application as an OAuth2 server. There are npm availables with the source code here.
Recommendation
I would install some open source Identity Management to separate the user management from your webapp, provides better integration with other third parties and forget about encryption and other stuff you need to take care in your webapp. There are multiple options such as KeyCloak for instance.
You have to define a dedicated user , and use the private_token of this user to login for ALL users that will use your application.
The restricition would imply all users will have the same rights ....
The other solution is to use the Private Token of the user at login. In this case , only the rights of these particular users will be used.

Azure Active Directory authentication from native application without requiring user login

Here is what I am trying to accomplish -
A native application which is going to be run on a system where I cannot involve the user to login but I want to access web services secured behind AAD using a bearer token. There are two options -
Use a certificate based flow (which I want to avoid for few reasons
specific to my project)
Use the client secret
Issue I am running into:
When I call acquiretokenasync using the Native AAD application's client ID and a client credential built using the AAD web application's (which the native app has permissions to) client secret, I get the following error -
{"AADSTS70002: Error validating credentials. AADSTS50012: Invalid client secret is provided.\r\nTrace ID: f52cc954-2674-47ee-9a7b-094451b05c7c\r\nCorrelation ID: 1ba8ac64-cc4a-4ff7-83d6-a333504459d6\r\nTimestamp: 2016-08-20 01:45:08Z"}
So given that the client secret is indeed correct (which I am positive about), what could be the real issue behind this error?
Thanks in advance for your help :)
You can't use the native application client ID and web application client credential (client secret). The native application has no associated secret, only the web application has. Native applications are assumed to run on insecure hosts, such as the desktops and smartphones. Client secrets would become too fragile.
For more information on how to authenticate a native application and access resources, take a look at these articles:
Authentication Scenarios - Native Application to Web API
Developing Native Client Applications
There are two types of application which we can register in Azure Active Directory.
Select Native for client applications that are installed locally on
a device. This setting is used for OAuth public native clients.
Select Web app/API for client applications and resource/API applications that are installed on a secure server. This setting is
used for OAuth confidential web clients and public user-agent-based
clients. The same application can also expose both a client and
resource/API.
Native applications are public clients in OAuth2 parlance. Those apps are meant to run on a device and aren't trusted to maintain a secret - hence, their entry in the directory does not have the corresponding property. Without a secret, there is no way to assert the identity of the app - hence such apps cannot gain app level permissions and the portal UX reflects that. Conversely web apps are, again in OAuth2 parlance, confidential clients. They can get delegated tokens for their users, but they can also use client credentials to get tokens as themselves. Native apps can obtain tokens for the user via the OAuth2 authorization grant.
Refer this article further.

How to restrict Firebase data modification?

Firebase provides database back-end so that developers can focus on the client side code.
So if someone takes my firebase uri (for example, https://firebaseinstance.firebaseio.com) then develop on it locally.
Then, would they be able to create another app off my Firebase instance, signup and authenticate themselves to read all data of my Firebase app?
#Frank van Puffelen,
You mentioned the phishing attack. There actually is a way to secure for that.
If you login to your googleAPIs API Manager console, you have an option to lock down which HTTP referrer your app will accept request from.
visit https://console.developers.google.com/apis
Go to your firebase project
Go to credentials
Under API keys, select the Browser key associated with your firebase project (should have the same key as the API key you use to initialize your firebase app.)
Under "Accept requests from these HTTP referrers (web sites), simply add the URL of your app.
This should only allow the whitelisted domain to use your app.
This is also described here in the firebase launch-checklist here: https://firebase.google.com/support/guides/launch-checklist
Perhaps the firebase documentation could make this more visible or automatically lock down the domain by default and require users to allow access?
The fact that someone knows your URL is not a security risk.
For example: I have no problem telling you that my bank hosts its web site at bankofamerica.com and it speaks the HTTP protocol there. Unless you also know the credentials I use to access that site, knowing the URL doesn't do you any good.
To secure your data, your database should be protected with:
validation rules that ensure all data adheres to a structure that you want
authorization rules to ensure that each bit of data can only be read and modified by the authorized users
This is all covered in the Firebase documentation on Security & Rules, which I highly recommend.
With these security rules in place, the only way somebody else's app can access the data in your database is if they copy the functionality of your application, have the users sign in to their app instead of yours and sign in/read from/write to your database; essentially a phishing attack. In that case there is no security problem in the database, although it's probably time to get some authorities involved.
Update May 2021: Thanks to the new feature called Firebase App Check, it is now actually possible to limit access to your Realtime Database to only those coming from iOS, Android and Web apps that are registered in your Firebase project.
You'll typically want to combine this with the user authentication based security described above, so that you have another shield against abusive users that do use your app.
By combining App Check with security rules you have both broad protection against abuse, and fine gained control over what data each user can access.
Regarding the Auth white-listing for mobile apps, where the domain name is not applicable, Firebase has
SHA1 fingerprint for Android apps and
App Store ID and Bundle ID and Team ID (if necessary) for your iOS apps
which you will have to configure in the Firebase console.
With this protection, since validation is not just if someone has a valid API key, Auth domain, etc, but also, is it coming from our authorized apps and domain name/HTTP referrer in case of Web.
That said, we don't have to worry if these API keys and other connection params are exposed to others.
For more info, https://firebase.google.com/support/guides/launch-checklist

Resources