And store the password encrypted...



  • I have been helping a guy with a project.  Originally I wasn't involved, but when it was six months late on a three month project, I got called in to do the other half which hadn't even been started.  I still remember the sick feeling in the pit of my stomach when the developer told me "all fields are varchar for simplicity".

     There's a database of users, who can log in.  Now, we all know that you store the password encrypted, right?  Perfect, it's stored as MD5.  Here's the three relevant fields in the database:

     name VARCHAR,

    password VARCHAR,

    password_md5 VARCHAR,

     ... and yes, the password field holds the plaintext password.

    Amazingly, the MD5 password is even calculated using a salt key. It's the MD5 hash of salt + name + password.  The salt is the name of the company the project is for.  Well, no.  It's a misspelling of the name, with two typos out of six letters.  Now, I'd have thought this might be intentional, except that two of the states a transaction can be in are CANCELED and CANCELLED_TX.

    The whole thing is like this.  Several megabytes of code.



  •  So, what's the problem?



  •  TRWTF is using MD5 in this day and age.  Actually, using any hashing algo to store passwords.



  • I know about a certain web-based app that not only stores passwords in plaintext, the login records also store the plaintext password in every log entry. Nice!

    I had to do some improvements on its functionality, but I was not allowed to change the "security", as it broke a lot of stuff if I modified it to "secure MD5". I would've gone for SSHA, but even trying to get them to use MD5 was useless.



  • @morbiuswilters said:

     TRWTF is using MD5 in this day and age.  Actually, using any hashing algo to store passwords.

    Salted MD5 is still a perfectly secure way of hashing passwords. The weaknesses in MD5 are related to collision resistance; breaking hashed passwords is a first preimage attack, a totally different thing.



  • @Carnildo said:

    Salted MD5 is still a perfectly secure way of hashing passwords. The weaknesses in MD5 are related to collision resistance; breaking hashed passwords is a first preimage attack, a totally different thing.

    Given the history of MD5 (and hash algos in general) it is incredibly foolish to suggest that people continue using them.  Remember, the password systems being implemented by people today will often be used for 5 or more years: to suggest MD5 is ridiculous.  I understand that most of the effort has only been focused on collisions, but that means the algorithm itself is not cryptographically strong.  It's only a matter of time before more weaknesses are uncovered.

     

    Also, breaking MD5 is not nearly as difficult as you imply.  For one, MD5 is a very fast, efficient hash algorithm which is a bad thing.  The faster the algorithm, the easier it is to brute force.  What's more, MD5 cracking is extremely parallelizable.  With a decent number of users it's almost guaranteed one of their passwords would be found in a 50k dictionary of common passwords.  Even with a random 32-bit salt, a fairly effective rainbow table could be constructed from this dictionary.  Basing the security of your users on something as rickety as MD5 in the year 2008 is simply unbelievable.



  • @morbiuswilters said:

    TRWTF is using MD5 in this day and age.  Actually, using any hashing algo to store passwords.
    Wait, what?

    Enlighten me, please.

    Edit: time lapsed. Never mind. 



  • @morbiuswilters said:

    With a decent number of users it's almost guaranteed one of their passwords would be found in a 50k dictionary of common passwords.  Even with a random 32-bit salt, a fairly effective rainbow table could be constructed from this dictionary.

    What kind of attack are you conceptualizing? A dictionary attack does not require access to the hashed passwords, and is equally effective against any hashing method (or no hashing at all). A rainbow attack, on the other hand, requires access to the hashed passwords.

    And unless you know the salt, how do you propose to build a useful rainbow table for a random 32-bit salted hash? The best I can think of is to extend common passwords with random salt, generate a rainbow table, and hope you get a hit. But you're forced to generate a far, far bigger rainbow table. I don't know that I'd classify this as "fairly effective", but it's only a matter of time before it's feasible, of course.



  • @bstorer said:

    And unless you know the salt
    I'm reminded of another WTF from my last comany.  I posted this little bit about them the last time we were talking about salty hash browns.  Now I recall that when [the other developer] redesigned the database/app, he created a different salt for each user.  Then, he put the salt for each password in the same row as said password. The field was conveniently called 'salt.'

    so, WTF or not?



  • @morbiuswilters said:

    [rants against MD5]

    So, what do you suggest? Don't mean to prove you wrong, just interested in how you can / we all should do better.



  • @belgariontheking said:

    he created a different salt for each user.  Then, he put the salt for each password in the same row as said password. The field was conveniently called 'salt.'

    so, WTF or not?

    It's a fairly common practice, but not a best practice. The system should use different salts for each user, because it severely hampers rainbow tables and prevents duplicate passwords from having the same hash, so if one is broken, both aren't. But as I mentioned above, rainbow tables have to work against the hash. If you have the hash, it's most likely because you have the password table. Thus you'd have the salts, too. But that doesn't really make cracking many passwords much easier.



  • @derula said:

    @morbiuswilters said:
    [rants against MD5]
    So, what do you suggest? Don't mean to prove you wrong, just interested in how you can / we all should do better.
    Well, SHA-1 is pretty well broken now. I'm hesitant to suggest SHA-2 because it's a similar algorithm, so even though it's currently considered secure, it seems likely to me that it's only a matter of time until somebody finds an attack for it, too. How about Whirlpool? It's fairly standard, and to my knowledge has no known weaknesses.



  • @morbiuswilters said:

     TRWTF is using MD5 in this day and age.  Actually, using any hashing algo to store passwords.

     

    ...not to mention using a hard-coded "salt".  Gotta love the fools who think they understand enough about security to create their own because they read a Jeff Atwood post.



  • @derula said:

    So, what do you suggest? Don't mean to prove you wrong, just interested in how you can / we all should do better.
     

    bcrypt.  There's an implementation available for almost every modern language/framework.



  • @bstorer said:

    A dictionary attack does not require access to the hashed passwords, and is equally effective against any hashing method (or no hashing at all).

    A dictionary attack doesn't imply using a dictionary against the login API.  Hopefully the API is intelligent enough to limit the speed and number of attacks anyway.  What we are worried about is someone getting ahold of the password database and using it to crack user passwords.  If it's at the point where someone has access to your password DB and the algo you used to store the passwords, your service is pretty much compromised.  The real reason to scramble passwords is because most users will use the same password for multiple services.  This means that as the developer of an app you have an obligation to protect the passwords the best you can so a malicious attack cannot get the plaintext password and use it to access their bank account or some other highly-privileged system.

     

    @bstorer said:

    The best I can think of is to extend common passwords with random salt, generate a rainbow table, and hope you get a hit.

    That's what I was implying.

     

    @bstorer said:

    But you're forced to generate a far, far bigger rainbow table.

    Not necessarily.  You probably know that rainbow tables can be built to conserve space at the cost of processor time or vice-versa.  A fairly sparse rainbow table could store common passwords with every random 32-bit salt.  Obviously this isn't something you would do for shits and giggles, but we're not worried about script kiddies here but competent hackers.  We're assuming they have access to a large amount of storage (a few TB) as well as a botnet or some other form of distributed parallel processing.  The real problem comes down to the fact that MD5 is a very fast algo.  It was designed to be fast and when it comes to hashing passwords this is the opposite of what you want -- you want the algo to take as long as is reasonably possible to hash the data.  Also keep in mind that any password system implemented today will probably be used for 5 years at a minimum.  Hackers are using increasingly sophisticated methods to crack passwords, including harnessing the power of GPUs and processors like Cell.

     

    The fact is, MD5 is toast.  Defending it is pointless now.  It's overkill for CRC checks, it's not cryptographically strong enough for message digests, it's not optimal enough for in-memory hashtables, it's too fast for password hashing and it doesn't generate results that are as evenly distributed as other algos for use in a distributed hashtable.  There's no reason to suggest anyone use it now.



  • @bstorer said:

    It's a fairly common practice, but not a best practice.

    Not sure what you mean here.  Salts sould always be randomly generated, per-user and should be stored with the password DB.  That is best practice.



  • @morbiuswilters said:

    @bstorer said:

    It's a fairly common practice, but not a best practice.

    Not sure what you mean here.  Salts sould always be randomly generated, per-user and should be stored with the password DB.  That is best practice.

    No, storing the salts away from the passwords would be best practice, but as I explained above, it's not really a huge difference.



  • @bstorer said:

    Well, SHA-1 is pretty well broken now. I'm hesitant to suggest SHA-2 because it's a similar algorithm, so even though it's currently considered secure, it seems likely to me that it's only a matter of time until somebody finds an attack for it, too. How about Whirlpool? It's fairly standard, and to my knowledge has no known weaknesses.

    It's pretty well accepted at this point that all hashing functions will ultimately succumb to collision attacks.  However, collision attacks aren't really what we are worried about when it comes to password hashing.  We just want a function that cannot be reversed and that takes a lot of cycles to calculate.  In this case, SHA-1 is better on both accounts than MD5, but it's still not secure enough on its own.  bcrypt is generally going to be your best bet, but second to that would be SHA-1 or SHA-2 with a long, random and per-user salt and some method of key stretching that increases the number of cycles it takes to generate a hash.



  • @bstorer said:

    No, storing the salts away from the passwords would be best practice, but as I explained above, it's not really a huge difference.

    Why would that matter?  The only thing that would protect you against was if the attacker could get the password table but not the salt table.  This is just another form of security through obscurity and it should be avoided as it tends to produce an unwarranted sense of security.  It's the equivalent of having a 9-inch thick solid steel door with massive locks and then propping a chair up in front of it to make it slightly harder to push open.  In that situation, the chair seems ridiculous and anyone can see that.  The problem is, things like "put the salts in another table" aren't instantly and obviously ridiculous so people become deceived into thinking they are safer than they are.  It's not best practice because wasting the time separating the salts from the passwords means you have less time to focus on measures that actually increase the security of your app (building a stronger door).  When it comes to cryptographic security, it is of the utmost importance for people to avoid doing what "feels safe" and to focus on proven, documented methods that are guaranteed mathematically to increase security.



  • @morbiuswilters said:

    @bstorer said:

    No, storing the salts away from the passwords would be best practice, but as I explained above, it's not really a huge difference.

    Why would that matter?  The only thing that would protect you against was if the attacker could get the password table but not the salt table.  

     

    You're absolutely right, and that's why people should store the salts away from the passwords.

    I once worked on a large (1m+ users) website which did this. The salts are stored on the webservers that sit on the DMZ; the passwords are stored in the databases that sit on an internal network. As a developer I had access to the DMZ network but absolutely no access to the network containing the databases. The DBAs sat in a different building and had access to the databases but no access to the web servers. So no one person could get the salts AND the passwords; two people from across the network divide would have to collaborate... star-crossed lovers, maybe.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.