Email verification theory - Looking for general guides - javascript

This is just a general question on how Email verification can commonly be carried out in a secure way in web apps (I am targeting nodejs based frameworks, but I don't want any framework specific code, just the steps). I can't seem to find any general guides on the best practices for email verification, so asking here :)
What I have in mind is the following
When a user signs up, create a random token and store it in a DB table along with a field token_created_at that tells when the token is created. Then send a verification mail with that token and the user id.
When the user clicks on the link, the route get's the token and the id. We can then lookup the table to verify the token for that id. If when the route is clicked is already past the token_created_at field, we simply say they need to generate a new verification URL. If it matches, the account is verified.
This is what I have in mind ? Is this a right approach for email verification ?
Thanks in advance ! :)

Related

How to hide manager password from user on web app?

I am creating a web app on a LAMP stack where I have users with their own logins and passwords. Typical users of the application have limits on operations. For example they cannot approve an order over $5000. If there is an order over $5000, they have to get a manager to come to their desk and enter in his/her username and password to approve the order.
I can easily create a form for the manager to enter his/her credentials into an HTML password input, but here is the problem. When the manager enters their credentials into the browser, the password field is hidden from the user. But when the form is submitted, the password is transmitted in clear text. In theory, a user could get the password by using F12 or by looking at the POST.
I wanted to hash the passwords before submitting the form, but the problem is that PHP stores the passwords using BCRYPT, and javascript can only digest with SHA.
So basically my question is. How can I ensure that the manager password is hidden from the user and they cannot get it?
javascript can only digest with SHA
I'm sure you could find implementations of bcrypt in client-side Javascript…
That won't really solve your problem though. If the password is hashed client-side, then the server cannot hash it further and needs to accept the hash as is to compare it directly to the stored hash. Which in essence means, the hash becomes the password, so the user could send the same hash again to the server and pass the test.
Further, bcrypt should be using random salts, so in order to recreate the same hash, the server would need to send the used salt to the client so it can create the correct hash. This is all madness.
Instead, you probably want some sort of challenge protocol. The idea being that the value the client sends to the server is different every time, so even if the attacker sees the value, they cannot reuse it. For this purpose the server would make up some random value, send that to the client, the client calculates some answer given the password and the random value, and sends only that to the server. A rough overview of different algorithm can be found at MDN and elsewhere.
This still won't solve the issue of the attacker installing some keyboard logger, or simply overriding some Javascript handler to log the entered password to the console before answering the challenge. In the end, if you don't trust the attacker and the attacker has full control over the system the password is entered into, there's nothing much you can do.

How to create a user verification hash/token?

So basically I have a registration endpoint in my express app. I am trying to make it so that users have to verify their email prior to their account being activated(the account is deactivated by default). I have everything set up, the only thing that is confusing me is how to create a hash that I can send as part of a link that a user clicks to verify their account. I have thought of using JWT and just creating a token and sending that along, however this seems a bit overkill. So my question is, is using JWT for this purpose a solid solution or is there a better alternative? If so, what is that alternative?
Thank you!
This question can lead to opinionated answers and I will try to give you one.
If all you want to do is verify email, then JWT seems like an overkill to me. Just create a hash using nanoid, shortid package from npm or using standard nodejs crypto.
Save the hash to DB record of the user, send out the link as in
https://my.server.com/whatever-path-you choose/${your-generated-hash}
This should be handled by the server where the endpoint:
looks up and verifies the user by the hash
enables the account
burns the hash (i.e. delete the hash from DB)
redirects to the page of your liking, most probably login page.
My 2 cents.
do a token that includes user id and a secret value to make it more safe but don't push your code online to hide this secret
also then put it as a cookie
another way without jwt is using res.locals

Is there a way to verify a signed up email?

