Password Mismanagement
Exit
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 "Log 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.
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
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.
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?
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
Use HTTPS to ensure passwords do not get intercepted
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
Allow users to send themselves password reset emails
Timeout reset links after a reasonable period
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.