Designing an new user confirmation (verify via email) - asp.net

I am developing an ASP.Net application that will need to verify that the user is legit and not a spam. Once the new user enters their first name, last name, email address, my application will send an email to verify the user's authenticity. The email would conatin a link that would confirm the users account.
I am looking help on what the logic is behind the email link. Once the user clicks the link, what happens?
I have had a website that has used Captcha, and not had much luck stopping spam (I know you can't stop 100% spam) similar to this Stopping spammers from creating accounts (reCaptcha not doing the trick)

As Rook has pointed out below, the simplest way is to use Captcha.
If you need to verify the email as well though, see below.
You could generate an approval GUID and pass it to the email URL which would mark the User as Active.
For example, add a column called ApprovalID to the users table and generate a new GUID when the user registers, i.e.
You should mark the user as inactive at this stage.
Example Guid 3F2504E0-4F89-11D3-9A0C-0305E82C3301
Then pass the User Id and GUID in the email body
Verify your account
Then a simple page verify.aspx
Code Behind
string UserId = Request[UserId].ToString(); // You can parse these as Guids
string ApprovalId = Request[ApprovalId].ToString();
TODO:
// Get user from database
// Match QueryString ApprovalId to Column ApprovalId
// Ask user to Log In
// Set user as active

Sending a confirmation link doesn't do anything to stop spam. Emailing someone a link with a Cryptographic Nonce just insures that they can receive email, bots can also receive email.
The best way stop spam is by using capthca, and I recocmend using reCapthca. You should prompt the user with a capthca when a user signs up for your service.

Related

Set password and verify email in one step

Lots of questions about email verification here on SO, but none seem to cover my scenario.
We would like to add users ourselves after an intake meeting. Our representative has a form to enter some details like company name, VAT number, contact data (which contains an email field), ... This data is saved in Firestore.
After this, an email is sent to the supplied email address which contains a link that takes the user to a form where his/her email address is displayed with a password and a password confirmation input field. When submitting this field, the user is created.
But now the user receives an email asking to confirm their email address. I assume, for security and privacy reasons, there's no way I can set the user's email address as verified.
I've looked at customizing the verification email, but that doesn't seem to solve my problem.
Creating the user with a random password after the intake meeting also doesn't seem to be a solution, as the user still has to verify and then reset the password in 2 steps. Or can I somehow redirect after the email verification to the 'set password' page? That would be an acceptable solution.
Is there any way to achieve the desired flow described above?
As a general workflow, you could achieve this using a Cloud Function along with either database system. You can also make use of App Check to further secure this process.
Representative adds base user information in their portal. Store the data securely in the database of your choice.
Send the user an invite email containing a short-lived verification token linked with the email added by the representative (this could be generated and fired off using an onCreate Cloud Function once the invitee's data is added to the database). This token should follow some standard like JWT so you can deserialize the contained email address or be exchangeable for the underlying email address.
When user clicks/copies the link to their browser, present them with an input form asking for the desired email and password. Note: the email field should be editable! The rep may have used an email the new user doesn't want to use with your platform.
If the token is still valid and not consumed, continue with the next steps.
If the token has expired and not consumed, send another email to reconfirm their email and restart this step.
If the token is already consumed, show an error and don't continue.
Submit the email, password and emailed token to your backend via a Callable Cloud Function.
Sign the user in using the authentication token returned by the function on success. Show an error otherwise.
In the callable function for creating the user:
Confirm the request comes from your app (if using App Check)
Confirm the validity of the emailed token
Pull the data the representative entered from the database linked with the emailed token's original email address.
Using that data, the updated email, the new password, and emailVerified=true, call the createUser API.
Using the User ID from the returned UserRecord, create the user's profile data in the database and also create a Custom Authentication Token.
Once their data has been created and the token generated, return the authentication token as the result of the request.

How to login a new user by default after mail Invite in Meteor?

I have a requirement where I need to log in a new user to a Meteor application by default, and take the user to the reset password route after that.
I looked into this documentation, but I don't think it would apply here, because the password is not known. Here's my use case in detail :-
A user invites another new user by providing the invited user's email ID. The application sends email invite to the user, asking them to be taken to a route which normally requires logging into the application.
The new user who receives the email invite, is not yet signed up with the application. So, they need to pick a password to log in to the invited area of the application.
Currently, I am using the meteor-useraccounts:core package; to trigger the resetPasswd route for FlowRouter. Using the onSubmitHook, one can redirect the user to the proper location after successful reset of the password.
However, I am not able to figure out how to first log in the user automatically. Because if the user is not logged in, the reset password page won't open. Instead, it would show some error, indicating unauthorized action.
How could a link be sent via mail to the invited user, which would automatically log in the user?
I looked into this documentation, but I don't think it would apply
here, because the password is not known.
That is right, and because of that, in order to achieve that you have to create an account for that e-mail at the time the user enters a link sent by e-mail. Or create the account at time of invitation.
So possible solutions:
1) create an account for an e-mail provided in query (http://app/login?email=blabla#google.com) for a route, random password, reset password e-mail sent immediately after the login. (create login automatically login the user). That would also required some security key, so that no-one could create lots of accounts on different e-mail addresses.
2) create account at time of invitation, take random password and send it as a query parameter of the link sent to the invited user. When user enters the site, you take that password (and e-mail) and login him with that, and immediately send reset password for that e-mail

About Email Verification - What methods

I just wanted to ask the procedure of email verification, whats the best method. So far i have a class that stores the information from the register.aspx form, then i send out an email to the user, but what should i send him, should i send the user a guid?.
Also my membership class that stores the register data is stored in a session, is this a good idea, becuase if the user session times out then the membership class will be nothing and the user will be prompted to register again in a Session Timeout webpage, is this a good method?
But what if i send the user a guid and then store the user data to the database with the guid and then check the email guid with the corresponding user guid in the database, what should i do?
Also i have a Regular expression that checks that the email is valid, its not that good yet and i havent tested it properly, is there free email verification api's out there?
I am using ASP.NET VB.
Here is what I would do:
1) Ask for user's email
2) Validate the email using Regex
3) If valid, create a Timestamp (DateTime.Now), append with user's Id and any other useful information that I need. We can use some appropriate delimiters.
4) Encrypt the data and build a URL with the encrypted token and email to user
5) When user clicks, decrypt the information, check the timestamp (perhaps there is a timeout required) and use user's Id to get its data from database.
This is in addition to the already accepted answer - I wouldn't limit the email validation to checking the Regex syntax only.
There's a free email verification API I've been using that checks a number of factors, including syntax, typos, SMTP & MX-Records (which verifies the actual existence of the email address), if its a free or disposable email, etc.
They're offering a thousand monthly requests for free - mailboxlayer.com
Save the data to the database, including the GUID. Set the status of the record to "inactive". Send the email, with a link back that includes the GUID. When the link is clicked, set the registration record to "active". Only "active" records can log in.
You can't effectively validate an email address with a regexp - search this site for explanations of why.
In .Net you should validate email addresses like this. See this question for details.
MailAddress address = new MailAddress(input)
This throws an exception if the email address is invalid.

