20

If I create a login for an app that has middle to low security risk (in other words, its not a banking app or anything), is it acceptable for me to verify a password entered by the user by just saying something like:

if(enteredPassword == verifiedPassword)
     SendToRestrictedArea();
else
     DisplayPasswordUnknownMessage();

It seems to easy to be effective, but I certainly would not mind if that was all that was required. Is a simple check on username/password combo enough?

Update: The particular project happens to be a web service, the verification is entirely server side, and it is not open-source. Does the domain change how you would deal with this?

9
  • 3
    it depends where validPassword comes from? if it's hardcoded you won't be able to configure/change password without changing the code. If it comes from a configuration file, it will be visible to anyone who accesses that.
    – Alb
    Feb 18, 2011 at 15:44
  • 1
    "is a check on username/password combo enough" to do what?
    – Chris
    Feb 18, 2011 at 15:47
  • 3
    @opinion: it seems unlikely that this is WORSE than not having a login. Please provide some reasoning for such a strong claim. Feb 18, 2011 at 16:12
  • 1
    Your terminology is incorrect, when you're comparing a password your verifying it, not making sure its valid. Please take the time to understand the difference.
    – billy.bob
    Feb 18, 2011 at 16:19
  • 1
    This implies plain text password storage, which is irresponsible. It also implies alerting a user that the password was incorrect, which provides a potential attacker with too much information. You should always be ambiguous, i.e. "Login or password incorrect". May 23, 2011 at 20:46

9 Answers 9

26

Not without SSL

This is not secure if the password is sent over the network in plain text. Hashing the password on the server side is also not secure if the password is sent over the network in plain text.

Since the HTML <input type="password"/> tag sends its contents in plain text, this will be a problem no matter how you store the password on the server, unless your website uses SSL to transmit the password.

(HTTP authentication, which pops up a dialog box in the browser asking for a password, may or may not be clear text, depending on what authentication mechanisms the server and browser have in common. So that could be a way to avoid this without using SSL.)

Not if the site administrators are suspect

Now, supposing you're using HTTPS to do the web site, this could be secure if you trust your site administrators (who can read plain text passwords), and other people who have access to the machine to behave properly. Now, it may be obvious that they can do anything they want with your website (since they administer it), but if they can read the password, the may also be able to use the stolen login/password pairs on other people's sites.

A way that keeps passwords safe from the administrator

One secure way to store and check passwords is as follows:

def change_password user, new_password
  salt = random(65536).to_s(16) #will be 4 characters long
  password_hash = salt + hash(salt + new_password)
  store(user,password_hash)
end

def does_password_match? user, entered_password
  correct_password_hash = retrieve(user)
  salt = correct_password_hash[0...4]
  entered_password_hash = salt + hash(salt + entered_password)
  return correct_password_hash == entered_password_hash
end

For the hash function, try to use something strong, and something that doesn't have good rainbow tables in the wild yet. You can change the length of the salt if necessary work around rainbow tables.

Depending on the environment you're in, the variability in your network latency, and whether user names are meant to be publically known, you may want to have another code path compute hash('0000'+entered_password) if the user doesn't exist, in order to prevent attackers from determining which usernames are valid based on the time it takes determine that the password is incorrect.

6
  • 1
    Good advices :) Regarding SSL, we were required to design something that would work in the wild, and simply used asymetric cryptography to encode the password (requires Javascript) and then decode it on the server. The salt+hash then occurs normally. Also, since the public key is sent with the web-page, it can change arbitrarily often. Feb 18, 2011 at 18:19
  • 1
    @Matthieu M.: When someone can fake your webpage, he can also change the public key there to one where he himself knows the corresponding private key. So your idea does help only against passive read-attacks, not against man-in-the-middle. Feb 18, 2011 at 23:04
  • @Paulo: yes, I agree that SSL is not only about encryption, but also about certificate, unfortunately I don't call the shots here, and when people say they want to use the webpage with a regular http:// connection... it's frustrating :/ Feb 19, 2011 at 11:33
  • @Matthieu: Does that mean you're sending public_key as part of the the public web page, computing encrypt(entered_password, public_key) on the client, and sending that result to the server, which performs does_password_match?(user, decrypt(encrypted_password, private_key))?
    – Ken Bloom
    Feb 20, 2011 at 3:17
  • @Ken: more or less, you got the encryption right. For matching the password it's more does_password_match(user, salt, decrypt(encrypted, key)), with the salt depending on the user. As I said, the obvious issue is the lack of man-in-the-middle protection. Feb 20, 2011 at 11:16
