Secure way to send "reset password" link - security

I'm developing an web application using Django.
Currently I am working on sending "reset password link" thorough email (amazon simple email service - SES)
The mechanism I used, is the same with the answer of "simeonwillbanks" below link
Secure ways to reset password or to give old password
Give users a reset password option.
This option saves a unique token for a user. The token eventually expires (hours, day or days).
A link is emailed to the user which includes the token.
User clicks on the emailed link.
If the token exists and isn't expired, the link loads a new password form. If not, don't load the new password form.
Once the user sets a new password, delete the token and send the user a confirmation email.
What I worry about this, I am not sure this way is safe in terms of security. What if the email is captured by a hacker?
I tested on several major websites how they care this.
get an "reset password" email and copy the link.
give the link to other and see if he can change password on my account.
From this test, I figured out that somebody else also can change my password only with the link.
If I cannot do anything on the link, is there way to make email more secure?
like as the mechanism of ssl(https) on website?
Thanks!

It's somewhat secure, though is toast if the user's email was compromised.
I prefer using an HMAC in the URL, which avoids storing tokens in the DB.
If you include the user's IP address in the URL, and in the HMAC, you can be sure the reset link click came from the same computer (router actually) that requested the reset, and that it can't be shared.
Instead of the IP, you could set a device cookie with the username/email and an HMAC, and then check this when the reset link comes in from the email.
The system should ask the user the answer to a secret question after he clicks the link. Even better, send an SMS to his mobile with a short random code and ask for that. This is called https://en.wikipedia.org/wiki/Multi-factor_authentication
Then show the change password form (over HTTPS of course).
While we're here, you should display the same "success" message whether or not the user has an account, to avoid user enumeration attacks.
Also, use a localhost MTA relay or asynchronous email so that a hacker can't tell whether you sent an email (a slow response would indicate that a user exists).

Related

How can I implement exclusive/invite-only user registration?