Best way of doing code for "Forgotten Password"

net website, i would like to implement forget password. I am using following steps
Form having input box for login Id and email Id and CAPTCHA
when user enter details and submit, at backend after validation new password is generated and replaced old password at database.
New passowrd is send to user at email.
Please help me whether i am doing right or not?
Is there any other secure mechanism for the same?
[EDIT]
Thanks, i got your reply. Really this is a secure mechanism. But here i have few doubt
What message should i shown to user when he enter loginId and email address at forgotten password page?
Whether message would be same for valid user and mallicious user?
Advantage of using CSRF token? Any help / link
When user click on link then what should i do; because as i guess user should automatically loggin into their account -then after that i have 2 choice (first) send new password automatically to user (second) new form will shown to user where user will enetr old password and new password twice?
Please help?
I can see why you'd want a CAPTCHA, but I'd take a different approach.
When a password reset is requested check that a reset has not already been requested for that account within the last X minutes. If a password has already been requested ignore the reset request.
Check the IP requesting the password reset. If that IP has requested a password reset in the last Y minutes ignore the request.
If the checks in 1 & 2 pass check the account exists. If it doesn't ignore the request.
If we've gotten this far generate a one time token, which expires in Z minutes and a password reset URL which encompasses this token. Email this to the registered email address. When the URL is loaded prompt for a new password and reset.
For those who believe that you should tell the user where the email has gone I strongly disagree. This is "information leakage", even if you do limit it to the domain name. For example say I've registered on JeffAtwoodEatsBabies.com as blowdart. If Jeff had requested a password reset for me and you showed the registration domain then he'd see idunno.org. This is my personal domain and thus Jeff would know the blowdart user is, in fact, me. This is a bad bad thing. I should not have to register using hotmail or gmail or whatever in order to protect myself from your code showing an email domain to all and sundry.
In addition you shouldn't be showing error messages at all. No matter what happens, a username is not actually registered, or too many requests have been made or the sky has fallen you should be telling the user that the password reset procedure has started. Informing a user that an account doesn't exist is more information leakage.
One final thing you could do is add a CSRF token to the reset request page, so it cannot be driven from other web sites.
Followup
So to answer your further questions.
What message you show is up to you. "Instructions for resetting your password have been emailed to the registered email for this account" is one idea, but really it's down to your audience.
Already addressed above.
Wikipedia is a good starting point. How you do it depends on your platform and is a complete other question! For ASP.NET you could look at my codeplex project, http://anticsrf.codeplex.com or look at ViewStateUserKey.
When the link is clicked I would first validate the token in the URL against the username it's being applied to then I would either allow the user to enter a new password, or generate a new one and email it. You can't prompt for the old one, as the whole point is the user has forgotten it!
There are many ways this has been implemented. As you said, generating a new password and sending it to the registered email address is one method. I wouldn't suggest you go that route though, as my password would be reset everytime somebody tried guessing my password.
Instead, the best thing I've seen to date is simply emailing the registered email with a link that will begin a password reset process. You may even let the user know which email address to check by showing a masked version of their email address used in registration:
An email was sent to ********#hotmail.com. Please check your inbox to continue.
Be sure to keep in consideration those of us who may forget which email address were registered with - typically a few security questions are a great way to make that information available.
I've done that recently. When the user enters their username or email address, we generate a unique token and email it to them as part of a link. Upon receipt of that email, they click the link, and are automatically logged in, taken to the my account screen, and prompted to reset their password.
Of course, this relies 100% on the security of the email client, but it's hard to beat from a usability perspective.
You shoud check the answer to the question : Can anyone provide references for implementing web application self password reset mechanisms properly? from D.W. on security.stackexchange.
It is the most complete answer I found on the subject. I also suggest you to read this article : Everything you ever wanted to know about building a secure password reset feature

