Profile completion after e-mail verification - security

I'm building a web application for two different types of users, with a different registration form for each of them. I could split up those forms and send a verification e-mail after the form is validated.
But I'd prefer to have one general small form where the user enters his/her e-mail address and user type. The server then sends a verification e-mail with a link to further complete the profile, depending on the chosen user type.
Now my question is: should I include a password field in the small registration form? I have seen it before on many websites, but I can't see why I would include it. My plan is to make the user choose his/her password on profile completion. Nothing about the user will be stored until he/she completes the profile (I would securely hash the e-mail address with a timestamp in a url).

In general, the developers ask all the details including password at the time of registration and they allow to login using the same password. However, there is an open risk of unverified user can access all or some of the feature of the application. Sometimes the application also provides time frame of 24-72 hours to activate the user account, within this period user can access account with some restrictions.
For sensitive applications, you can ask for the password once the user verify the email address. So, that you are assured about the verified user.
If you are providing the feature to access the user accounts without being verified, make sure that the unverified account users can access the account with restrictions according to your application context.

Related

User management via google login and custom sign-in. How to avoid conflicts when emails are the same?

I'm working on my first MERN fullstack project (an e-commerce demo). I have almost finished the authentication part, but I am having doubts about how to manage the users who have the same registration email both through custom sign-in and google login on the MongoDB database.
While doing various researches, I noticed that one of the methods used is the following:
1- If the email of the user who logs in via google login is already saved in the database as the same user had already registered via traditional sign-up, a new user will not be created in the database, but with both methods of signing -in we will point to the same user already saved with that email.
2- If there are no users saved in the database with that email (as the user logged in for the first time with google login and did not first register traditionally), once the user logged in with google login, it will be saved to the database for the first time.
However, this method presents problems with regard to the second type of users mentioned above.
In fact, if we merge the accounts with the same email on the database, if the user logs in for the first time with google, no password will be saved on the database. Therefore, if the same user decides in the future to log in in the traditional way, he will not be able to do so because he will not be able to fill in the password field.
How to solve this problem?
Usually sites with the "first Google login immediately creates an account" have 2 solutions to this problem:
As part of the "immediately create an account", they directly ask the user to choose a password.
Alternatively, their "Change password" section allows creating a password should there be none yet. Therefore the account is indeed passworld-less at the beginning, but the user can opt to add a password.
For the 2nd solution, there's the small problem that if the user loses access to their Google account and didn't set a password, they're locked out. Rare case which might not be worth looking out for. And perhaps your Customer Service can still help them out.

Is there a way to get a second user to authorize an action without the logged in user seeing their details in the request header?

A strange situation that I am unable to find other people having to deal with. We are using Microsoft AspNetCore.Identity to handle our authentication. Everything is working fine.
The problem is that for a user to perform certain actions, they MUST get another user to 'sign' that action. This act of signing of course requires that other user to use their user name and password to sign the action.
The issue with this is that the other user's details are readily visible in the request payload. So if I am sneaky, I can open the developer tools in my browser (and hide it), then ask my admin to come and sign my action, and when they have gone i can go to the network tab and see their username and login in plain text!
Of course this is all over https but still, we can't allow one user to see another's sensitive information.
How are we to manage to allow a second userB to 'sign' an action for userA while in user A's active session, while removing the capacity for userA to steal userB's credentials??? Any ideas? (Front end is angular.js)
I imagine it's a big rework, but instead of having the "admin" sign the request on the user's machine, the admin could receive a "user A requires this action to be signed, proceed? [ok] [cancel]" on their account, the action would be stored in the database (perhaps temporarily?) & then all of the sensitive information is kept within each user's session with no cross over.
Then the authentication of who is permitted to approve actions can be handled in the backend via standard identity methods.
The user's "Please wait while an admin signs this action" modal (assumption) could then poll an API to determine the status of the action and then proceed once accepted.
I second #justcompile's answer if you need an authorised and authenticated user to sign/confirm the action, more work but the only secure way.
If you just need a second pair of eyes to confirm you could message a private group or slack channel that only "authorised" people have access to with a one-time URL containing a token (that maybe expires after a period of time too).
Assuming admins only access that channel they can follow the link, the app can validate the token and confirm the action.
Saves a second (admin) user logging in on their own machine and the need to build a workflow and UI etc, but again exposes you to risk if nefarious types get access to the channel or the links sent to it.
Depends on your appetite for risk I guess.
another user performs signing action on your local system? and you are sly?
there is no way to protect their password.
use two factor authentication.
The way this would normally be handled is for the user to request an action. This (unsigned) action-request is recorded in the database. The admin user is able to see this unsigned request in their account, and make an (authenticated) request to sign it. The user would be able to see the status of their request, and whether it has been signed yet.