I'm creating a site with user auth, and I plan to limit access using either invites or some other method.
The site is built on Node, Express, and MongoDB. I plan to use Passport JS, mainly because it's the only method I've learned (this is my first personal project).
The only idea I have is a "secret code" on the registration page. Thus only those I've told the code can register. I have a feeling there are more elegant or secure ways to handle this, and would love any recommendations!
I think your idea is correct in principle - it's the same method used for registration/beta keys for games. You generate a unique 'key' for each user you invite to register. They register with that key and it is marked 'used' in your database; this prevents other users from discovering that key and re-using it.
You could also use email addresses in essentially the same way. The email address that is used to register must be on your 'invite list'. And when you 'confirm' an address by sending a 'click this link to confirm' email you will have to generate another key for authenticity.
Therefore, upon registration with an invited email, you could generate a key as follows:
require('crypto').randomBytes(48, function(err, buffer) {
var key = buffer.toString('base64');
// then save the key with the new user in the database
});
Then send an email with a confirm link containing the key, for example:
https://www.mywebsite.com/users/confirm_email/{key}
This link would call a 'confirm_email' action on your server, look up the specified key, and enable the account it is associated with.
You might want to add an expiry along with each key creation for a bit added security. Maybe only 24 hours to confirm the email.
You don't need any secret codes if it's with invitations :
When someone invites someone else, you store the email invited somewhere. You simply need to check that a new user is "on your guest list" when he tries to register.
Of course, to be "secure" this approach assumes you actually checks that an email address properly belongs to the user that registers, for instance with a verification email, as done usually. The point is that you don't need an additional token.
One solution I can think of just generates the token using the senders token (use jsonwebtoken signed with expiry time and sender's token). Now when the user who is invited will receive the link, let say: http://localhost:5000/invite/${token} and the link is clicked then a GET request will be sent to the server so catch that request and then in that request in the backend decode that token and check your user database if that user exists i.e sender and token is not expired then it's valid invitation so now directly redirect the invitation receiver to the register page else send the message that invitation is not valid.
Hope this help.
Let me know your views.

Firebase: stopping spam to my database

I have a webapp in which preferably I would like users to be able to interact with without having to sign up. Although there are many features, let's consider one: clicking a "like" button - I would like users to only be able to click "like" once. Without user accounts, my Firebase is open to spam (someone could get the url to my Firebase and constantly submit data to my database; the only thing that prevented this was client code, but the spammer could easily bypass it by running their code elsewhere).
So I considered Firebase's anonymous accounts feature; each anonymous account would only be able to vote once during their session and I would store votes on user local storage. This too can be bypassed if a spammer constantly makes a new anonymous account and clears their storage. In fact, they wouldn't have to clear their storage as the storage check occurs in client code, which is easily bypassable.
So now I am considering Firebase's email account feature. As I was coding it, I realized what stops a spammer from entering a ton of fake email addresses? This could fill up my db quick with unnecessary accounts and also could lead to spam of the "like" button. Does Firebase check if the email is valid? Would Firebase send a confirmation email that the user would have to verify?
Firebase provides email verification feature. Send Verification code to user's email id.
You can use it to verify the user's email. It will send a unique token to the user's email. Firebase authentication sets a flag for email verified. You can check it on your landing page and if it's set to false do not allow user to perform any task. Unless the user clicks on that token, the flag will remain set as false.

what is the best practice for forgot password process?

I am currently developing a c# web application that allows users to login with a password. A feature that I need to include is a forgot password function.
What is the recommended process for forgot password?
I was considering this:
User clicks forgot password, enter email address
Email sent
Click on link in email (link only valid once and within time period)
Taken to the site and asked to enter new password (should they also give answer to security question?)
Password changed, email sent to user of such
User now can log in with new password
Your idea looks solid, but I would add some other considerations:
Be sure that the token you are generating in the email using is using a the .Net Framework crypto classes designed for randomization, not something that seems random but is not designed for that purpose.
Take no action on the account from the sending of the reset email (otherwise people will be able to lock other people's accounts if they know their email)
Add a rate limiter on how many resets per hour can be generated for a given email. Otherwise somebody could DOS a user by: (a) using x bad passwords to lock the account and then (b) generating reset emails for them faster than the email system can deliver.
Where possible defer to other systems such as OpenID. It's easy to get things wrong when you roll your own.
We have two ways to retrieve the forgot password:
1. Through registered email id
2. Through registered mobile number
Registered Email id:
a. Ask the user to provide the registered email id
b. The system checks the provided email id is available in the DB or not
c. If Email ID is there in the DB then system send the Email to reset the password but if Email id is not there in the DB then system show the alert messaged.
d. The user must provide strong password while resetting the forgot password.
e. Password reset successfully and is also change in the DB with respect to the Email ID.
Registered Mobile number:
The process is almost same as the email but in this case, OTP will be sent over the registered mobile number.
We need to integrate the 3rd part SDK for this or we can use the imessage in IOS.

Web application account confirmation security flow

I have a question about security flow of confirmation link.
I have a website on which you have to fill your email address and password after filing these information my app sends an email with a secure link to user email address. After clicking on confirmation email user automatically gets logged inside the application.
Now question :
Is there a security risk to auto login user on clicking of confirmation link ?
Is there and security risk to auto login user on clicking of confirmation link? Yes and no. It depends on what is in the link. What I would do is I would have two field in database activate_code, that is randomly generated and is_activated which is defaulted to 0. Then I will send a link to activation code and another email with activation link. Once at activation link, user will fill code and account will be activated. redirect him to login page.
Do not send user emails or any other information. just send random codes or something similar
That is my cent!
Yes there is a security concern, as Gumbo points out.
Since the user has provided an email & password, why not require he be logged in to access his confirmation page?

Requiring unique email addresses while protecting the privacy of your users?

I setup my website to require unique email addresses (no two users can have the same email address), but I realized that this could allow someone to check if a person is registered on my website by attempting to signup with that email. Granted that this person would have to know the email address they wanted to try, but it could be useful information for some people (e.g. competitors who wanted to see if their users are registered on my website).
Is there any real way to stop this, or does this just have to be accepted as a possibility?
Edit: just to be clear, this is about creating an account. Even you provide a generic "invalid login" for bad logins, how would you require a unique email address or username without disclosing which usernames or email addresses are valid?
Additional, much later edit: One thing that wasn't considered here was maintaining the requirement for unique email addresses when you let users change their email address after account creation. Here, the solution I accepted of sending a "forgot password" email doesn't work nearly as well. Instead, it seems that the only options are to use captchas or limitations on the number of times an email address can be changed in a certain period of time to limit automated attempts.
If someone tries to sign up with an existing account — send a "Change your password" email instead of a "New account" email (and explain why).
Leave the HTTP response as a simple "A confirmation email has been sent to the address you specified. Follow the instructions in it to continue".
I suppose the issue is if someone forgets their password, you would ask them to enter their email address and you would send the password there if a match was found?
For that you can have users supply a question/answer challenge when they register their email address. Its a bigger pain for your users but if security is a concern then they may go for it.
Another possibility is your registration form. In this case users can enter an email address to see if its already "taken".
To address your concern you should just happily accept all registrations and send a confirmation email, even if they are already registered. That way the user doesn't know if they just registered the email address for the first time or not.
Finally, if an incorrect username/password is given, don't tell the user which is bad.
I don't think it's a terrible security risk unless membership to the site is sensitive, in which case you can use some of the patterns described.
Yes, that can happen and you cannot really do anything about it except limiting the number of checks/registration attempts in time. That will at least prevent automated checks by your competitor. Of course, if some guy decides to check if his girlfriend is registered there, then he will have that possibility.
Just a thought, not sure if it would work, but why not do something like the login page, where instead of saying "your password is wrong" it says "your username or password was wrong". Maybe just state "your email address is invalid". It's probably a bit of usability error, but if you are concerned about people doing as you say, then you might have to live with it.

Resources