Securing temporary passwords sent through e-mail to users?

I have a simple web application set up where admins can create users. Users do not create themselves. All an admin has to do is enter a username and an e-mail and a temporary password is sent to the user for them to login. This e-mail is sent in plain text format. If the user is logging on for the first time, they are required to change their password and enter a security question and answer. The user obviously has to know their temporary password in order to login for the first time and this is the only way I know of letting them know (through e-mail). The other option would be to have the admin call the user and tell them over the phone or in person their temporary password, but this is not practical. How could I handle a situation like this?
I typically use a temporary url based on an invite record on the back end. Essentially you create an invite record and generate a hash based on some information perhaps the users email address, a timestamp and a random value. Store the hash as part of the invite record and then send them a url with the hash as the parameter.
When they click the link lookup the invite and validate that it exists and has not been used - then allow them to setup their password and invalidate the invite.
It gets rid of the need to send any sort of password and you can set an expiry on your invite records if you want as well.
The scenario you describe is very common- emailing a temporary password and requiring it to be changed on first login. Unless you have a specific problem with this model I see no reason not to use it. Having an admin call users can get complicated- I would avoid this at all costs.
You can generate a custom url with a password and user hash as argument where the user has to log itself. The hash will be difficult to retrieve if the attacker does not have the information

Resources