Everything you ever wanted to know about securely resetting passwords. Part 1

I recently had time to rethink how the secure password reset function should work, first when I was building this functionality into ASafaWeb , and then when I helped another person do something similar. In the second case, I wanted to give him a link to the canonical resource with all the details of the safe implementation of the reset function. However, the problem is that such a resource does not exist, at least one that describes everything that seems important to me. So I decided to write it myself.



You see, the world of forgotten passwords is actually quite mysterious. There are many different, perfectly acceptable points of view and a lot of quite dangerous ones. Chances are that you have encountered each of them many times as an end user; so I will try to use these examples to show who is doing things right and who is not, and what to focus on to properly implement the function in your application.







Password storage: hashing, encryption, and (ooh!) Plain text



We cannot discuss what to do with forgotten passwords before we discuss how to store them. In the database, passwords are stored in one of three main types:



  1. Simple text. There is a password column, which is stored in plain text.
  2. . ( ), .
  3. . ( , ); , , , .


Let's deal with the simplest question right away: never store passwords in plain text! Never. One single injection vulnerability , one inadvertently made backup, or one of dozens of other simple mistakes - and that's it, gamer, all your passwords - that is, I'm sorry, all your customers' passwords will become public domain. Of course, this will mean a huge possibility that all their passwords from all their accounts in other systems will become public domain . And that will be your fault.



Encryption is better, but it has its weaknesses. The problem with encryption is decryption; you can take those crazy looking ciphers and convert them back to plain text, and when that happens, we'll be back to the situation with readable passwords. How does this happen? A small flaw penetrates the code that decrypts the password, making it publicly available - this is one way. Hackers gain access to the machine on which the encrypted data is stored - this is the second method. Another way, again, is to steal the backup of the database, and someone also gets the encryption key, which is often very insecure stored.