How can I detect if a user already singed with a social account on my website and now wants to create a normal account?

How can I detect if a user already singed with a social account on my website and now wants to create a normal account?
How do I detect the changes?
My personal vision on this:
Let the user sign in with social auth then add the email in the database(mongo) but with no password?
Also when the same user wants to register on the website with the same email but without the social auth and a password, i should redirect him to his profile info from the social auth like username?
An example of what I am talking about:
User signs with google+ on stackoverflow
Then after a while comes back to sign for an account with the same email but a different password.
What is the best way to deal with this situation also from the GDPR standpoint can I use passport for this?
Thank you
When a user registers with social auth, you can also prompt for password (if you wish so) or create an account without it. Next time when a user registers using the same password, you should show an error message 'Email is taken'. In that case, user should receive an automated email that there was an attempt to use his email containing information on how this account was created (e.g. with Google+) - as a reminder.
Using social accounts for auth isn't safe and asking for password (requesting long passwords with special characters, upper/lower case letters) adds a little bit to the overall security. And Two-Factor Authentication takes it to the next level. For most websites, it should be secure enough. Temporarily blocking accounts after a number of unsuccessful attempts is easy to implement and protects from brute forcing.
Alternatively, a user should have an option to restore access to his account by means of requesting a password recovery URL to be sent to the email attached to the account. Then a user is prompted to input password that will be saved for the given account. Thus a user can log in to his account using email/password or the social auth that was used to create it.
With regards to GDRP, a user should be able to:
see what social accounts are connected to the profile and be able to detach them
delete his account (the right to be forgotten)
see what data is stored on him and export it (data portability)
modify data (Right to rectification)
opt-out/in for getting promo emails
manage advertising Cookies
There should be clear T&C provided with a full description of what data is stored, why and for how long.
Additionally, security (2FA, https, etc.)
This is in a nutshell ...

How can I authenticate a user from an email link?

Our web app. sends reports out to users which contain links that point to various items within our web app. (specific records). Users ordinarily have to login to our system to access it, so I am wondering what the best methods are of allowing one of these links to direct the user to the area of the system, without them having to repeatedly login.
When you create a link, you can note which user this link is for. When user clicks on the link, fetch information for the user. Guid in your url would guarantee that no other person can guess path for that users data. This will not technically authenticate a user. But will allow them to see data you need.
First of all it's bad idea to distribute user credentials even to a known email address.
You can generate a unique key for each customer and insert it in query string of included URL in the email. once user clicks on the sent URL, system discovers which user is dealing with and authenticates user. After successful authentication process it really makes sense if you disable the sent unique key.

Handle OAuth signup/login when email exist

Problem assumptions/conditions:
There exists a user with email foo#bar.com (unverified) in the system.
Visitor is not signed into the system (no current session, e.g. new browser).
Visitor signup/login using Google Account, through OAuth (user authorizes).
The system receives callback with uid and the email foo#bar.com [verified by Google].
I see three options here:
A. Sign in the visitor to the existing account with email foo#bar.com. This have some security implications.
B. Ask for a password [assuming there is a password in the system, this may not be the case with multiple OAuth providers] and sign them into existing account if it's valid.
C. Reject the login/signup, say email is already used, encourage user to login before connecting with Google.
What are the security risks with option #A?
What I've come up with myself:
'Anticipation attacks' could be performed, where an attacker anticipates a signup and creates an account on the system before the target does. After the target has signed up using OAuth he will have an active session on that account. Would be defeated by clearing all sessions on the account before doing #A.
When the user logged in through OAuth in Google, you can be sure that the email address you get back from Google really belongs to that user. So the thing you seem to worry about is that the user already known on your system by that email address does not own that email address. That should have been caught by the time he signed up, with an email conversation. But if it isn't, you might want to reset the password and send an email to the genuine user that you did so, and for what reasons. You may also want to log the user out if he is currently logged in. The user can still access his data, but only through his OAuth login session, or by responding to the email. The email should state that it is a precaution, as there is no way to find out if it really is the same person.
An "accidental attack" can happen too:
In step 1, the user who signed up with address foo#bar.com, in fact intended to type fuu#bar.com, but typed a typo: foo instead of fuu.
Now, the Google user signs up with Oauth and foo#bar.com, and in this way hijacks the account of the step-1 user. Accidentally :-) because of a typo made by the step-1 user.
So, either the step-1 user can anticipate-attack the Google user, or the Google user can accidentally-attack the step-1 user. (I cannot think of any other attacks at least not right now.)

Resources