I'm using react-native and firebase for my login/signup system.
I want to add the feature that when you signup with a mail and password you receive first a mail that you need to confirm before you can use that account for logging in.
I searched for documentation about it but i couldnt find anything that really fits to the feature.
This have been covered quite a few times before, so I recommend searching for previous answers. For example: https://stackoverflow.com/search?q=%5Bfirebase-authentication%5D+verified+before+sign+in
But nowadays I'd probably use an email link to sign in to Firebase, since that automatically ensures the email account exists.
I didn't work a lot with firebase but iirc there was a way to return a token when signing up and sending it when signing in later.
There is also a way that doesn't involve tokens which is to add a boolean to your DB and send an email with a certain randomly generated id. When the user clicks on the link in the email, you could then send that key to the backend and set the boolean to true.
This approach works as I personally tried it before but it needs effort to make.

firebase authentification one user

I am creating a login for my chrome extension where I am going to be using the firebase email and password.
I am going to be putting the create User firebase code on my website and when someone can enter in there email and the script will create a random set of digits and set that as the password. It will then email that password to the user and the user uses the email he entered and the random digit password he received via email to login.
My question is If a user signs up and then logs in with his email and password. Whats to stop him from giving that email and password to his friend and he also logs in. I want to control the amount of users I allow within my chrome extension and only want the person who logged in to use the chrome extension (I want so the login can only be used once) Is this possible for firebase or not?
Also If anyone knows a simpler method than that I described above with sending the email please let me know becuase to do that above I have to create something that sends an email and creates the password.
I would also like to know if firebase has something where I can set a date on a user and after that date passes the user is logged out and has to register again.
But my main question is that if a user where to register if he has the ability to share the login with his friend or if only he can use it.
I really appreciate your reply and help on my issue in advance Thanks A lot.
You'll likely have to do this from the server side (e.g. in a Cloud Function).
One option would be to use the session management features in the auth admin SDK: https://firebase.google.com/docs/auth/admin/manage-sessions - if you report back from the extension with the logged in user, you can revoke access for users who are seen in too many places at the same time. This limit might not be 1 - you may want to allow your users to log in on multiple machines at once.
For even more control, look at the option for managing your own session cookie: https://firebase.google.com/docs/auth/admin/manage-cookies - this allows you to set your own expiry and control the logged in state more granularly.

Remove a user from firebase

I am trying to remove a user programatically from my firebase. The method removeuser takes 2 arguments, email and password. Now email is not hard to find out since this is stored in the auth variable + I am adding it in my database when a user is created. However, how am I supposed to find out the password from the user?
When I create a user I do add the generated md5_hash information with this user in my database. However, I can not convert this value back to the real password.
I also obviously do not want to store the real password in the database since this is just asking for problems.
So I'm wondering, is there anything overly obvious I am missing here on how to remove a user programatically from the database, with his password? (Why do I actually even need his password to remove him?)
EDIT: To clarify, I am only allowing an admin to delete users, so he has a list of every user that has been created in my firebase. Having a user delete his own user account is still not so easy since (I presume) the firebase hashing algorithm is not public, so there's no way for me to check if he did input the correct password.
Firebase Simple Login is a service built on-top of Firebase Custom Login, and provides useful primitives for authenticating users via common means.
By design, Firebase Simple Login does not give you access to the users' passwords programmatically, as it only increases the risk that they are not handled or stored securely. Today, the only two methods that can be used to remove an email / password hash mapping is either via the client API using the email and password, or via the admin panel at https://<YOUR-FIREBASE>.firebaseio.com.
Keep in mind that when using email / password login, Firebase Simple Login simply creates a new mapping between an email address and a password hash, but does not store any information in your Firebase. Also note that there is no way to "blacklist" a user id, so if you remove the mapping, the user could re-create it.
If you want to ban / block users, a better approach would be to create a new list in Firebase of your "blacklisted" users, and then use security rules to ensure that that user is in the list (i.e. user is blocked if root.child('blocked-users').hasChild(auth.uid)).

Categories

Resources