52

That would suggest, that you're keeping passwords in open text, which is a no-no, even in low security scenarios.

You should rather have:

if(hash(enteredPassword) == storedHash)

You can use simple hash as for example MD5

5
  • 22
    +1 for hashing the password. But I'd at least add some salt as well. Otherwise, since users are going to reuse usernames & passwords between systems, breaching your low security app may enable an attacker to breach a much higher security app. The recent HBGary hack, for example, managed to compromise the CMS system running their website and turn that into root access to their servers in part because the low-security CMS system wasn't adding salt to hashes arstechnica.com/tech-policy/news/2011/02/… Feb 18, 2011 at 16:05
  • 1
    Agree... consider the following.. "strings JavaFile.class | grep -i password"
    – Bill
    Feb 18, 2011 at 16:23
  • What is the problem with having the password in plain text if they are only used once?
    – user15608
    Feb 18, 2011 at 16:25
  • 10
    @Tim because users won't use the password only once. Studies consistently show that users re-use passwords multiple times (e.g. theregister.co.uk/2011/02/10/password_re_use_study ) no matter how many times they're told not to.
    – Scott
    Feb 18, 2011 at 16:46
  • 3
    @Tim: besides, just open your exe, dll, etc, in a text editor, and you'll likely see your password right there. Feb 18, 2011 at 16:53
14

I concur with those who suggest hashing, but there is also a wheel you are reinventing here. Depending on the platform you can probably find a role/user management tool that covers all of the user management stuff safely and securely without needing too much intervention on your part.

1
  • I only just discovered ASP.Net Membership Providers but I was looking at them thinking "how many times have I wasted my time implementing something like this?"
    – glenatron
    Feb 18, 2011 at 16:23
8

Security is a very touchy subject, particularly because there needs to be a balance between inconveniencing your users and making sure their information is safe. Typically, the formula for how much security you need is a function of the importance of the data. In short:

isSecuritySufficient = effortToBreak > rewardForBreaking

A common misunderstanding about people who do bad things is what they are after. Most of them are out to destroy trust. You should always do everything you can to protect your users' trust. Part of that is doing your due diligence to make sure their identity is safe. They may care less about the data they store, but they do care about their identity--even at the lowest threshold of security.

There's a number of low cost (to implement and impact to the user) options available. One of those is hashing the password at a bare minimum. Any service that stores something as sensitive as a password in plain text deserves the embarrassment of being hacked.

General Principles for Password Protection

  • Never store passwords in plain text
  • Hash using a secure hash function like SHA-1 or even SHA-512 (even MD5 is too easy to find a matching hash)
  • Use an application salt value. The salt is random bytes either added to a password to make it more difficult to guess. The salt should be generated at run time and using information about the machine as a seed value rather than stored and referenced in any way.
  • Use a user specific salt value. Use this in conjunction with your application salt.
  • Encrypt all authentication requests that go over a network. That means use SSL for web applications.

Since you would be using SSL for the authentication, at a minimum you want to encrypt all the pages that deal with the user's account as well. This allows as much of a user's identity to be protected as possible.

A note about password management: Users will forget their password from time to time. The absolute worst thing you can do is to send them their password in an email. If you implement the principles outlined above, you won't be able to do that anyway. It is much better to provide a way to reset their password using a link sent to their registered email address. That reset link will have a one-time use code to ensure the person accessing the page is them.