And that brings us to hashing. The idea behind hashing is that it is done one way; the only way to compare the password entered by the user with its hashed version is to hash the entered password and compare them. To prevent attacks with tools like rainbow tables, we use salt to add randomness to the process (read my post on cryptographic storage for a complete picture ). Ultimately, if implemented correctly, we can confidently assume that hashed passwords will never become plain text again (I'll talk about the benefits of various hashing algorithms in another post).



A quick argument about hashing and encryption: The only reason you'll ever need to encrypt rather than hash a password is when you need to see the password in plain text, and you should never want to , at least not in a standard website. If you need it, then most likely you are doing something wrong!



Attention!



Below in the text of the post is part of a screenshot of the pornographic website AlotPorn. It is neatly cropped, and so there is nothing that cannot be seen on the beach, but if it still might cause some problems then do not scroll down the page.


Always reset your password, never remind it



Have you ever been asked to create a password reminder feature ? Take a step back and think about this request in reverse: why is this "reminder" necessary? Because the user has forgotten the password. What do we really want to do? Help him log in again.



I understand the word "reminder" is used (often) colloquially, but what we're really trying to do is safely help the user to be online again . Since we need security, there are two reasons why a reminder (i.e. sending the user his password) is not appropriate:



  1. — . , HTTP ( HTTPS), , . , , , , , , , . — .
  2. . — ( ), .


Let me illustrate the problem with usoutdoor.com as an example : Here is a typical login page:





Obviously, the first problem is that the login page is not loaded over HTTPS, but the site also offers to send a password ("Send Password"). This might be an example of the colloquial use of the term mentioned above, so let's take it one step further and see what happens:





It doesn't look much better, unfortunately; and the email confirms the problem:





This tells us two important aspects of usoutdoor.com:



  1. The site does not hash passwords. At best, they are encrypted, but it is likely that they are stored in plain text; we see no evidence to the contrary.
  2. The site sends a long-term password (we can go back and use it over and over again) over an unsecured channel.


With this in mind, we need to check if the reset process is being performed safely. The first step to do this is to make sure the requestor has the right to perform the reset. In other words, before that we need an identity check; Let's take a look at what happens when an identity is verified without first verifying that the requester is indeed the owner of the account.



Listing usernames and its impact on anonymity



This problem is best illustrated visually. Problem:





See? Pay attention to the message "There is no user registered with this email address" ("The user with this email address is not registered"). The problem obviously arises if such a site confirms the existence of a user registered with such an email address. Bingo - you've just discovered your husband / boss / neighbor porn fetish!



Of course, porn is a fairly canonical example of the importance of privacy, but the danger of associating a person with a particular website is much broader than the potentially embarrassing situation described above. One of the dangers is social engineering; if the attacker can match the person with the service, then he will have information that he can start using. For example, he might contact a person posing as a website spokesperson and ask for more information in an attempt to spearphishing .



Practices like this also raise the “enumeration of usernames” danger, in which one can verify the existence of an entire collection of usernames or email addresses on a website by simple group queries and examining the responses to them. Do you have a list of all employees' email addresses and a few minutes to write a script? Then you see what the problem is!



What is the alternative? In fact, it is quite simple, and is well implemented in Entropay :





Here Entropay does not reveal at all about the existence of an email address in its system to anyone who does not own the email address . If you own this address and it does not exist in the system, then you will receive an email like this:





Of course, there are acceptable situations in which someone thinks they have registered on the website. but it is not, or did it from a different mail address. The example shown above handles both situations well. Obviously, if the address matches, then you will receive an email making it easier to reset your password.



The subtlety of Entropay's chosen solution is that identity verification is done via email prior to any online verification. Some sites ask users for a secret question (more on this below) beforehow the reset can begin; however, the problem with this is that you need to answer the question while providing some form of identification (mail or username), which makes it almost impossible to answer intuitively without revealing the existence of an anonymous user account.



There is a slight decrease in usability with this approach , because there is no instant feedback in the event of an attempt to reset a non-existent account. Of course, this is the whole point of sending an email, but from the point of view of a real end user, if he enters the wrong address, then the first time he finds out about it only when he receives the letter. This may cause some tension on his part, but this is a small price to pay for such a rare process.



Another side note, a bit off-topic, the login help functions that reveal the correct username or email address have the same problem. Always respond to the user with a message “You username and password combination is invalid”, rather than explicitly confirming the existence of credentials (for example, “the username is correct, but the password was entered incorrectly”).



Sending a reset password versus sending a reset url



The next concept that we need to discuss is related to the way to reset a password. There are two popular solutions:



  1. Generating a new password on the server and sending it by email
  2. Send an email with a unique URL to simplify the reset process


Despite the many tutorials , the first point should never be used. Its problem is that it means there is a stored password that can be returned and reused at any time; it was transmitted over an unsecured channel and remains in your inbox. There is a possibility that inboxes are synced with mobile devices and the email client, plus they can be stored online in a web-based email service for a very long time. The point is that the mailbox cannot be viewed as a reliable medium for long-term storage .



But besides this, the first paragraph has another serious problem - it simplifies as much as possibleblocking the account with malicious intent. If I know the email address of the person who owns the account on the website, then I can block him at any time by simply resetting his password; this is a denial-of-service attack, laid out on a silver platter! That is why the reset should be performed only after a successful check with the requestor of the right to it.



When we talk about a reset URL, we mean a website address that is unique to that particular instance of the reset process . It should of course be random, it shouldn't be easy to guess, and it shouldn't contain any external account links to make it easy to reset. For example, the reset URL shouldn't be just a path like "Reset /? Username = JohnSmith".



We want to create a unique token that can be emailed as a reset URL, and then verified against a server record against the user account, thus confirming that the account owner is indeed the same person who is trying to reset the password. ... For example, a token can be of the form "3ce7854015cd38c862cb9e14a1ae552b" and is stored in the table along with the user ID of the resetting user and the time the token was generated (more on this below). When sending an email, it contains a URL like "Reset /? Id = 3ce7854015cd38c862cb9e14a1ae552b", and when the user loads it, the page asks for the existence of the token, after which it confirms the user's information and allows changing the password.



Of course, since the above process (hopefully) allows the user to create a new password, ensure that the URL is loaded over HTTPS. No, it is not enough to send it with a POST request over HTTPS , this URL with the token must use the security of the transport layer so that it would be impossible to perform a MITM attack on the new password entry form and the password created by the user is transmitted over a secure connection.



Also for the reset URL, you need to add a token time limit so that the reset process can be performed within a certain interval, for example, within an hour. This ensures that the reset window is minimal so that the recipient of this reset URL can only act within this very small window. Of course, the attacker can start the reset process again, but he will need to obtain another unique reset URL.



Finally, we need to make this process one-shot. After the reset process is complete, the token must be removed so the reset URL is no longer functional. The previous point is needed so that the attacker has a very small window during which he can manipulate the reset URL. Plus, of course, after a successful reset, the token is no longer needed.



Some of these steps may seem overly redundant, but they don't interfere with usability at all and actually increase security, albeit in situations that we hope will be rare. In 99% of cases, the user will engage the reset within a very short period of time and will not reset the password again in the near future.



Role of CAPTCHA



Oh, CAPTCHA, the remedy we all love to hate! In fact, CAPTCHA means not so much protection as identification - you are a human or a robot (or an automated script). Its purpose is to avoid automatic form submission, which, of course, can be used as an attempt to breach security. In the context of resetting passwords, CAPTCHA means that the reset function cannot be brute-force cracked to either spam the user or try to determine the existence of accounts (which, of course, will not be possible if you followed the advice in the section on identity verification).



Of course, the CAPTCHA itself is not ideal; there are many precedents for its software "hacking" and achieving sufficient success rates (60-70%). In addition, there is a solution shown in my post on hacking CAPTCHAs with automated people where you can pay people a fraction of a cent to solve each CAPTCHA and get a 94% success rate. That is, it is vulnerable, but (slightly) raises the barrier to entry.



Let's take a look at a PayPal example:





In this case, the reset process simply cannot start before the CAPTCHA is solved, so in theory it is impossible to automate the process. In theory.



However, for most web applications, this will be overkill and is definitely a decrease in usability - people just don't like CAPTCHAs! Also, a CAPTCHA is a thing that can be easily revisited when needed. If a service begins to be attacked (logging comes in handy here, but more on that later), adding a CAPTCHA is nowhere easier.



Secret questions and answers



With all of the methods we looked at, we were able to reset the password just by having access to an email account. I say "just", but of course, illegally gaining access to someone else's mail account must be difficult. However, this is not always the case .



In fact, the link above about hacking Sarah Palin's Yahoo! serves two purposes; first, it illustrates how easy it is to hack (some) email accounts, and second, it shows how bad security questions can be used maliciously. But we'll come back to this later.



The problem with resetting passwords with 100% reliance on email is that the integrity of the account of the site you are trying to reset becomes 100% dependent on the integrity of the email account. Anyone who has access to your email has access to any account that can be reset by simply receiving an email . For such accounts, email is the "key to all doors" of your online life.



One way to mitigate this risk is to implement a security question and answer pattern. No doubt you've seen them before: choose a question that only you have to answerknow the answer, after which when you reset your password, you are asked. This adds confidence that the person attempting the reset is indeed the owner of the account.



Back to Sarah Palin, the mistake was that the answers to her security question / questions were easy to find. In particular, when you are such a significant public figure, information about your mother's maiden name, educational history or where someone may have lived in the past is not all that secret. In fact, most of it can be found by almost anyone. And so it happened with Sarah:



Hacker David Kernell gained access to Palin's account by finding her background information, such as her college and birth date, and then using Yahoo !.'s forgotten password recovery feature.


This is primarily a design flaw on the part of Yahoo! - By pointing out these simple questions, the company essentially sabotaged the value of the secret question, and therefore the protection of its system. Of course, resetting passwords for an email account is always more difficult because you can't verify ownership by sending an email to the owner (without having a second address), but fortunately there are not many ways to create such a system today.



Back to the secret questions - there is an option to give the user the ability to create their own questions. The problem is that the result will be terribly obvious questions:



What color is the sky?



Questions that put people in an awkward position when a person uses a security question to identify(eg call center):



Who did I sleep with on Christmas?



Or frankly stupid questions:



How do you spell "password"?



When it comes to security questions, users need to be saved from themselves! In other words, the secret question should be determined by the site itself, or better yet, ask a series of secret questions from which the user can choose. And don't just pick one ; ideally the user should select two or more security questions at the time of registrationwhich will then be used as the second identification channel. Having multiple questions increases the confidence in the verification process, as well as the ability to add randomness (not always showing the same question), plus provides a little redundancy in case the real user has forgotten the password.



What should be a good security question? This is influenced by several factors:



  1. It should be short - the question should be clear and unambiguous.
  2. The answer must be specific - we do not need a question that one person can answer in different ways
  3. Possible answers should be varied - asking about someone's favorite color gives a very small subset of possible answers
  4. ( , ),
  5. — - ,


As it happens, there is a good questions website called GoodSecurityQuestions.com . Some of the questions seem to be quite good, others do not pass some of the tests described above, in particular the "ease of search" test.



Let me show you how security questions are implemented in PayPal and, in particular, how much effort the site makes to identify. Above we saw a page for starting a process (with a CAPTCHA), but here we show what happens after you enter an email address and solve a CAPTCHA:





As a result, the user receives the following letter:





While this is normal, here's what lies behind this reset URL:





So, secret questions come into play. In fact, PayPal also allows you to reset your password by verifying your credit card number, so there is an additional channel that many sites don't have access to. I just can't change my password without answering both security questions (or knowing the card number). Even if someone hijacks my email, they won't be able to reset my PayPal account password if they don't know a little more personal information about me. What information? Here are the security question options offered by PayPal:





The school and hospital question might be a little dubious in terms of ease of searching, but the rest are not so bad. However, to improve security, PayPal requires additional identification to change the security answers:





PayPal is a pretty utopian example of a secure password reset: it implements a CAPTCHA to reduce the risk of brute force, requires two secret questions, and then requires another kind of completely different identification just to change answers - and this is after the user is already signed in. This is of course what we would expect from PayPal; it is a financial institution dealing with large amounts of money. This does not mean that every password reset has to follow these steps - in most cases it is overkill - but it is a good example for when security is serious business.



The convenience of the system of secret questions is that if you did not implement it immediately, then it can be added later if the level of resource protection requires it. A good example of this is Apple, which has just recently implemented this mechanism [written in 2012] . Once I started updating the application on the iPad, I saw the following request:





Then I saw a screen where I could select several pairs of secret questions and answers, as well as a rescue email address:





As for PayPal, the questions are pre-selected and some of them are actually pretty good:





Each of the three pairs of questions and answers represents a separate set of possible questions, so there are ample ways to configure an account.



Another aspect to consider regarding the answer to the security question is storage. Finding plain text in DB poses almost the same threats as in the case of a password, namely - disclosing the database instantly reveals the meaning and puts at risk not only the application, but also potentially completely different applications using the same security questions (this is again a question of berries acai). One option is secure hashing (strong algorithm and cryptographically random salt), but unlike most password storage cases, there can be a good reason for the response to appear as plain text. A typical scenario is an identity verification by a live operator over the phone. Of course, in this case, hashing is also applicable (the operator can simply enter the response named by the client), but in the worst case, the secret answer must be at some level of the cryptographic store, even if it is just symmetric encryption. To summarize: treat secrets as secrets!



And the last aspect of secret questions and answers - they are more vulnerable to social engineering. Trying to directly elicit the password for someone else's account is one thing, but striking up a conversation about its education (a popular secret question) is completely different. In fact, you can quite realistically communicate with someone about many aspects of their life that may constitute a security question, without raising suspicion. Of course, the very essence of the secret question is that it is related to someone's life experience, so it is remembered, and this is precisely the problem - people love to talk about their life experiences! There is little that can be done about it, just by choosing the security question options so that they are less likely to be pulled out by social engineering.



[To be continued.]






Advertising



VDSina offers reliable servers with a daily payment , each server is connected to an Internet channel of 500 megabits and is protected from DDoS attacks for free!






All Articles