Password Mismanagement
Back to All Lessons
The first thing to consider is: do you really need to build your own authentication system? Facebook, Twitter, Google and others offer mature OAuth implementations.
Implementing a "Login in with Facebook" button offloads the complexity of authentication management to a trusted third-party, and makes the login process very convenient for your users.
Complexity 9c00f082cfd6960f535ccf3934e86a1954c0176045dcfbec875ef69b818680fc
Try to push your users into choosing less obvious passwords
123456
password
12345
12345678
qwerty
123456789
1234
baseball
dragon
football
Users often don't exercise a lot of imagination when choosing a password
Absurd complexity 6c5b5eb899ac9293acb90f44ee9d8700fc9895fc7c2b84e714ad613ae2ee9995
Too many complexity rules actually undermine the security of your users
Some sites refuse to reset a password to a value that was previously used. The intention here is good. However, most users will simply append a number at the end of the password where repeated passwords are not allowed.
Which brings us on to another subject: how to implement password resets? The industry standard is to allow users to send themselves password reset emails.
Your site will typically implemented two password reset screens - one for logged out users (after clicking on a password reset link in an email), and one for users already logged in. Ensure this latter screen requires re-entering of the user's old password, in case they leave themselves logged in on a shared computer.
Password lockout 2110f0dc2062c5dd9c8eee3539e346ec4d74da3e7e02ba8d8a5a879477f5cf9f
A login screen that allows the user to retry after an indefinite number of logins is prone to brute-force attacks.
Prove you're not a robot
Which dog is the tastiest snack?
Doge bread 1 642ee3c3aeda2e4be2cf9d9d614da9ab048f43e7de87fd91b470577a5c5acdb9 Doge bread 2 3ab64a39d18fb4a887d4f5da48ccbb8067872e331b3a768cbb1b0c73a3fb3b67 Doge bread 3 bbc86dcc0834208b324fb3286faf898ffa73a01b45859c203c5e217f8b332fd9
Password storage is also a complex subject. There are some basics you need to get right.
Never store passwords in plain-text. Always use a one-way hashing algorithm to encrypt your stored passwords. This will protect your users even if your database gets hacked.
Choose a strong hash like BCrypt. Storing the password hash will allow you to test the correctness of a password when a user re-enters it, but keeps it opaque to anyone who has database access.
Remember to "salt" your passwords too. This means adding an element of randomness to each encrypted password so they can't be backwards-engineered from lookup tables.
Headers
Preview
Response
Cookies
General
Request Method:
GET
Status Code:
200 OK
Response Headers
Content-Type:
text/html
For tips on secure session management, review our other exercises
<form name="login"
      method="POST"
      autocomplete="off">

  [...]

</form>
Use the "autocomplete" attribute to stop the browser remembering passwords
Secure 9de81775238857fb1e333325894b7a6eb08d223d3b29e7e286c01eb4ea935e7a
Use HTTPS to ensure passwords do not get intercepted
Oauth 9d5387586e5ccbc827f04576c66cb9a72382294c0e76bedce802c364dfdb2328
Single sign-on can supplement or replace your authentication system
Social media authentication isn't suitable for all applications, of course. If you find yourself implementing your own authentication, the first thing to consider is your password complexity rules.
Passwords need a minimum length (8 characters is good). Many sites require mixed case, numeric characters, or special symbols in an effort to encourage less guessable passwords.
Bear in mind that your users are creatures of habit, and can only remember a limited number of passwords. Many users will simply capitalize the first letter, put a number at the end, or append a ! to their password, when asked to make it more complex.
Even worse: if your password complexity rules are too arduous users will resort to writing their passwords down, which undermines the effort you are putting in to make them secure.
football1
football2
football3
football4
football5
football6
Avoiding repeat passwords can be counterproductive
Forgotten 5f27e2397d183a000ae434c96f0a79d561541c130e4845becd4af661c86b3f42
Allow users to send themselves password reset emails
Expired 7c1d70b797066f3b2df11af2aa6155642ad308d9b987e4f57f563cd3fd500f2b
Timeout reset links after a reasonable period
Password reset 90a96f0902eb873a1044e4735fd363cfa428fe1459456bf198640652322f8e9b
Internal reset screens should require the old password to be re-entered
Secure sites often implement a password lockout period after too many failed login attempts. This is to discourage brute-forcing of passwords, where an attackers submits a lists of common passwords against known usernames.
This opens up the possibility of a malicious user intentionally locking out a named account, though, so forcing the user to pass a CAPTCHA test may be better.
QOaCWHh9HONsrgWBrbb42x1PygKdEB5hq5tRIXlwO
EMTh3QopMOV0xjshri72X.O/ha75Y6D0RezBaWacK
0ErkKvqmEOWiMtkkCxKIuTBORSK3PWkIkvJPePLka
IdfcNRUPvebr0l0ftNtlrKDIy04FsvdXqPVUVB3ne
kKES3P8ateyVLe6FF2UDqtSAOPCN0YqZaJA0/Uqfa
e0x/wXACou/7yOrQtm.FsZrvi7T.0RsYOVWGJausu
IiShZ9LOAeHYu8Qk7YvEOZdjG2SfOW6vwtLU/bZtC
RIGbJs4j4eTYWVhrLteXsduC9xnKPzThiaUSSRrL6
8158Gr6li.btXeXvUUg9PFYEaKiZvIZVGtwJcqfEe
Hashed passwords are of limited use to an attacker, even if your database gets hacked
# Given a secret and a valid salt calculates
# a bcrypt() password hash.
def self.hash_secret(secret, salt, _ = nil)
  if valid_secret?(secret)
    if valid_salt?(salt)
      __bc_crypt(secret.to_s, salt)
    else
      raise Errors::InvalidSalt.new("invalid salt")
    end
  else
    raise Errors::InvalidSecret.new("invalid secret")
  end
end
Strong password algorithms are widely available as open-source libraries
# Generates a random salt with a given cost.
def self.generate_salt(cost = self.cost)
  cost = cost.to_i
  if cost > 0
    if cost < MIN_COST
     cost = MIN_COST
    end
    prefix = "$2a$05$C.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW"
    __bc_salt(prefix, cost, random_bytes(MAX_LENGTH))
  else
    raise Errors::InvalidCost.new("cost must be > 0")
  end
end
A good implementation will make adding salt easy
Good password management needs to be paired with good session management. Remember to implement session timeouts, or you risk having your users' accounts compromised if they forget to press the "logout" button.
Also consider whether you want browsers to cache passwords on your login page. There is a trade-off between convenience and security here. Think carefully what is most important for your application - and be aware that browser settings or password manager plug-ins may override your suggestion not to cache passwords.
Lastly, make sure your site uses HTTPS and marks cookies as Secure. Unencrypted communication is vulnerable to network-sniffing, meaning passwords could be stolen in transit by man-in-the-middle attacks.