4
  • 1
    At first I was really struck by the idea of application salt + user salt, but the more I think about it, the less convinced I am. If you used, say, 4 characters of application salt and 4 of user salt, then the difference between that and 8 characters of user salt is just that half the salt would be identical for every user. It would seem that it would be more secure to just increase the size of the user salt, rather than have application salt. Also, if the application salt is based on the hardware then you can't upgrade or change the hardware without invalidating all the passwords. Mar 14, 2011 at 1:39
  • The problem is that the user salt is included in the database row with the user password. If a bad person knows what a salt is for (and they do), and they see it in the database, then they know how to completely crack it. By including a part in the application that is calculated (the same way every time mind you) instead of stored, it makes it that much harder to crack the user tables. Of course you can go one step further and make a 1 part pure random salt and a 1 part calculated salt with both being user specific. Mar 14, 2011 at 10:16
  • Ah, I see, keep part of the salt out of the database. That does make sense. Thank you. Mar 24, 2011 at 2:22
  • I don't see a problem storing the salt per-row, as long as its unique per row. Here's a hash: "fd84235a55bbfeb1585a3dd069d48127989c9753058b51b6ba2056fd6c5a0a91" (SHA256), here's the salt: "671254bdf7944f8fa88e6c9913b948ee". Think you can get the password? There's no rainbow table for that salt (even if you're given the salt), you're stuck brute-forcing it. Jul 9, 2012 at 21:45
3

That's fine unless the password is used for anything else. There's still a risk that the user decides that he can re-use the password, so it would be even better with:

if(hash(enteredPassword) == hashOfValidPassword)

If it's for yourself or someone who is aware that the password is stored in plain-text, then it's fine.

3
  • 1
    As in Justin Cave's comment to vartec's answer, use salt, so if (hash (enteredPassword + salt) == hashOfValidSaltedPassword) - and note that the + is probably concatenation, not addition. This really hinders the use of rainbow tables, which are tables of hashes of likely passwords. Feb 18, 2011 at 17:10
  • if all you are checking for is a hash, could they not just run through a loop of possible strings until one generates the same hash as the stored hash? There are many strings that could correspond to the same hash, after all. Feb 21, 2011 at 18:20
  • @Prof Plum: It is very difficult to find collisions if the hashing algorithm is good. This is the basis of modern cryptography: they are essentially one-way functions.
    – user15608
    Feb 22, 2011 at 8:58
3

Is the source code available? Even if not, I'm quite sure the password could be found in the machine instructions in case the binary is available. I would recommend doing a checksum and comparing that instead.

Never overlook security even if it isn't very important in your opinion.

2
  • 2
    Yes, bad idea if it's an open source project :)
    – user15608
    Feb 18, 2011 at 15:47
  • -1 - If you think having the source makes a difference, you know nothing about security.
    – mattnz
    Jun 10, 2012 at 22:31
1

Absolutely not. Have a read of this, it describes how hackers hacked a security web site. You plan would have you as the weakest link in the chain.

0

It has been noted in a couple of answers that you should not store the password itself, but a hash - and you should use SSL.

You may say, what is the big deal? If my application gets hacked, that is of little concern. Well it is a quite common pattern for users to reuse the same password on all sites. Was a hacker to hack your site and gain access to user's passwords, the hacker would be able to impersonate a lot of those users on other sites of greater importance to those users. So hacking your site could be the first step for a hacker to gain access to banking information for the users.

And just hashing the password is not enough. You need to hash it with a salt. Hackers have reverse hash lookup tables, so for a given hash, they can find a matching password.

If you choose not to implement these feature, you should inform the users of of this lack of security, encouraging them not to use the same password that they use elsewhere.

-2

As long as this is server side.. Then yes.

If you want a bit more security go for https and encrypt\hash the password in the DB.

3
  • 3
    Why assume this is a web app?
    – Chris
    Feb 18, 2011 at 15:47
  • Good point! I just did.
    – Morons
    Feb 18, 2011 at 15:49
  • 4
    -1 even if it is server side this still isn't ok.
    – GSto
    Feb 18, 2011 at 17:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.